---
title: "Audit every page in a browser before · Agent Wranglers"
url: https://agentwranglers.se/playbook/website/site-architecture/browser-audits-before-release
updated: 2026-10-20
licence: "All rights reserved"
---

# Audit every page in a browser before release

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Site architecture](https://agentwranglers.se/playbook/website/site-architecture)
- Rule: Run an accessibility checker and a lab tool such as Lighthouse in a browser. Test light and dark mode, at phone and desktop width, and watch the console for policy errors.
- How: Script a browser driver, such as Playwright, to open every page type. Run axe-core, an accessibility checker, with the WCAG 2.0, 2.1 and 2.2 AA rules and best practices. Run Lighthouse, and collect console errors. Run the accessibility part in CI on every build, as in [accessibility in CI](https://agentwranglers.se/playbook/testing/non-functional-tests/accessibility-in-ci).
- Check: No axe violations and no console errors, such as CSP or Trusted Types errors, on any page. Run Lighthouse on the home page and one page of each type, and keep its scores as a record.

Example:

```js
import { chromium } from 'playwright';
import { readFileSync } from 'node:fs';
const axe = readFileSync('node_modules/axe-core/axe.min.js', 'utf8');
const browser = await chromium.launch();
for (const colorScheme of ['light', 'dark']) {
  const page = await browser.newPage({ colorScheme, viewport: { width: 360, height: 800 } });
  page.on('console', m => m.type() === 'error' && console.log('console:', m.text()));
  await page.goto('https://example.com/');
  // evaluate, not addScriptTag: a strict CSP blocks an injected <script>
  const { violations } = await page.evaluate(`(() => { ${axe}; return axe.run({
    runOnly: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa', 'best-practice'] }); })()`);
  console.log(colorScheme, violations.map(v => v.id));
}
await browser.close();
```

```python
from pathlib import Path
from playwright.sync_api import sync_playwright
axe = Path("node_modules/axe-core/axe.min.js").read_text()
run_axe = f"(() => {{ {axe}; return axe.run({{ runOnly: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa', 'best-practice'] }}); }})()"
with sync_playwright() as p:
    browser = p.chromium.launch()
    for scheme in ("light", "dark"):
        page = browser.new_page(color_scheme=scheme, viewport={"width": 360, "height": 800})
        page.on("console", lambda m: m.type == "error" and print("console:", m.text))
        page.goto("https://example.com/")
        print(scheme, [v["id"] for v in page.evaluate(run_axe)["violations"]])
    browser.close()
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers website playbook: https://agentwranglers.se/playbook/website/site-architecture/browser-audits-before-release`.

- Previous: [Keep the previous build's assets](https://agentwranglers.se/playbook/website/site-architecture/keep-the-previous-build-s-assets)
- [Site architecture](https://agentwranglers.se/playbook/website/site-architecture)
