.tmp-flow3.mjs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import { chromium } from 'playwright';
  2. const base = 'http://localhost:4200';
  3. const b = await chromium.launch({ channel: 'msedge' });
  4. const ctx = await b.newContext({ viewport: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true,
  5. userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Mobile/15E148 Safari/604.1' });
  6. const p = await ctx.newPage();
  7. const errs = [];
  8. p.on('pageerror', e => errs.push(e.message));
  9. p.on('console', m => { if (m.type() === 'error') errs.push(m.text().slice(0, 140)); });
  10. const r = {};
  11. await p.goto(base + '/login'); await p.waitForTimeout(900);
  12. await p.locator('input').nth(0).fill('13800000000');
  13. await p.getByRole('button', { name: /获取验证码/ }).first().click(); await p.waitForTimeout(400);
  14. await p.locator('input').nth(1).fill('123456');
  15. await p.getByRole('button', { name: /^登\s*录$/ }).first().click(); await p.waitForTimeout(3500);
  16. r.landing = p.url().replace(base, '');
  17. // 新建对话
  18. await p.getByRole('button', { name: '新建对话' }).first().click(); await p.waitForTimeout(700);
  19. r.pick = await p.locator('.pick-row').count();
  20. await p.locator('.pick-row').first().click(); await p.waitForTimeout(2500);
  21. r.afterNew = p.url().replace(base, '').slice(0, 60);
  22. // 发消息
  23. const ta = p.locator('textarea').first();
  24. await ta.fill('你好,做个测试'); await ta.press('Enter'); await p.waitForTimeout(2500);
  25. r.sent = (await p.evaluate(() => document.body.innerText)).includes('你好,做个测试');
  26. await p.screenshot({ path: '.tmp-shots/chat.png' });
  27. // 抽屉(会话列表页顶栏 ☰)
  28. await p.goto(base + '/mobile/chat-index'); await p.waitForTimeout(1800);
  29. await p.getByRole('button', { name: '打开会话抽屉' }).click(); await p.waitForTimeout(800);
  30. r.drawer = (await p.evaluate(() => document.body.innerText)).includes('新建对话') && (await p.evaluate(() => document.body.innerText)).includes('更多');
  31. await p.locator('button:has-text("更多")').first().click(); await p.waitForTimeout(400);
  32. r.moreList = (await p.evaluate(() => document.body.innerText)).includes('成果');
  33. await p.screenshot({ path: '.tmp-shots/drawer.png' });
  34. await p.keyboard.press('Escape');
  35. // 详情页
  36. for (const [route, name] of [['projects/pr-0', 'project-detail'], ['tasks/t-0', 'task-detail']]) {
  37. await p.goto(`${base}/mobile/${route}`); await p.waitForTimeout(1500);
  38. await p.screenshot({ path: `.tmp-shots/${name}.png` });
  39. }
  40. // 配色切换
  41. await p.goto(base + '/mobile/mine'); await p.waitForTimeout(1200);
  42. await p.locator('.pal').nth(1).click(); await p.waitForTimeout(500);
  43. r.palette = await p.evaluate(() => document.documentElement.dataset.palette);
  44. await p.screenshot({ path: '.tmp-shots/mine-ice.png' });
  45. console.log(JSON.stringify({ r, errs: [...new Set(errs)].slice(0, 6) }, null, 1));
  46. await b.close();