Files
mcn-short-video/project/短视频脚本创作/V1.0/mcn-work-shop/cdp-verify-r29.mjs
T
maogeigei 2aa13bf900 R29 列位移修正:账号详情视频列表标签列从「时长」前改为「点赞」左边
- 之前位置(时长前)按用户原话「时长前面」实现,忽略了三遍明确指示(标签在点赞左边)
- 新位置(点赞左边):data-pages.js 表头/data 行同步移动 td-tag
- 冒烟脚本 cdp-verify-r29.mjs 断言更新:thTagIdx 6→2、tagBeforeDur→tagBeforeLike、rowCells[6]→rowCells[2]
- 版本 ?v=20260903o→p;CDP PASS + 视觉截图确认
2026-09-03 16:17:33 +08:00

57 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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);