98 lines
5.3 KiB
JavaScript
98 lines
5.3 KiB
JavaScript
'use strict';
|
||
/* ⑬ 秒表与计时器跨标签恢复、endAt 唯一基准、防重复通知(任务书测试 13) */
|
||
module.exports = {
|
||
name: '11-clock',
|
||
title: '秒表/计时器跨标签恢复;endAt 唯一基准;结束只通知一次;关闭前提示',
|
||
async run({ t, track, newPage, unlock, http }) {
|
||
const env = track(await newPage(http));
|
||
const { page } = env;
|
||
await unlock(page);
|
||
await page.evaluate(() => window.Apps.open('clock'));
|
||
await page.waitForTimeout(300);
|
||
const go = tab => page.evaluate(tb => {
|
||
const w = window.WM.windowsForApp('clock')[0];
|
||
[...w.body.querySelectorAll('.store-tab')].find(b => b.dataset.tab === tb).click();
|
||
}, tab);
|
||
const swst = () => page.evaluate(() => {
|
||
const w = window.WM.windowsForApp('clock')[0];
|
||
const s = w.appState.sw;
|
||
return {
|
||
running: s.running, laps: s.laps.length,
|
||
btn: w.body.querySelectorAll('.sw-btn')[1] ? w.body.querySelectorAll('.sw-btn')[1].textContent : null,
|
||
disp: w.body.querySelector('.sw-disp') ? w.body.querySelector('.sw-disp').textContent : null,
|
||
lapRows: w.body.querySelectorAll('.sw-lap').length,
|
||
};
|
||
});
|
||
|
||
// ---- 秒表:开始 → 切走 → 切回恢复 ----
|
||
await go('sw');
|
||
await page.evaluate(() => { const w = window.WM.windowsForApp('clock')[0]; [...w.body.querySelectorAll('.sw-btn')].find(b => b.textContent === '开始').click(); });
|
||
await page.waitForTimeout(600);
|
||
// 计次两次
|
||
await page.evaluate(() => { const w = window.WM.windowsForApp('clock')[0]; [...w.body.querySelectorAll('.sw-btn')].find(b => b.textContent === '计次').click(); });
|
||
await page.waitForTimeout(200);
|
||
await page.evaluate(() => { const w = window.WM.windowsForApp('clock')[0]; [...w.body.querySelectorAll('.sw-btn')].find(b => b.textContent === '计次').click(); });
|
||
let s1 = await swst();
|
||
t.eq(s1.laps, 2, '计次 2 次');
|
||
t.eq(s1.btn, '暂停', '运行中按钮为暂停');
|
||
// 切到世界时钟再切回
|
||
await go('world');
|
||
await page.waitForTimeout(700);
|
||
await go('sw');
|
||
await page.waitForTimeout(150);
|
||
s1 = await swst();
|
||
t.eq(s1.btn, '暂停', '切回后按钮恢复为暂停');
|
||
t.eq(s1.lapRows, 2, '切回后计次列表恢复 2 条');
|
||
t.ok(s1.disp && s1.disp !== '00:00.0', '切回后显示当前秒表值: ' + s1.disp);
|
||
// 暂停后切走切回
|
||
await page.evaluate(() => { const w = window.WM.windowsForApp('clock')[0]; [...w.body.querySelectorAll('.sw-btn')].find(b => b.textContent === '暂停').click(); });
|
||
await go('alarm'); await go('sw');
|
||
s1 = await swst();
|
||
t.eq(s1.btn, '继续', '暂停后切回按钮为继续');
|
||
|
||
// ---- 计时器:跨标签到点通知且只通知一次 ----
|
||
await go('timer');
|
||
await page.evaluate(() => {
|
||
const w = window.WM.windowsForApp('clock')[0];
|
||
const st = w.appState;
|
||
st.timer.total = 1200; st.timer.left = 1200;
|
||
st.timer.endAt = Date.now() + 1200; st.timer.notified = false; st.timer.running = true;
|
||
});
|
||
await go('world'); // 切走
|
||
await page.waitForTimeout(2500); // 等计时结束(到点检测不依赖当前标签)
|
||
const notifs = await page.evaluate(() => window.Notify.list.filter(n => n.appId === 'clock' && n.title === '计时器').length);
|
||
t.eq(notifs, 1, '切走时到点仍通知,且只通知一次');
|
||
await page.waitForTimeout(1200);
|
||
const notifs2 = await page.evaluate(() => window.Notify.list.filter(n => n.appId === 'clock' && n.title === '计时器').length);
|
||
t.eq(notifs2, 1, '之后不重复通知');
|
||
await go('timer');
|
||
const t1 = await page.evaluate(() => {
|
||
const w = window.WM.windowsForApp('clock')[0];
|
||
const btns = [...w.body.querySelectorAll('.sw-btn')];
|
||
return { btn: btns.find(b => ['开始', '暂停', '继续'].includes(b.textContent)).textContent, disp: w.body.querySelector('.sw-disp').textContent };
|
||
});
|
||
t.eq(t1.btn, '开始', '计时结束后按钮恢复为开始');
|
||
t.eq(t1.disp, '00:00', '计时结束显示 00:00');
|
||
|
||
// ---- 运行中关闭窗口弹确认 ----
|
||
await page.evaluate(() => {
|
||
const w = window.WM.windowsForApp('clock')[0];
|
||
const st = w.appState;
|
||
st.timer.total = 60000; st.timer.left = 60000;
|
||
st.timer.endAt = Date.now() + 60000; st.timer.notified = false; st.timer.running = true;
|
||
});
|
||
await page.evaluate(() => { window.WM.close(window.WM.windowsForApp('clock')[0]); });
|
||
await page.waitForSelector('.modal-mask .dialog', { timeout: 3000 });
|
||
t.ok(true, '运行中关闭弹出确认');
|
||
await page.evaluate(() => { [...document.querySelectorAll('.dlg-btns .btn')].find(b => b.textContent === '取消').click(); });
|
||
await page.waitForTimeout(300);
|
||
t.eq(await page.evaluate(() => window.WM.windowsForApp('clock').length), 1, '取消后窗口保留');
|
||
await page.evaluate(() => { window.WM.close(window.WM.windowsForApp('clock')[0]); });
|
||
await page.waitForSelector('.modal-mask .dialog', { timeout: 3000 });
|
||
await page.evaluate(() => { [...document.querySelectorAll('.dlg-btns .btn')].find(b => b.textContent === '关闭').click(); });
|
||
await page.waitForTimeout(400);
|
||
t.eq(await page.evaluate(() => window.WM.windowsForApp('clock').length), 0, '确认后窗口关闭');
|
||
t.eq(env.errors.length, 0, '全程无未捕获异常: ' + env.errors.join(' | '));
|
||
},
|
||
};
|