75 lines
3.9 KiB
JavaScript
75 lines
3.9 KiB
JavaScript
'use strict';
|
||
/* ⑮ 响应式(任务书测试 15:四种视口截图 + 窗口边界) */
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
module.exports = {
|
||
name: '13-responsive',
|
||
title: '2048×1152/1440×900/1100×700/768×1024 四视口无溢出、窗口不越界、英文名不断行',
|
||
async run({ t, track, newPage, unlock, http, ROOT }) {
|
||
const shotsDir = path.join(ROOT, 'tests', 'shots');
|
||
fs.mkdirSync(shotsDir, { recursive: true });
|
||
const VIEWPORTS = [
|
||
[2048, 1152], [1440, 900], [1100, 700], [768, 1024],
|
||
];
|
||
for (const [w, h] of VIEWPORTS) {
|
||
const env = track(await newPage(http, { viewport: { width: w, height: h } }));
|
||
const { page } = env;
|
||
await unlock(page);
|
||
// 打开多个 App 覆盖典型布局
|
||
await page.evaluate(() => {
|
||
window.Apps.open('finder');
|
||
window.Apps.open('mail');
|
||
window.Apps.open('settings');
|
||
window.Apps.open('calculator');
|
||
});
|
||
await page.waitForTimeout(600);
|
||
// 窗口不越界
|
||
const wins = await page.evaluate(() => window.WM.windows.map(x => ({ app: x.appId, ...x.rect })));
|
||
for (const win of wins) {
|
||
t.ok(win.w <= w, `[${w}×${h}] ${win.app} 宽度 ${win.w} ≤ 视口 ${w}`);
|
||
t.ok(win.x + win.w <= w + 80, `[${w}×${h}] ${win.app} 右缘不越界`);
|
||
t.ok(win.y >= 25, `[${w}×${h}] ${win.app} 不被菜单栏遮挡`);
|
||
}
|
||
// 计算器(小窗口)在窄视口下宽度有效
|
||
const calc = wins.find(x => x.app === 'calculator');
|
||
if (calc) t.ok(calc.w <= w - 10, `[${w}×${h}] 计算器宽度有效: ${calc.w}`);
|
||
// 菜单栏与 Dock 正常
|
||
t.ok(await page.isVisible('#menubar'), `[${w}×${h}] 菜单栏可见`);
|
||
t.ok(await page.isVisible('#dock'), `[${w}×${h}] Dock 可见`);
|
||
const dockW = await page.evaluate(() => document.querySelector('#dock .dock-icon').getBoundingClientRect().width);
|
||
if (w <= 640) t.ok(dockW <= 40.5, `[${w}×${h}] Dock 图标缩小: ${dockW}`);
|
||
else if (w <= 1100) t.ok(dockW <= 48.5, `[${w}×${h}] Dock 图标收窄: ${dockW}`);
|
||
// 页面无横向滚动溢出
|
||
const overflowX = await page.evaluate(() => document.documentElement.scrollWidth - innerWidth);
|
||
t.ok(overflowX <= 1, `[${w}×${h}] 页面无水平溢出 (${overflowX}px)`);
|
||
// 锁屏也检查一次(每视口重新锁屏代价高,仅 768 视口验证)
|
||
if (w === 768) {
|
||
await page.evaluate(() => window.Sys.showLock());
|
||
await page.waitForTimeout(400);
|
||
t.ok(await page.isVisible('#lockscreen'), '[768×1024] 锁屏正常显示');
|
||
await page.screenshot({ path: path.join(shotsDir, `lock-${w}x${h}.png`) });
|
||
await page.click('#lockscreen');
|
||
await page.waitForSelector('#desktop:not(.hidden)', { timeout: 5000 });
|
||
}
|
||
await page.screenshot({ path: path.join(shotsDir, `desktop-${w}x${h}.png`) });
|
||
t.eq(env.errors.length, 0, `[${w}×${h}] 无未捕获异常: ` + env.errors.join(' | '));
|
||
}
|
||
|
||
// ---- 桌面英文名不在单词中间断行 ----
|
||
const env2 = track(await newPage(http, { viewport: { width: 1440, height: 900 } }));
|
||
await unlock(env2.page);
|
||
await env2.page.evaluate(() => window.FS.write('/Users/guest/Desktop/SuperLongEnglishFileNameDocument.txt', 'x'));
|
||
await env2.page.waitForTimeout(300);
|
||
const nameStyle = await env2.page.evaluate(() => {
|
||
const n = [...document.querySelectorAll('.desk-icon .di-name')].find(x => x.textContent.includes('SuperLong'));
|
||
if (!n) return null;
|
||
const cs = getComputedStyle(n);
|
||
return { wordBreak: cs.wordBreak, overflowWrap: cs.overflowWrap };
|
||
});
|
||
t.ok(nameStyle, '桌面显示长英文名文件');
|
||
t.ok(nameStyle.wordBreak !== 'break-all', '桌面文件名不在单词中间断行');
|
||
await env2.page.evaluate(() => window.FS.trash('/Users/guest/Desktop/SuperLongEnglishFileNameDocument.txt'));
|
||
t.eq(env2.errors.length, 0, '无未捕获异常: ' + env2.errors.join(' | '));
|
||
},
|
||
};
|