From 95cfa046248de1510d88075f0e6fc2e367c417b8 Mon Sep 17 00:00:00 2001 From: Duncan Faulkner Date: Thu, 15 Oct 2026 22:40:13 +0100 Subject: [PATCH 1/2] fix(report): scan pages with a strict CSP or Trusted Types --- CHANGELOG.md | 11 +++++++++++ package-lock.json | 4 ++-- package.json | 2 +- src/report/headless.ts | 9 ++++++++- src/testing/e2e-report.spec.ts | 19 ++++++++++++++++++- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97adcfc..e308115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to `@ngbracket/a11y-devtools` are documented here. This project adheres to [Semantic Versioning](https://semver.org/). +## 0.18.3 + +### Fixed + +- Report mode now scans pages served with a strict Content-Security-Policy or + Trusted Types. The scan runs as an injected script, which a policy such as + `script-src 'self'` or `require-trusted-types-for 'script'` blocked, so the + page was reported as an error with no findings. The scanning browser now + bypasses the page's CSP. Your app's policy is unchanged; only the headless + browser that report mode starts ignores it. + ## 0.18.2 ### Fixed diff --git a/package-lock.json b/package-lock.json index 2cdf0fe..fb31bdb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ngbracket/a11y-devtools", - "version": "0.18.2", + "version": "0.18.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ngbracket/a11y-devtools", - "version": "0.18.2", + "version": "0.18.3", "license": "MIT", "dependencies": { "axe-core": "^4.13.0" diff --git a/package.json b/package.json index 8e75ecb..0f5764f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ngbracket/a11y-devtools", - "version": "0.18.2", + "version": "0.18.3", "description": "Finds accessibility problems in Angular apps and names the component behind each one. A dev overlay, or headless reports for CI.", "license": "MIT", "author": "Duncan Faulkner", diff --git a/src/report/headless.ts b/src/report/headless.ts index e6b8334..88f2ca2 100644 --- a/src/report/headless.ts +++ b/src/report/headless.ts @@ -214,7 +214,14 @@ async function scanPass( config: PassConfig, ): Promise { const { baseUrl, routes, labels, waitMs, axeOptions, inPageScript, frameworkPrefixes } = config; - const context = await browser.newContext({ viewport: { width: 1280, height: 900 }, colorScheme }); + // bypassCSP: the scan runs as an injected inline script (plus a style tag that + // hides the overlay), which a strict Content-Security-Policy or Trusted Types + // would block. It only lifts the policy in this scanning browser. + const context = await browser.newContext({ + viewport: { width: 1280, height: 900 }, + colorScheme, + bypassCSP: true, + }); const pages: PageReport[] = []; try { const page = await context.newPage(); diff --git a/src/testing/e2e-report.spec.ts b/src/testing/e2e-report.spec.ts index c99b3bb..e958095 100644 --- a/src/testing/e2e-report.spec.ts +++ b/src/testing/e2e-report.spec.ts @@ -57,6 +57,13 @@ const PAGES: Record = { Help `, + // Served with a strict Content-Security-Policy and Trusted Types (see the + // server below), which block the injected scan unless the browser bypasses CSP. + '/csp': ` +
+

Strict CSP

+ +
`, // Healthy: native controls in order, plus an iframe (Tab inside a frame shows // up as repeated focus on the