- 之前位置(时长前)按用户原话「时长前面」实现,忽略了三遍明确指示(标签在点赞左边) - 新位置(点赞左边):data-pages.js 表头/data 行同步移动 td-tag - 冒烟脚本 cdp-verify-r29.mjs 断言更新:thTagIdx 6→2、tagBeforeDur→tagBeforeLike、rowCells[6]→rowCells[2] - 版本 ?v=20260903o→p;CDP PASS + 视觉截图确认
57 lines
3.8 KiB
JavaScript
57 lines
3.8 KiB
JavaScript
// R29 冒烟:账号详情「视频列表」tab——「时长」前新增「标签」列(固定 40px,超长省略,悬停 title 显示完整)
|
||
const list = await fetch('http://localhost:9225/json').then((r) => r.json());
|
||
const page = list.find((t) => t.type === 'page');
|
||
if (!page) { console.log('ERR: no page'); process.exit(1); }
|
||
const ws = new WebSocket(page.webSocketDebuggerUrl);
|
||
let id = 0; const pending = new Map();
|
||
const send = (method, params = {}) => new Promise((res, rej) => { const i = ++id; pending.set(i, { res, rej }); ws.send(JSON.stringify({ id: i, method, params })); });
|
||
ws.onmessage = (e) => { const m = JSON.parse(e.data); if (m.id && pending.has(m.id)) { const p = pending.get(m.id); pending.delete(m.id); m.error ? p.rej(new Error(m.error.message)) : p.res(m.result); } };
|
||
await new Promise((r) => (ws.onopen = r));
|
||
const ev = async (expr) => { const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true, awaitPromise: true }); if (r.exceptionDetails) return { __err: (r.exceptionDetails.exception?.description || r.exceptionDetails.text).slice(0, 200) }; return r.result.value; };
|
||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||
await send('Page.enable'); await send('Runtime.enable');
|
||
const waitFor = async (expr, ms = 15000) => { const t0 = Date.now(); while (Date.now() - t0 < ms) { if (await ev(expr)) return true; await sleep(300); } return false; };
|
||
const fail = (m) => { console.log('FAIL@' + m); process.exit(1); };
|
||
const goto = async (hash) => { await ev(`location.hash = ${JSON.stringify(hash)}`); await sleep(800); };
|
||
|
||
await send('Page.navigate', { url: 'http://localhost:8900/#/' });
|
||
if (!(await waitFor(`!!document.querySelector('#view')`))) fail('app boot');
|
||
await ev(`document.querySelectorAll('.modal-mask').forEach((m) => m.remove())`); // 清 root 设置弹窗
|
||
|
||
/* ============ 账号 1629 视频列表 tab(persona) ============ */
|
||
await goto('#/account/1629/persona');
|
||
if (!(await waitFor(`document.querySelector('#view .table tbody tr')`))) fail('video table rows');
|
||
const out = await ev(`(() => {
|
||
const ths = [...document.querySelectorAll('#view .table thead th')].map((t) => t.textContent.trim());
|
||
const thTag = document.querySelector('#view .table thead th.th-tag');
|
||
const firstTr = document.querySelector('#view .table tbody tr');
|
||
const cells = [...firstTr.children];
|
||
const tagTd = firstTr.querySelector('td.td-tag');
|
||
return {
|
||
ths, // 完整表头文本序列
|
||
thTagIdx: ths.indexOf('标签'),
|
||
likeIdx: ths.indexOf('点赞'),
|
||
durIdx: ths.indexOf('时长'),
|
||
thTagW: thTag ? Math.round(thTag.getBoundingClientRect().width) : null,
|
||
tagBeforeLike: ths.indexOf('标签') === ths.indexOf('点赞') - 1,
|
||
// 数据行
|
||
rowCells: cells.map((c) => ({ cls: c.className, txt: (c.textContent || '').trim().slice(0, 24) })),
|
||
tagTdText: tagTd ? (tagTd.textContent || '').trim() : null,
|
||
tagTdTitle: tagTd ? (tagTd.getAttribute('title') || '') : null,
|
||
tagTdClips: tagTd ? tagTd.scrollWidth > tagTd.clientWidth : null, // 是否发生省略截断
|
||
tagTdW: tagTd ? Math.round(tagTd.getBoundingClientRect().width) : null,
|
||
hasNumClass: tagTd ? tagTd.classList.contains('num') : null,
|
||
};
|
||
})()`);
|
||
console.log(JSON.stringify(out, null, 1));
|
||
const ok = out && !out.__err
|
||
&& out.ths.length === 9 && out.thTagIdx === 2 && out.likeIdx === 3 && out.durIdx === 7 && out.tagBeforeLike === true
|
||
&& out.thTagW === 40
|
||
&& out.rowCells.length === 9 && out.rowCells[2].cls.includes('td-tag')
|
||
&& !!out.tagTdText && out.tagTdText.length > 0
|
||
&& !!out.tagTdTitle && out.tagTdTitle.includes('#') && out.tagTdTitle.length >= out.tagTdText.length
|
||
&& out.tagTdClips === true && out.tagTdW === 40 && out.hasNumClass === false;
|
||
console.log(ok ? '\n=== PASS ===' : '\n=== CHECK ===');
|
||
ws.close();
|
||
process.exit(ok ? 0 : 1);
|