| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- /**
- * 移动端逐屏截图(对照 prototypes/fmode-mobile-20261102/shots)
- *
- * 用法:node scripts/shots-mobile.mjs
- * 前置:npm run build:mock(MockApi 数据,无需真实登录)
- */
- import { chromium, devices } from 'playwright';
- import { mkdir } from 'node:fs/promises';
- import { createServer } from 'node:http';
- import { existsSync } from 'node:fs';
- import { readFile } from 'node:fs/promises';
- import { extname, join, resolve, dirname } from 'node:path';
- import { fileURLToPath } from 'node:url';
- const here = dirname(fileURLToPath(import.meta.url));
- const distDir = resolve(here, '../dist/fmode-app-v2/browser');
- const outDir = resolve(here, '../test-results/mobile-shots');
- const MIME = {
- '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css',
- '.json': 'application/json', '.svg': 'image/svg+xml', '.woff2': 'font/woff2',
- '.ico': 'image/x-icon', '.png': 'image/png',
- };
- const server = createServer(async (req, res) => {
- try {
- const url = decodeURIComponent((req.url ?? '/').split('?')[0]);
- let file = join(distDir, url);
- if (!existsSync(file) || url === '/') file = join(distDir, 'index.html');
- const body = await readFile(file);
- res.writeHead(200, { 'Content-Type': MIME[extname(file)] ?? 'application/octet-stream' });
- res.end(body);
- } catch {
- res.writeHead(404).end('not found');
- }
- });
- await new Promise((r) => server.listen(0, r));
- const base = `http://127.0.0.1:${server.address().port}`;
- await mkdir(outDir, { recursive: true });
- const browser = await chromium.launch({ channel: 'msedge' });
- const ctx = await browser.newContext({ ...devices['iPhone 13'], deviceScaleFactor: 2 });
- const page = await ctx.newPage();
- const errors = [];
- page.on('pageerror', (e) => errors.push(String(e)));
- await page.goto(base + '/');
- await page.evaluate(() => {
- localStorage.setItem('fmode_ui_mode_override', 'mobile');
- localStorage.setItem('fmode_session_token', 'demo-fmode');
- localStorage.setItem('fmode_me', JSON.stringify({ id: 'me-1', name: '林一舟', mobile: '13800000000', companyName: '北美数字科技' }));
- });
- const shots = [
- ['01-messages', '/mobile/messages'],
- ['03-home', '/mobile/home'],
- ['04-contacts', '/mobile/contacts'],
- ['06-projects', '/mobile/projects'],
- ['08-tasks', '/mobile/tasks'],
- ['10-deliverables', '/mobile/deliverables'],
- ['11-events', '/mobile/events'],
- ['12-workbench', '/mobile/workbench'],
- ['13-mine', '/mobile/mine'],
- ];
- for (const [name, path] of shots) {
- await page.goto(base + path, { waitUntil: 'networkidle' });
- await page.waitForTimeout(900);
- await page.screenshot({ path: join(outDir, `${name}.png`) });
- console.log('shot', name, page.url());
- }
- // 登录页(清掉登录态)
- await page.goto(base + '/login');
- await page.evaluate(() => {
- localStorage.removeItem('fmode_session_token');
- localStorage.removeItem('fmode_me');
- });
- await page.goto(base + '/login', { waitUntil: 'networkidle' });
- await page.waitForTimeout(600);
- await page.screenshot({ path: join(outDir, '00-login.png') });
- console.log('errors:', errors.length ? errors : 'none');
- await browser.close();
- server.close();
|