feat: add evidence search and stabilize pdf previews
- add document evidence parsing/search/open routes, Hermes tool wiring, local index settings/status, and the document-evidence skill plus design notes - fix PDF resource tabs by rendering PDFs inline with pdf.js canvases instead of iframe preview pages, release PDF documents on close, and document the fourth-PDF stall bug - keep PDF preview at 2x rendering while removing the previous lazy-load/placeholder direction, and make dev:hot bind loopback defaults externally reachable Verification: - node --check rust/crates/mnote-web/browser/document-resource-tab-runtime.js - node scripts/task-dev-hot-plan-test.js - cargo test -p mnote-web --manifest-path rust/Cargo.toml pdf_preview_page_does_not_render_visible_toolbar - cargo test -p mnote-web --manifest-path rust/Cargo.toml document_shell_returns_page_aggregate_snapshot - cargo build -p mnote-web --manifest-path rust/Cargo.toml - browser smoke: sequentially opened the four tea_seed_oil_cosmetic PDFs; fourth PDF rendered 15/15 canvases, iframeCount=0, browser errors=0
This commit is contained in:
@@ -148,16 +148,21 @@ async function main() {
|
||||
const watchBatchBeforeOcr = await page.evaluate(() => document.documentElement.getAttribute("data-mnote-local-folder-watch-batch-applied") || "");
|
||||
await page.getByTestId("mnote-local-ocr-task-toggle").waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
|
||||
await page.getByTestId("mnote-local-ocr-task-toggle").click({ timeout: UI_TIMEOUT_MS });
|
||||
await page.getByTestId("mnote-local-ocr-settings-popover").waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
|
||||
await page.locator('[data-local-ocr-settings-action="run-active"]').click({ timeout: UI_TIMEOUT_MS });
|
||||
await page.getByTestId("mnote-local-ocr-task-drawer").waitFor({ state: "hidden", timeout: UI_TIMEOUT_MS });
|
||||
const topbarOcrButtonInfo = await page.getByTestId("mnote-local-ocr-task-toggle").evaluate((node) => {
|
||||
const topbar = node.closest(".wolai-topbar-actions");
|
||||
return {
|
||||
inTopbar: Boolean(topbar),
|
||||
action: node.getAttribute("data-mnote-action") || "",
|
||||
label: node.getAttribute("aria-label") || "",
|
||||
text: node.textContent || "",
|
||||
badge: node.querySelector("[data-mnote-local-ocr-task-count]")?.textContent || "",
|
||||
};
|
||||
});
|
||||
assert.equal(topbarOcrButtonInfo.inTopbar, true, `OCR 任务入口应位于右上角 topbar: ${JSON.stringify(topbarOcrButtonInfo)}`);
|
||||
assert.equal(topbarOcrButtonInfo.inTopbar, true, `OCR 设置入口应位于右上角 topbar: ${JSON.stringify(topbarOcrButtonInfo)}`);
|
||||
assert.equal(topbarOcrButtonInfo.action, "open-ocr-settings", `OCR 顶栏按钮应打开设置: ${JSON.stringify(topbarOcrButtonInfo)}`);
|
||||
await page.waitForFunction(
|
||||
(sourcePath) => {
|
||||
const row = document.querySelector(`[data-mnote-local-ocr-task-row="${CSS.escape(sourcePath)}"]`);
|
||||
@@ -167,6 +172,8 @@ async function main() {
|
||||
{ timeout: UI_TIMEOUT_MS },
|
||||
);
|
||||
await page.getByTestId("mnote-local-ocr-task-toggle").click({ timeout: UI_TIMEOUT_MS });
|
||||
await page.getByTestId("mnote-local-ocr-settings-popover").waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
|
||||
await page.locator('[data-local-ocr-settings-action="tasks"]').click({ timeout: UI_TIMEOUT_MS });
|
||||
await page.getByTestId("mnote-local-ocr-task-drawer").waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
|
||||
const uiOcrPath = await page.evaluate(async ({ rootUri, sourceRootRelativePath }) => {
|
||||
const url = new URL("/api/local-folder/ocr/status", window.location.origin);
|
||||
@@ -247,6 +254,8 @@ async function main() {
|
||||
timeout: UI_TIMEOUT_MS,
|
||||
});
|
||||
await page.getByTestId("mnote-local-ocr-task-toggle").click({ timeout: UI_TIMEOUT_MS });
|
||||
await page.getByTestId("mnote-local-ocr-settings-popover").waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
|
||||
await page.locator('[data-local-ocr-settings-action="run-active"]').click({ timeout: UI_TIMEOUT_MS });
|
||||
await page.waitForFunction(
|
||||
(sourcePath) => {
|
||||
const row = document.querySelector(`[data-mnote-local-ocr-task-row="${CSS.escape(sourcePath)}"]`);
|
||||
@@ -322,9 +331,28 @@ async function main() {
|
||||
return { ok: true, parentPath };
|
||||
}, uiOcrPath);
|
||||
assert.equal(fileTreeOpenResult.ok, true, `OCR sidecar parent should exist in filetree: ${JSON.stringify(fileTreeOpenResult)}`);
|
||||
const ocrFileTreeRow = page.locator(`#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-local-relative-path="${uiOcrPath.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"]`).first();
|
||||
await ocrFileTreeRow.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
|
||||
await ocrFileTreeRow.click({ timeout: UI_TIMEOUT_MS });
|
||||
const ocrFileTreeOpenResult = await page.waitForFunction(
|
||||
(ocrRootRelativePath) => {
|
||||
const rows = Array.from(document.querySelectorAll('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"]'));
|
||||
const exact = rows.find((row) => row.getAttribute("data-local-relative-path") === ocrRootRelativePath);
|
||||
const fileName = ocrRootRelativePath.split("/").filter(Boolean).pop() || ocrRootRelativePath;
|
||||
const fallback = rows.find((row) => {
|
||||
const relativePath = row.getAttribute("data-local-relative-path") || "";
|
||||
return relativePath.endsWith(`/${fileName}`) || relativePath === fileName || (row.textContent || "").includes(fileName);
|
||||
});
|
||||
const target = exact || fallback;
|
||||
if (!(target instanceof HTMLElement)) return false;
|
||||
target.click();
|
||||
return {
|
||||
ok: true,
|
||||
exact: Boolean(exact),
|
||||
relativePath: target.getAttribute("data-local-relative-path") || "",
|
||||
};
|
||||
},
|
||||
uiOcrPath,
|
||||
{ timeout: UI_TIMEOUT_MS },
|
||||
).then((handle) => handle.jsonValue());
|
||||
assert.equal(ocrFileTreeOpenResult.ok, true, `OCR sidecar filetree row should open: ${JSON.stringify(ocrFileTreeOpenResult)}`);
|
||||
await page.waitForFunction(
|
||||
() => document.documentElement.getAttribute("data-mnote-local-ocr-filetree-open") === "resource-tab",
|
||||
null,
|
||||
|
||||
Reference in New Issue
Block a user