mirror of
https://github.com/Tencent/BrowserSkill.git
synced 2026-10-02 07:34:35 +08:00
Merge pull request #304 from kevin9327/fix/long-screenshot-aria-case
fix(extension): treat ARIA loading tokens as case-insensitive
This commit is contained in:
@@ -313,6 +313,24 @@ describe("page capture cleanup", () => {
|
||||
}
|
||||
expect(await send({ action: "inspect" })).toMatchObject({ bottomReady: true });
|
||||
});
|
||||
it("waits for ARIA loading markers regardless of attribute case", async () => {
|
||||
const loader = document.createElement("div");
|
||||
loader.setAttribute("role", "PROGRESSBAR");
|
||||
loader.setAttribute("aria-busy", "TRUE");
|
||||
document.body.append(loader);
|
||||
vi.spyOn(loader, "getBoundingClientRect").mockReturnValue({
|
||||
top: 500,
|
||||
bottom: 530,
|
||||
width: 100,
|
||||
height: 30,
|
||||
} as DOMRect);
|
||||
await send({ action: "begin", label: "Capture", cancelLabel: "Cancel" });
|
||||
const moving = send({ action: "move", y: 1800, capture: true, final: true });
|
||||
await vi.advanceTimersByTimeAsync(2500);
|
||||
expect(await moving).toMatchObject({ bottomReady: false, loading: true });
|
||||
expect(await send({ action: "inspect" })).toMatchObject({ bottomReady: false, loading: true });
|
||||
});
|
||||
|
||||
it("does not treat article text, code examples or numeric progress widgets as loading", async () => {
|
||||
document.body.innerHTML +=
|
||||
'<p>Loading files in JavaScript</p><pre><code>Loading...</code></pre><div role="progressbar" aria-valuenow="100"></div>';
|
||||
|
||||
@@ -7,6 +7,10 @@ import {
|
||||
ScreenshotError,
|
||||
} from "./types";
|
||||
|
||||
function ariaToken(element: Element, name: string): string {
|
||||
return (element.getAttribute(name) ?? "").trim().toLowerCase();
|
||||
}
|
||||
|
||||
export function createPageCapture(onCancel: (id: string, reason: CaptureCancelReason) => void) {
|
||||
let task: ReturnType<typeof prepare> | undefined;
|
||||
|
||||
@@ -70,8 +74,11 @@ export function createPageCapture(onCancel: (id: string, reason: CaptureCancelRe
|
||||
const loadingText =
|
||||
/^(?:加载中|正在加载|载入中|loading(?:\s+(?:more|content|items|results))?)[\s.。…!!]*$/i;
|
||||
const trackLoading = (element: Element) => {
|
||||
const role = ariaToken(element, "role");
|
||||
if (
|
||||
element.matches('[aria-busy="true"], [role="progressbar"], [role="status"]') ||
|
||||
ariaToken(element, "aria-busy") === "true" ||
|
||||
role === "progressbar" ||
|
||||
role === "status" ||
|
||||
(element.childElementCount === 0 &&
|
||||
!element.closest("pre, code") &&
|
||||
loadingText.test(element.textContent?.trim() ?? ""))
|
||||
@@ -144,7 +151,7 @@ export function createPageCapture(onCancel: (id: string, reason: CaptureCancelRe
|
||||
seen.add(element);
|
||||
trackLoading(element);
|
||||
if (
|
||||
element.getAttribute("role") === "contentinfo" ||
|
||||
ariaToken(element, "role") === "contentinfo" ||
|
||||
(element.tagName === "FOOTER" && !element.closest("article, aside, section"))
|
||||
)
|
||||
footers.add(element);
|
||||
@@ -280,8 +287,8 @@ export function createPageCapture(onCancel: (id: string, reason: CaptureCancelRe
|
||||
const style = getComputedStyle(element);
|
||||
if (style.visibility === "hidden" || style.display === "none") continue;
|
||||
if (
|
||||
element.getAttribute("aria-busy") === "true" ||
|
||||
(element.getAttribute("role") === "progressbar" &&
|
||||
ariaToken(element, "aria-busy") === "true" ||
|
||||
(ariaToken(element, "role") === "progressbar" &&
|
||||
!element.hasAttribute("aria-valuenow")) ||
|
||||
(!element.closest("pre, code") && loadingText.test(element.textContent?.trim() ?? ""))
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user