Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions scanner/.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,5 @@
!codec/*.c
!codec/*.patch

!site-preview.mjs

!page-image.mjs
!jpeg.mjs
4 changes: 2 additions & 2 deletions scanner/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ RUN node node_modules/playwright/cli.js install-deps chromium \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

FROM chromium-runtime AS worker
COPY worker.mjs preview.mjs site-preview.mjs page-image.mjs jpeg.mjs public-worker.mjs public-report.mjs public-report.test.mjs ./
COPY worker.mjs preview.mjs page-image.mjs jpeg.mjs public-worker.mjs public-report.mjs public-report.test.mjs ./
COPY gateway/ ./gateway/
COPY firewall/ ./firewall/
COPY fixtures/ ./fixtures/
Expand Down Expand Up @@ -99,7 +99,7 @@ WORKDIR /opt/kindpath-worker
COPY package.json package-lock.json ./
RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force \
&& rm -rf /usr/lib/node_modules/npm /usr/bin/npm /usr/bin/npx /root/.npm
COPY worker.mjs preview.mjs site-preview.mjs page-image.mjs jpeg.mjs public-worker.mjs public-report.mjs public-report.test.mjs ./
COPY worker.mjs preview.mjs page-image.mjs jpeg.mjs public-worker.mjs public-report.mjs public-report.test.mjs ./
COPY gateway/ ./gateway/
COPY firewall/ ./firewall/
COPY fixtures/ ./fixtures/
Expand Down
23 changes: 13 additions & 10 deletions scanner/public-report.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,22 @@ export function analyzePublicPage(page) {

// Bound worker output without presenting a shortened list as the complete result.
export function summarizeRules(rules) {
const selected = rules.slice(0, 100);
const selected = rules.slice(0, 100).map(rule => ({
id: rule.id, impact: rule.impact ?? 'unknown', help: rule.help,
description: rule.description, helpUrl: rule.helpUrl,
nodes: rule.nodes.slice(0, 20).flatMap(node => {
if (node.target.length > 100) return [];
const target = node.target.map(selector => typeof selector === 'string' ? selector : JSON.stringify(selector));
// A shortened selector could point to the wrong element.
if (target.some(selector => selector.length > 4000)) return [];
return [{ target, summary: (node.failureSummary ?? '').slice(0, 2000) }];
}),
}));
return {
omittedRules: rules.length - selected.length,
omittedNodes: rules.reduce((count, rule) => count + rule.nodes.length, 0)
- selected.reduce((count, rule) => count + Math.min(rule.nodes.length, 20), 0),
rules: selected.map(rule => ({
id: rule.id, impact: rule.impact ?? 'unknown', help: rule.help,
description: rule.description, helpUrl: rule.helpUrl,
nodes: rule.nodes.slice(0, 20).map(node => ({
target: node.target.map(selector => typeof selector === 'string' ? selector : JSON.stringify(selector)),
summary: (node.failureSummary ?? '').slice(0, 2000),
})),
})),
- selected.reduce((count, rule) => count + rule.nodes.length, 0),
rules: selected,
};
}

Expand Down
14 changes: 14 additions & 0 deletions scanner/public-report.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,17 @@ test('complete and empty result sets have no omitted items', () => {
assert.equal(output.omittedRules, 0); assert.equal(output.omittedNodes, 0);
assert.equal(output.rules[0].nodes[0].summary, 'review');
});

test('oversized selector paths omit the element and preserve the rule and valid elements', () => {
const boundary = 'a'.repeat(4000);
const output = summarizeRules([{ ...rule, nodes: [
{ ...node, target: [boundary + 'a'] },
{ ...node, target: [[boundary]] },
{ ...node, target: Array(101).fill('a') },
{ ...node, target: Array(100).fill(boundary) },
] }]);
assert.equal(output.omittedRules, 0);
assert.equal(output.omittedNodes, 3);
assert.equal(output.rules[0].id, rule.id);
assert.deepEqual(output.rules[0].nodes, [{ target: Array(100).fill(boundary), summary: 'review' }]);
});
130 changes: 0 additions & 130 deletions scanner/site-preview.mjs

This file was deleted.

8 changes: 5 additions & 3 deletions scripts/preview-browser.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,6 @@ try {
{...publicReport.coverage,failedRequests:-1},{blockedRequests:0,failedRequests:0,omittedRules:0,omittedNodes:2}]) {
publicResponse={...publicReport,findings:[],coverage};
await publicButton.click();
await page.waitForFunction(()=>document.querySelector('form').getAttribute('aria-busy')==='false');
await coverageNotice.waitFor();
const text=await coverageNotice.textContent();
assert.ok(text.includes('Zero violations does not establish accessibility conformance.'));
Expand Down Expand Up @@ -951,10 +950,13 @@ try {
await publicButton.click();
await heldCancellation;
assert.equal(publicHeld, true);
const scanStatus = page.locator('form').getByRole('status');
await scanStatus.filter({ hasText: 'Checking the page and preparing your report' }).waitFor();
assert.equal(await scanStatus.evaluate(status => status.closest('[aria-busy="true"]')), null);
assert.equal(await websiteEntry.getAttribute('readonly'), '');
assert.deepEqual(await landingPositions(), beforeMobileScan, 'A pending scan must also keep the mobile landing controls in place');
await page.getByRole('button', {name:'Cancel request',exact:true}).click();
await page.getByRole('status').filter({hasText:'Request cancelled'}).waitFor();
await scanStatus.filter({hasText:'Request cancelled'}).waitFor();
assert.equal(await sprout.count(), 0);
assert.equal(await frog.evaluate(node => getComputedStyle(node).animationName), 'none');
assert.equal(await page.locator('.results').count(), 0);
Expand All @@ -970,7 +972,7 @@ try {
assert.equal(await scanRetry.evaluate(node => node === document.activeElement), true);
publicResponseOverride = undefined;
await scanRetry.click();
await page.locator('.results').waitFor();
await scanStatus.filter({hasText:'Report ready.'}).waitFor();
await assertDownload(publicResponse);
// The draft URL and the already-completed report are independent.
await page.getByRole('button', { name: /Visual preview/ }).click();
Expand Down
2 changes: 1 addition & 1 deletion scripts/validate-chrome.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ try {
if (index === 0) await input.press("Enter");
else await page.getByRole("button", { name: "Scan website", exact: true }).click();
await page.locator(".results").waitFor({ state: "detached" });
await page.waitForFunction(() => document.querySelector("form")?.getAttribute("aria-busy") === "false", void 0, { timeout: 1e5 });
await page.waitForFunction(() => document.querySelector('button[type="submit"]')?.disabled === false, void 0, { timeout: 1e5 });
assert.equal(requests, before + 1);
assert.ok(actual);
const report = actual.report;
Expand Down
2 changes: 1 addition & 1 deletion src/components/WebsiteForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function WebsiteForm({ url, activity, reportReady, onViewReport, onCancel
return <form ref={form} onSubmit={event => {
if (fieldError) urlInput.current?.focus();
onSubmit(event);
}} aria-busy={busy}>
}}>
<label htmlFor="website">Your website URL</label>
<div className={fieldError ? "url-field url-field-invalid" : "url-field"}>
<input
Expand Down
Loading