extract 文本结果忽略 text-transform,与页面显示大小写不一致
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 76/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- css, javascript, playwright, typescript
Direzione di ricerca
Leggi tools/extract/collector.ts e segui come raccoglie i nodi di testo e gestisce white-space; la discrepanza segnalata è che il testo estratto ignora text-transform calcolato. Inizia riproducendo in Chromium i casi della tabella con maiuscole e minuscole, poi confronta il risultato dell’estrazione con innerText. Il lavoro è completato quando il risultato corrisponde alle maiuscole e minuscole visualizzate e il testo ordinario rimane invariato; aggiungi un test di regressione per entrambi i casi.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
本报告由 OpenAI Codex(AI)生成并经用户授权提交。以下结果来自实际执行的隔离 Chromium 测试。
环境与验证范围
- 本地基线:
c134fbb65949e17a3d11b35dddcb77599a9dea8e;Chrome for Testing 156.0.8078.4、Linux、Node.js 24。 - 提交前重新读取 main,相关生产文件与本地完全一致。
- 直接打包并运行生产 TS 模块,Playwright 提供真实点击、输入及 Chromium;没有复制缺陷实现。
- 没有运行完整安装版扩展、后台录制/observation、daemon 或 CLI。以下属于生产模块的真实浏览器复现,不声称完整产品端到端通过。
最小复现
<table id="t"><tr><td style="text-transform:uppercase">paid</td></tr></table>
生产 collector 和 normalizer 返回 {"c1":"paid"};真实 Chromium 的 innerText 和页面呈现是 PAID。
反向对照:text-transform:lowercase 配合原文 PAID,浏览器显示 paid,提取仍为 PAID。没有 text-transform 的普通单元格提取与 innerText 一致。
预期:若按 #382 所述读取 rendered text,普通文本节点应保留应用 text-transform 后的显示内容。此处不是要求 OCR 或 CSS 伪元素生成内容;若该差异属于有意保留底层文本,建议在文档说明此例外。
原因线索与范围
tools/extract/collector.ts 自行遍历 text node 并处理 white-space,但没有应用 computed text-transform。本复现仅验证 ASCII upper/lower,不声称已验证所有语言的大小写、capitalize 或完整 CSS 文本算法。
本次检索公开 issue/所有状态 PR 的 text-transform、extract 等关键词,暂未找到相同报告。Related: #382 的 rendered-text 支持;#453 涉及隐藏内容而非文本转换。
独立浏览器复现脚本
在仓库根目录保存下面脚本为 reproduce-case.mjs,然后运行:
npm install --prefix /tmp/bsk-audit-runtime --no-audit --no-fund esbuild playwright
/tmp/bsk-audit-runtime/node_modules/.bin/playwright install chromium
node reproduce-case.mjs
要求环境能启动 Chromium;默认依赖路径为 /tmp/bsk-audit-runtime,可用 BSK_AUDIT_RUNTIME 指定。脚本中的断言用于确认当前差异;修复后预期会失败,不能把它作为修复后的回归断言。所有脚本均已实际执行并以退出码 0 完成。
完整脚本
import {createRequire} from 'node:module';
import {resolve} from 'node:path';
import {writeFile} from 'node:fs/promises';
const require=createRequire(resolve(process.env.BSK_AUDIT_RUNTIME || '/tmp/bsk-audit-runtime','package.json'));
const {build}=require('esbuild');
const {chromium}=require('playwright');
const root=process.cwd();
const bundle=await build({stdin:{contents:"export {collectExtractDom} from './apps/extension/src/tools/extract/collector'; export {validateExtract} from './apps/extension/src/tools/extract/validation'; export {normalizeExtract} from './apps/extension/src/tools/extract/normalize';",resolveDir:root,loader:'ts'},bundle:true,write:false,format:'iife',globalName:'Audit',platform:'browser',tsconfigRaw:{compilerOptions:{baseUrl:root,paths:{'@/*':['apps/extension/src/*']}}}});
const browser=await chromium.launch({channel:'chromium',headless:true,args:['--no-sandbox']});
try {
const page=await browser.newPage();
await page.setContent('<!doctype html><body>');
await page.addScriptTag({content:bundle.outputFiles[0].text});
const read=async(html)=>page.evaluate(html=>{
document.body.innerHTML=html;
const options=Audit.validateExtract({session_id:'audit',action:'table',selector:'#t'});
const raw=Audit.collectExtractDom.call(document.documentElement,options);
const el=document.querySelector('#t'),r=el.getBoundingClientRect();
return {rendered:el.innerText,width:r.width,height:r.height,error:raw.error,result:raw.error?null:Audit.normalizeExtract(raw,options,1,{page_url:location.href,frame_url:location.href,frame_id:'root',title:'audit',captured_at:raw.captured_at})};
},html);
const upper=await read('<table id="t"><tr><td style="text-transform:uppercase">paid</td></tr></table>');
const lower=await read('<table id="t"><tr><td style="text-transform:lowercase">PAID</td></tr></table>');
const control=await read('<table id="t"><tr><td>paid</td></tr></table>');
if (!(upper.rendered==='PAID' && upper.result.rows[0].c1==='paid' && lower.rendered==='paid' && lower.result.rows[0].c1==='PAID' && control.rendered===control.result.rows[0].c1)) throw Error('Unexpected result');
console.log(JSON.stringify({upper,lower,control},null,2));
} finally {await browser.close();}
- Lingua principale
- TypeScript
- Stelle
- 10.1k
- Fork
- 732
- Merge medio
- 2g 2h
- PR unite (30g)
- 92
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Tencent/BrowserSkill
-
录制 contenteditable 多行内容时 fill 值丢失换行Forse già presa @tlysanhuo l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
Tencent/BrowserSkill#594 ·
I maintainer di solito rispondono entro 1 giorno
-
录制遗漏 input[type=submit] 和 input[type=reset] 的真实点击Forse già presa @tlysanhuo l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
Tencent/BrowserSkill#593 ·
I maintainer di solito rispondono entro 1 giorno
-
docs: 补充 strict observation 的发放条件与扩展悬浮层遮挡的排查说明Forse già presa @Wang-MuFF l’ha presa 4 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
Tencent/BrowserSkill#551 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug] dsh-plugin skill: the injection-warning sentence added for #286 is itself a prompt-injection match, so the skill body gets blockedForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
Tencent/BrowserSkill#390 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 72/100
Tencent/BrowserSkill#633 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di Tencent/BrowserSkill
Issue simili
-
content triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
tensorflow/tfjs#8754 ·
-
tool-submission
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 83/100
BraveOPotato/NoSignups#2348 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
code-yeongyu/oh-my-openagent#12784 ·
I maintainer di solito rispondono entro 1 giorno
-
external-issue to-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 71/100
I maintainer di solito rispondono entro 1 giorno