webguardx 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../node_modules/tsup/assets/cjs_shims.js","../src/config/schema.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/utils/logger.ts","../src/runner/index.ts","../src/auth/strategies/api-login.ts","../src/utils/fs.ts","../src/auth/strategies/form-login.ts","../src/auth/strategies/cookie-inject.ts","../src/auth/strategies/bearer-token.ts","../src/auth/index.ts","../src/audits/http-status.ts","../src/audits/content-visibility.ts","../src/audits/accessibility.ts","../src/utils/sanitize.ts","../src/audits/lighthouse.ts","../src/audits/broken-links.ts","../src/audits/console-errors.ts","../src/audits/index.ts","../src/runner/page-runner.ts","../src/utils/sleep.ts","../src/runner/retry.ts","../src/runner/parallel.ts","../src/runner/setup.ts","../src/reporters/json.ts","../src/reporters/terminal.ts","../src/reporters/html.ts","../src/reporters/junit.ts","../src/reporters/screenshot.ts","../src/reporters/index.ts","../src/plugins/registry.ts","../src/plugins/loader.ts","../src/notifications/webhook.ts","../src/notifications/slack.ts","../src/notifications/index.ts","../src/baseline/storage.ts","../src/baseline/diff.ts"],"sourcesContent":["// Core API\nexport { defineConfig } from \"./config/defaults.js\";\nexport { loadConfig } from \"./config/loader.js\";\nexport { run } from \"./runner/index.js\";\n\n// Types\nexport type { WebguardConfig, PageEntry, AuthConfig } from \"./config/schema.js\";\nexport type { AuditResult, PageResult, RunResult, AuditSeverity } from \"./types/index.js\";\nexport type { RunOptions } from \"./runner/index.js\";\nexport type { Audit, AuditContext } from \"./audits/index.js\";\n\n// Plugin system\nexport type { WebguardPlugin, Reporter, LifecycleHooks } from \"./plugins/types.js\";\nexport { PluginRegistry } from \"./plugins/registry.js\";\nexport { loadPlugins } from \"./plugins/loader.js\";\n\n// Notifications\nexport type { NotificationChannel } from \"./notifications/types.js\";\nexport { createWebhookNotifier } from \"./notifications/webhook.js\";\nexport { createSlackNotifier } from \"./notifications/slack.js\";\nexport { sendNotifications } from \"./notifications/index.js\";\n\n// Baseline\nexport type { BaselineComparison, AuditChange } from \"./baseline/types.js\";\nexport { saveBaseline, loadBaseline, compareRuns } from \"./baseline/index.js\";\n\n// Audits (for custom composition)\nexport { HttpStatusAudit } from \"./audits/http-status.js\";\nexport { ContentVisibilityAudit } from \"./audits/content-visibility.js\";\nexport { AccessibilityAudit } from \"./audits/accessibility.js\";\nexport { LighthouseAudit } from \"./audits/lighthouse.js\";\nexport { BrokenLinksAudit } from \"./audits/broken-links.js\";\nexport { ConsoleErrorsAudit } from \"./audits/console-errors.js\";\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { z } from \"zod\";\n\nconst AuthApiLoginSchema = z.object({\n method: z.literal(\"api-login\"),\n loginUrl: z.string().url(),\n payload: z.record(z.string()),\n headers: z.record(z.string()).optional(),\n});\n\nconst AuthFormLoginSchema = z.object({\n method: z.literal(\"form-login\"),\n loginUrl: z.string().url(),\n fields: z.array(\n z.object({\n selector: z.string(),\n value: z.string(),\n })\n ),\n submitSelector: z.string(),\n waitAfterLogin: z.string().optional(),\n});\n\nconst AuthCookieSchema = z.object({\n method: z.literal(\"cookie\"),\n cookies: z.array(\n z.object({\n name: z.string(),\n value: z.string(),\n domain: z.string(),\n path: z.string().default(\"/\"),\n })\n ),\n});\n\nconst AuthBearerSchema = z.object({\n method: z.literal(\"bearer-token\"),\n token: z.string(),\n});\n\nconst AuthNoneSchema = z.object({\n method: z.literal(\"none\"),\n});\n\nconst AuthSchema = z.discriminatedUnion(\"method\", [\n AuthApiLoginSchema,\n AuthFormLoginSchema,\n AuthCookieSchema,\n AuthBearerSchema,\n AuthNoneSchema,\n]);\n\nconst PageSchema = z.object({\n name: z.string(),\n path: z.string(),\n expectedStatus: z.number().default(200),\n skipAudits: z.array(z.string()).optional(),\n});\n\nconst LighthouseThresholdsSchema = z\n .object({\n performance: z.number().min(0).max(100).default(50),\n accessibility: z.number().min(0).max(100).default(90),\n bestPractices: z.number().min(0).max(100).default(80),\n seo: z.number().min(0).max(100).default(80),\n })\n .partial();\n\nexport const WebguardConfigSchema = z.object({\n baseURL: z.string().url(),\n\n pages: z.array(PageSchema).min(1),\n\n auth: AuthSchema.default({ method: \"none\" }),\n\n // Open record — built-in keys have defaults, custom audit keys are allowed\n audits: z\n .record(z.string(), z.boolean())\n .default({\n httpStatus: true,\n contentVisibility: true,\n accessibility: true,\n lighthouse: false,\n brokenLinks: false,\n consoleErrors: true,\n }),\n\n // Custom audits defined inline in config\n customAudits: z.array(z.any()).default([]),\n\n // Plugins — objects or string paths to npm packages / local files\n plugins: z.array(z.any()).default([]),\n\n wcagTags: z\n .array(z.string())\n .default([\"wcag2a\", \"wcag2aa\", \"wcag21a\", \"wcag21aa\"]),\n\n lighthouseThresholds: LighthouseThresholdsSchema.default({}),\n\n retry: z\n .object({\n maxRetries: z.number().min(1).default(3),\n delayMs: z.number().min(0).default(5000),\n })\n .default({}),\n\n runner: z\n .object({\n concurrency: z.number().min(1).default(1),\n failFast: z.boolean().default(false),\n })\n .default({}),\n\n browser: z\n .object({\n headless: z.boolean().default(true),\n timeout: z.number().default(60000),\n viewport: z\n .object({\n width: z.number().default(1280),\n height: z.number().default(720),\n })\n .default({}),\n })\n .default({}),\n\n output: z\n .object({\n dir: z.string().default(\"./webguard-results\"),\n formats: z\n .array(z.enum([\"terminal\", \"html\", \"json\", \"junit\"]))\n .default([\"terminal\", \"html\", \"json\"]),\n screenshots: z.boolean().default(true),\n screenshotOnFailOnly: z.boolean().default(false),\n })\n .default({}),\n\n baseline: z\n .object({\n enabled: z.boolean().default(false),\n updateOnPass: z.boolean().default(true),\n })\n .default({}),\n\n notifications: z.array(z.any()).default([]),\n});\n\nexport type WebguardConfig = z.infer<typeof WebguardConfigSchema>;\nexport type PageEntry = z.infer<typeof PageSchema>;\nexport type AuthConfig = z.infer<typeof AuthSchema>;\nexport type AuditsConfig = WebguardConfig[\"audits\"];\n","import { z } from \"zod\";\nimport { WebguardConfigSchema, type WebguardConfig } from \"./schema.js\";\n\ntype WebguardConfigInput = z.input<typeof WebguardConfigSchema>;\n\nexport function defineConfig(config: WebguardConfigInput): WebguardConfig {\n return WebguardConfigSchema.parse(config);\n}\n","import path from \"path\";\nimport fs from \"fs\";\nimport { WebguardConfigSchema, type WebguardConfig } from \"./schema.js\";\nimport { log } from \"../utils/logger.js\";\n\nconst CONFIG_NAMES = [\n \"webguard.config.ts\",\n \"webguard.config.js\",\n \"webguard.config.mjs\",\n \"webguard.config.json\",\n];\n\nexport async function loadConfig(\n configPath?: string\n): Promise<WebguardConfig> {\n const resolvedPath = configPath\n ? path.resolve(configPath)\n : findConfigFile();\n\n if (!resolvedPath) {\n throw new Error(\n `No webguard config found. Run \"webguardx init\" to create one, or specify --config <path>.`\n );\n }\n\n log.info(`Loading config from ${path.relative(process.cwd(), resolvedPath)}`);\n\n let rawConfig: unknown;\n\n if (resolvedPath.endsWith(\".json\")) {\n const content = fs.readFileSync(resolvedPath, \"utf-8\");\n rawConfig = JSON.parse(content);\n } else {\n // Use jiti for runtime TypeScript/ESM loading\n const { createJiti } = await import(\"jiti\");\n const jiti = createJiti(import.meta.url);\n const mod = await jiti.import(resolvedPath);\n rawConfig = (mod as any).default ?? mod;\n }\n\n const result = WebguardConfigSchema.safeParse(rawConfig);\n\n if (!result.success) {\n const errors = result.error.issues\n .map((i) => ` - ${i.path.join(\".\")}: ${i.message}`)\n .join(\"\\n\");\n throw new Error(`Invalid webguard config:\\n${errors}`);\n }\n\n return result.data;\n}\n\nfunction findConfigFile(): string | null {\n const cwd = process.cwd();\n for (const name of CONFIG_NAMES) {\n const fullPath = path.join(cwd, name);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n","import chalk from \"chalk\";\n\nexport const log = {\n info(msg: string) {\n console.log(chalk.blue(\"i\"), msg);\n },\n success(msg: string) {\n console.log(chalk.green(\"✓\"), msg);\n },\n warn(msg: string) {\n console.log(chalk.yellow(\"⚠\"), msg);\n },\n error(msg: string) {\n console.log(chalk.red(\"✗\"), msg);\n },\n dim(msg: string) {\n console.log(chalk.dim(msg));\n },\n plain(msg: string) {\n console.log(msg);\n },\n};\n","import { chromium } from \"playwright\";\nimport type { WebguardConfig } from \"../config/schema.js\";\nimport type { RunResult, PageResult } from \"../types/index.js\";\nimport { authenticate } from \"../auth/index.js\";\nimport { getEnabledAudits } from \"../audits/index.js\";\nimport { runPageAudits } from \"./page-runner.js\";\nimport { runPagesParallel } from \"./parallel.js\";\nimport { setupRunDirectory } from \"./setup.js\";\nimport { runReporters } from \"../reporters/index.js\";\nimport { PluginRegistry, loadPlugins } from \"../plugins/index.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport interface RunOptions {\n headed?: boolean;\n pagesFilter?: string[];\n auditsFilter?: string[];\n}\n\nexport async function run(\n config: WebguardConfig,\n options: RunOptions = {}\n): Promise<RunResult> {\n const start = Date.now();\n\n // Override headless from CLI\n if (options.headed !== undefined) {\n config.browser.headless = !options.headed;\n }\n\n // Load plugins\n const registry = new PluginRegistry();\n if (config.plugins.length > 0) {\n const plugins = await loadPlugins(config.plugins);\n for (const plugin of plugins) {\n registry.register(plugin);\n }\n }\n\n // Setup run directory\n const { runDir } = setupRunDirectory(config.output.dir);\n\n // Authenticate\n const authResult = await authenticate(config.auth, runDir);\n\n // Launch browser\n const browser = await chromium.launch({\n headless: config.browser.headless,\n });\n\n const contextOptions: any = {\n viewport: config.browser.viewport,\n };\n\n if (authResult?.storageStatePath) {\n contextOptions.storageState = authResult.storageStatePath;\n }\n if (authResult?.extraHeaders) {\n contextOptions.extraHTTPHeaders = authResult.extraHeaders;\n }\n\n const browserContext = await browser.newContext(contextOptions);\n\n // beforeAll hook\n await registry.runHook(\"beforeAll\", { config, browserContext });\n\n // Get enabled audits (built-in + plugin + custom)\n let audits = getEnabledAudits(\n config.audits,\n registry.getPluginAudits(),\n config.customAudits\n );\n\n // Filter audits if specified\n if (options.auditsFilter?.length) {\n audits = audits.filter((a) => options.auditsFilter!.includes(a.name));\n }\n\n const enabledAuditNames = audits.map((a) => a.name);\n\n // Filter pages if specified\n let pages = config.pages;\n if (options.pagesFilter?.length) {\n pages = pages.filter((p) => options.pagesFilter!.includes(p.name));\n }\n\n log.plain(\"\");\n log.info(`Base URL: ${config.baseURL}`);\n log.info(`Pages: ${pages.length}`);\n log.info(`Audits: ${enabledAuditNames.join(\", \")}`);\n if (config.plugins.length > 0) {\n log.info(`Plugins: ${config.plugins.length}`);\n }\n if (config.runner.concurrency > 1) {\n log.info(`Workers: ${config.runner.concurrency}`);\n }\n log.plain(\"\");\n\n // Run audits on each page\n let pageResults: PageResult[];\n\n if (config.runner.concurrency > 1) {\n // Parallel execution\n pageResults = await runPagesParallel(\n pages,\n config,\n browserContext,\n audits,\n runDir,\n registry,\n config.runner.concurrency,\n config.runner.failFast\n );\n } else {\n // Sequential execution\n pageResults = [];\n\n for (let i = 0; i < pages.length; i++) {\n const pageEntry = pages[i];\n log.plain(` [${i + 1}/${pages.length}] ${pageEntry.name} (${pageEntry.path})`);\n\n const result = await runPageAudits(\n pageEntry,\n config,\n browserContext,\n audits,\n runDir,\n registry\n );\n pageResults.push(result);\n\n // Print inline results\n for (const audit of result.audits) {\n const icon = audit.passed ? \" \\u2713\" : audit.severity === \"warning\" ? \" \\u26A0\" : \" \\u2717\";\n const duration = audit.duration ? `${audit.duration}ms` : \"\";\n log.plain(`${icon} ${audit.audit.padEnd(20)} ${audit.message.padEnd(30)} ${duration}`);\n }\n log.plain(\"\");\n\n // Fail fast\n if (config.runner.failFast && result.audits.some((a) => a.severity === \"fail\")) {\n log.warn(\"Fail fast enabled — stopping after first failure\");\n break;\n }\n }\n }\n\n await browserContext.close();\n await browser.close();\n\n // Build summary\n const allAudits = pageResults.flatMap((p) => p.audits);\n const runResult: RunResult = {\n timestamp: new Date().toISOString(),\n config: {\n baseURL: config.baseURL,\n totalPages: pages.length,\n auditsEnabled: enabledAuditNames,\n },\n pages: pageResults,\n summary: {\n totalAudits: allAudits.length,\n passed: allAudits.filter((a) => a.severity === \"pass\").length,\n failed: allAudits.filter((a) => a.severity === \"fail\").length,\n warnings: allAudits.filter((a) => a.severity === \"warning\").length,\n skipped: allAudits.filter((a) => a.severity === \"skip\").length,\n duration: Date.now() - start,\n },\n };\n\n // afterAll hook\n await registry.runHook(\"afterAll\", { config, result: runResult });\n\n // Run reporters (built-in + plugin)\n await runReporters(runResult, config, runDir, registry.getPluginReporters());\n\n return runResult;\n}\n","import { request } from \"playwright\";\nimport path from \"path\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport type { AuthResult } from \"../index.js\";\n\ninterface ApiLoginConfig {\n method: \"api-login\";\n loginUrl: string;\n payload: Record<string, string>;\n headers?: Record<string, string>;\n}\n\nexport async function apiLogin(\n config: ApiLoginConfig,\n outputDir: string\n): Promise<AuthResult> {\n const authDir = path.join(outputDir, \".auth\");\n ensureDir(authDir);\n const storagePath = path.join(authDir, \"storageState.json\");\n\n const origin = new URL(config.loginUrl).origin;\n const context = await request.newContext({ baseURL: origin });\n\n const response = await context.post(config.loginUrl, {\n data: config.payload,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n ...config.headers,\n },\n });\n\n if (!response.ok()) {\n const body = await response.text();\n await context.dispose();\n throw new Error(`Login failed (HTTP ${response.status()}): ${body}`);\n }\n\n await context.storageState({ path: storagePath });\n await context.dispose();\n\n return { storageStatePath: storagePath };\n}\n","import fs from \"fs\";\nimport path from \"path\";\n\nexport function ensureDir(dir: string): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n\nexport function cleanDir(dir: string): void {\n if (fs.existsSync(dir)) {\n fs.rmSync(dir, { recursive: true, force: true });\n }\n}\n\nexport function ensureCleanDir(dir: string): void {\n cleanDir(dir);\n fs.mkdirSync(dir, { recursive: true });\n}\n\nexport function writeJson(filePath: string, data: unknown): void {\n ensureDir(path.dirname(filePath));\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2));\n}\n","import { chromium } from \"playwright\";\nimport path from \"path\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport type { AuthResult } from \"../index.js\";\n\ninterface FormLoginConfig {\n method: \"form-login\";\n loginUrl: string;\n fields: Array<{ selector: string; value: string }>;\n submitSelector: string;\n waitAfterLogin?: string;\n}\n\nexport async function formLogin(\n config: FormLoginConfig,\n outputDir: string\n): Promise<AuthResult> {\n const authDir = path.join(outputDir, \".auth\");\n ensureDir(authDir);\n const storagePath = path.join(authDir, \"storageState.json\");\n\n const browser = await chromium.launch({ headless: true });\n const context = await browser.newContext();\n const page = await context.newPage();\n\n await page.goto(config.loginUrl);\n\n for (const field of config.fields) {\n await page.fill(field.selector, field.value);\n }\n\n await page.click(config.submitSelector);\n\n if (config.waitAfterLogin) {\n if (config.waitAfterLogin.startsWith(\"http\")) {\n await page.waitForURL(config.waitAfterLogin);\n } else {\n await page.waitForSelector(config.waitAfterLogin);\n }\n } else {\n await page.waitForLoadState(\"networkidle\");\n }\n\n await context.storageState({ path: storagePath });\n await browser.close();\n\n return { storageStatePath: storagePath };\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport type { AuthResult } from \"../index.js\";\n\ninterface CookieConfig {\n method: \"cookie\";\n cookies: Array<{\n name: string;\n value: string;\n domain: string;\n path: string;\n }>;\n}\n\nexport async function cookieInject(\n config: CookieConfig,\n outputDir: string\n): Promise<AuthResult> {\n const authDir = path.join(outputDir, \".auth\");\n ensureDir(authDir);\n const storagePath = path.join(authDir, \"storageState.json\");\n\n const storageState = {\n cookies: config.cookies.map((c) => ({\n name: c.name,\n value: c.value,\n domain: c.domain,\n path: c.path || \"/\",\n expires: -1,\n httpOnly: false,\n secure: true,\n sameSite: \"Lax\" as const,\n })),\n origins: [],\n };\n\n fs.writeFileSync(storagePath, JSON.stringify(storageState, null, 2));\n return { storageStatePath: storagePath };\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport type { AuthResult } from \"../index.js\";\n\ninterface BearerConfig {\n method: \"bearer-token\";\n token: string;\n}\n\nexport async function bearerToken(\n config: BearerConfig,\n outputDir: string\n): Promise<AuthResult> {\n const authDir = path.join(outputDir, \".auth\");\n ensureDir(authDir);\n const storagePath = path.join(authDir, \"storageState.json\");\n\n fs.writeFileSync(\n storagePath,\n JSON.stringify({ cookies: [], origins: [] })\n );\n\n return {\n storageStatePath: storagePath,\n extraHeaders: { Authorization: `Bearer ${config.token}` },\n };\n}\n","import type { AuthConfig } from \"../config/schema.js\";\nimport { apiLogin } from \"./strategies/api-login.js\";\nimport { formLogin } from \"./strategies/form-login.js\";\nimport { cookieInject } from \"./strategies/cookie-inject.js\";\nimport { bearerToken } from \"./strategies/bearer-token.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport interface AuthResult {\n storageStatePath: string;\n extraHeaders?: Record<string, string>;\n}\n\nexport async function authenticate(\n authConfig: AuthConfig,\n outputDir: string\n): Promise<AuthResult | null> {\n if (authConfig.method === \"none\") {\n return null;\n }\n\n log.info(`Authenticating via ${authConfig.method}...`);\n\n let result: AuthResult;\n\n switch (authConfig.method) {\n case \"api-login\":\n result = await apiLogin(authConfig, outputDir);\n break;\n case \"form-login\":\n result = await formLogin(authConfig, outputDir);\n break;\n case \"cookie\":\n result = await cookieInject(authConfig, outputDir);\n break;\n case \"bearer-token\":\n result = await bearerToken(authConfig, outputDir);\n break;\n }\n\n log.success(\"Authenticated successfully\");\n return result;\n}\n","import type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport const HttpStatusAudit: Audit = {\n name: \"httpStatus\",\n description: \"Verify the page returns the expected HTTP status code\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const status = ctx.navigationResponse?.status() ?? 0;\n const expected = ctx.pageEntry.expectedStatus ?? 200;\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: status === expected,\n severity: status === expected ? \"pass\" : \"fail\",\n message:\n status === expected\n ? `HTTP ${status} OK`\n : `Expected HTTP ${expected}, got ${status}`,\n details: { status, expected },\n };\n },\n};\n","import type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport const ContentVisibilityAudit: Audit = {\n name: \"contentVisibility\",\n description: \"Verify the page has visible rendered content\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const { page } = ctx;\n\n const bodyVisible = await page\n .locator(\"body\")\n .isVisible()\n .catch(() => false);\n\n if (!bodyVisible) {\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: false,\n severity: \"fail\",\n message: \"Page body is not visible\",\n details: { bodyVisible: false, textLength: 0, elementCount: 0 },\n };\n }\n\n const bodyText = await page\n .locator(\"body\")\n .innerText()\n .catch(() => \"\");\n const textLength = bodyText.trim().length;\n\n const elementCount = await page\n .locator(\n \"body h1, body h2, body p, body main, body div, body section, body nav, body header\"\n )\n .count();\n\n const passed = textLength > 0 && elementCount > 0;\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed,\n severity: passed ? \"pass\" : \"fail\",\n message: passed\n ? `${elementCount} elements visible`\n : `Content check failed (text: ${textLength} chars, elements: ${elementCount})`,\n details: { bodyVisible: true, textLength, elementCount },\n };\n },\n};\n","import AxeBuilder from \"@axe-core/playwright\";\nimport path from \"path\";\nimport type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\nimport { sanitize } from \"../utils/sanitize.js\";\nimport { writeJson } from \"../utils/fs.js\";\n\nexport const AccessibilityAudit: Audit = {\n name: \"accessibility\",\n description: \"WCAG accessibility audit via axe-core\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const results = await new AxeBuilder({ page: ctx.page })\n .withTags(ctx.config.wcagTags)\n .analyze();\n\n const violations = results.violations;\n\n if (violations.length > 0) {\n const summary = violations.map((v) => ({\n rule: v.id,\n impact: v.impact,\n description: v.description,\n helpUrl: v.helpUrl,\n elements: v.nodes.length,\n }));\n\n const pageDir = path.join(\n ctx.runDir,\n \"screenshots\",\n sanitize(ctx.pageEntry.name)\n );\n writeJson(path.join(pageDir, \"a11y-violations.json\"), summary);\n }\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: violations.length === 0,\n severity: violations.length === 0 ? \"pass\" : \"warning\",\n message:\n violations.length === 0\n ? \"0 violations\"\n : `${violations.length} violation(s)`,\n details: {\n violationCount: violations.length,\n violations: violations.map((v) => ({\n rule: v.id,\n impact: v.impact,\n description: v.description,\n elements: v.nodes.length,\n })),\n },\n };\n },\n};\n","export function sanitize(name: string): string {\n return name.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n}\n","import path from \"path\";\nimport type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\nimport { sanitize } from \"../utils/sanitize.js\";\nimport { writeJson, ensureDir } from \"../utils/fs.js\";\n\nexport const LighthouseAudit: Audit = {\n name: \"lighthouse\",\n description:\n \"Lighthouse performance, accessibility, best practices, and SEO audit\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n let lighthouse: any;\n let chromeLauncher: any;\n\n try {\n lighthouse = await import(\"lighthouse\");\n chromeLauncher = await import(\"chrome-launcher\");\n } catch {\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: false,\n severity: \"skip\",\n message:\n 'Lighthouse not installed. Run: npm install lighthouse chrome-launcher',\n };\n }\n\n const chrome = await chromeLauncher.launch({\n chromeFlags: [\"--headless\", \"--no-sandbox\"],\n });\n\n const url = `${ctx.config.baseURL}${ctx.pageEntry.path}`;\n const thresholds = ctx.config.lighthouseThresholds;\n\n try {\n const result = await lighthouse.default(url, {\n port: chrome.port,\n output: \"json\",\n logLevel: \"error\",\n onlyCategories: [\n \"performance\",\n \"accessibility\",\n \"best-practices\",\n \"seo\",\n ],\n });\n\n await chrome.kill();\n\n if (!result?.lhr) {\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: false,\n severity: \"fail\",\n message: \"Lighthouse failed to produce results\",\n };\n }\n\n const scores = {\n performance: Math.round(\n (result.lhr.categories.performance?.score ?? 0) * 100\n ),\n accessibility: Math.round(\n (result.lhr.categories.accessibility?.score ?? 0) * 100\n ),\n bestPractices: Math.round(\n (result.lhr.categories[\"best-practices\"]?.score ?? 0) * 100\n ),\n seo: Math.round((result.lhr.categories.seo?.score ?? 0) * 100),\n };\n\n const failures: string[] = [];\n if (thresholds.performance && scores.performance < thresholds.performance)\n failures.push(\n `Performance: ${scores.performance} < ${thresholds.performance}`\n );\n if (\n thresholds.accessibility &&\n scores.accessibility < thresholds.accessibility\n )\n failures.push(\n `Accessibility: ${scores.accessibility} < ${thresholds.accessibility}`\n );\n if (\n thresholds.bestPractices &&\n scores.bestPractices < thresholds.bestPractices\n )\n failures.push(\n `Best Practices: ${scores.bestPractices} < ${thresholds.bestPractices}`\n );\n if (thresholds.seo && scores.seo < thresholds.seo)\n failures.push(`SEO: ${scores.seo} < ${thresholds.seo}`);\n\n const pageDir = path.join(\n ctx.runDir,\n \"screenshots\",\n sanitize(ctx.pageEntry.name)\n );\n ensureDir(pageDir);\n writeJson(path.join(pageDir, \"lighthouse-report.json\"), result.lhr);\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: failures.length === 0,\n severity: failures.length > 0 ? \"fail\" : \"pass\",\n message:\n failures.length > 0\n ? `Failed: ${failures.join(\"; \")}`\n : `perf=${scores.performance} a11y=${scores.accessibility} bp=${scores.bestPractices} seo=${scores.seo}`,\n details: { scores, thresholds, failures },\n };\n } catch (err) {\n await chrome.kill().catch(() => {});\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: false,\n severity: \"fail\",\n message: `Lighthouse error: ${(err as Error).message}`,\n };\n }\n },\n};\n","import type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport const BrokenLinksAudit: Audit = {\n name: \"brokenLinks\",\n description: \"Find broken links (4xx/5xx) on the page\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const links: string[] = await ctx.page.$$eval(\"a[href]\", (anchors) =>\n anchors\n .map((a) => a.getAttribute(\"href\"))\n .filter((href): href is string => !!href)\n );\n\n const baseOrigin = new URL(ctx.config.baseURL).origin;\n const uniqueLinks = [\n ...new Set(\n links\n .map((href) => {\n try {\n return new URL(href, ctx.config.baseURL).href;\n } catch {\n return null;\n }\n })\n .filter(\n (url): url is string =>\n !!url &&\n (url.startsWith(\"http://\") || url.startsWith(\"https://\"))\n )\n ),\n ];\n\n const broken: Array<{ url: string; status: number }> = [];\n\n for (const url of uniqueLinks) {\n try {\n const response = await ctx.page.request.head(url, { timeout: 10000 });\n if (response.status() >= 400) {\n broken.push({ url, status: response.status() });\n }\n } catch {\n broken.push({ url, status: 0 });\n }\n }\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: broken.length === 0,\n severity: broken.length > 0 ? \"warning\" : \"pass\",\n message:\n broken.length === 0\n ? `All ${uniqueLinks.length} links valid`\n : `${broken.length} broken link(s) of ${uniqueLinks.length}`,\n details: { totalLinks: uniqueLinks.length, broken },\n };\n },\n};\n","import type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport const ConsoleErrorsAudit: Audit = {\n name: \"consoleErrors\",\n description: \"Capture browser console errors and warnings\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const messages = ctx.consoleMessages;\n\n const errors = messages.filter((m) => m.type === \"error\");\n const warnings = messages.filter((m) => m.type === \"warning\");\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: errors.length === 0,\n severity:\n errors.length > 0 ? \"fail\" : warnings.length > 0 ? \"warning\" : \"pass\",\n message:\n errors.length === 0 && warnings.length === 0\n ? \"0 errors\"\n : `${errors.length} error(s), ${warnings.length} warning(s)`,\n details: {\n errors: errors.map((e) => e.text),\n warnings: warnings.map((w) => w.text),\n },\n };\n },\n};\n","import type { Page, BrowserContext, Response } from \"playwright\";\nimport type { PageEntry, WebguardConfig } from \"../config/schema.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport interface AuditContext {\n page: Page;\n browserContext: BrowserContext;\n pageEntry: PageEntry;\n config: WebguardConfig;\n runDir: string;\n navigationResponse: Response | null;\n consoleMessages: Array<{ type: string; text: string }>;\n}\n\nexport interface Audit {\n name: string;\n description: string;\n run(ctx: AuditContext): Promise<AuditResult>;\n}\n\nimport { HttpStatusAudit } from \"./http-status.js\";\nimport { ContentVisibilityAudit } from \"./content-visibility.js\";\nimport { AccessibilityAudit } from \"./accessibility.js\";\nimport { LighthouseAudit } from \"./lighthouse.js\";\nimport { BrokenLinksAudit } from \"./broken-links.js\";\nimport { ConsoleErrorsAudit } from \"./console-errors.js\";\n\nconst BUILTIN_AUDITS: Record<string, Audit> = {\n httpStatus: HttpStatusAudit,\n contentVisibility: ContentVisibilityAudit,\n accessibility: AccessibilityAudit,\n lighthouse: LighthouseAudit,\n brokenLinks: BrokenLinksAudit,\n consoleErrors: ConsoleErrorsAudit,\n};\n\nexport function getEnabledAudits(\n auditsConfig: Record<string, boolean>,\n pluginAudits: Audit[] = [],\n customAudits: Audit[] = []\n): Audit[] {\n const allAudits: Record<string, Audit> = { ...BUILTIN_AUDITS };\n\n // Register plugin-provided audits\n for (const audit of [...pluginAudits, ...customAudits]) {\n allAudits[audit.name] = audit;\n }\n\n const enabled: Audit[] = [];\n for (const [name, audit] of Object.entries(allAudits)) {\n // Custom/plugin audits default to enabled unless explicitly disabled\n const isEnabled = auditsConfig[name] ?? true;\n if (isEnabled) {\n enabled.push(audit);\n }\n }\n return enabled;\n}\n\nexport function getAuditByName(name: string): Audit | undefined {\n return BUILTIN_AUDITS[name];\n}\n","import path from \"path\";\nimport type { BrowserContext } from \"playwright\";\nimport type { PageEntry, WebguardConfig } from \"../config/schema.js\";\nimport type { AuditResult, PageResult } from \"../types/index.js\";\nimport type { Audit, AuditContext } from \"../audits/index.js\";\nimport type { PluginRegistry } from \"../plugins/registry.js\";\nimport { navigateWithRetry } from \"./retry.js\";\nimport { sanitize } from \"../utils/sanitize.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport async function runPageAudits(\n pageEntry: PageEntry,\n config: WebguardConfig,\n browserContext: BrowserContext,\n audits: Audit[],\n runDir: string,\n registry?: PluginRegistry\n): Promise<PageResult> {\n const start = Date.now();\n const url = `${config.baseURL}${pageEntry.path}`;\n const page = await browserContext.newPage();\n\n // beforePage hook\n if (registry) {\n await registry.runHook(\"beforePage\", { config, pageEntry, page });\n }\n\n // Attach console listener before navigation\n const consoleMessages: Array<{ type: string; text: string }> = [];\n page.on(\"console\", (msg) => {\n consoleMessages.push({ type: msg.type(), text: msg.text() });\n });\n\n // Navigate with retry\n let navigationResponse = null;\n try {\n navigationResponse = await navigateWithRetry(\n page,\n url,\n config.retry,\n \"domcontentloaded\"\n );\n } catch (err) {\n log.error(`Failed to navigate to ${url}: ${(err as Error).message}`);\n }\n\n // Build audit context\n const ctx: AuditContext = {\n page,\n browserContext,\n pageEntry,\n config,\n runDir,\n navigationResponse,\n consoleMessages,\n };\n\n // Filter out skipped audits for this page\n const pageAudits = audits.filter(\n (a) => !pageEntry.skipAudits?.includes(a.name)\n );\n\n // Run each audit\n const auditResults: AuditResult[] = [];\n for (const audit of pageAudits) {\n // beforeAudit hook\n if (registry) {\n await registry.runHook(\"beforeAudit\", { audit, auditContext: ctx });\n }\n\n const auditStart = Date.now();\n let result: AuditResult;\n try {\n result = await audit.run(ctx);\n result.duration = Date.now() - auditStart;\n } catch (err) {\n result = {\n audit: audit.name,\n page: pageEntry.name,\n passed: false,\n severity: \"fail\",\n message: `Audit error: ${(err as Error).message}`,\n duration: Date.now() - auditStart,\n };\n }\n auditResults.push(result);\n\n // afterAudit hook\n if (registry) {\n await registry.runHook(\"afterAudit\", { audit, result });\n }\n }\n\n // Capture screenshot\n let screenshotPath: string | undefined;\n if (config.output.screenshots) {\n const anyFailed = auditResults.some((r) => !r.passed);\n if (!config.output.screenshotOnFailOnly || anyFailed) {\n try {\n const pageDir = path.join(runDir, \"screenshots\", sanitize(pageEntry.name));\n ensureDir(pageDir);\n const status = anyFailed ? \"fail\" : \"pass\";\n screenshotPath = path.join(pageDir, `page-${status}.png`);\n await page.screenshot({ path: screenshotPath, fullPage: true });\n } catch {\n // Screenshot failed, not critical\n }\n }\n }\n\n const pageResult: PageResult = {\n page: pageEntry.name,\n path: pageEntry.path,\n url,\n audits: auditResults,\n screenshotPath,\n duration: Date.now() - start,\n };\n\n // afterPage hook\n if (registry) {\n await registry.runHook(\"afterPage\", { config, pageEntry, pageResult });\n }\n\n await page.close();\n\n return pageResult;\n}\n","export function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { Page, Response } from \"playwright\";\nimport { sleep } from \"../utils/sleep.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport interface RetryConfig {\n maxRetries: number;\n delayMs: number;\n}\n\nexport async function navigateWithRetry(\n page: Page,\n url: string,\n retry: RetryConfig,\n waitUntil: \"domcontentloaded\" | \"networkidle\" | \"load\" = \"domcontentloaded\"\n): Promise<Response | null> {\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= retry.maxRetries; attempt++) {\n try {\n const response = await page.goto(url, {\n waitUntil,\n timeout: 30_000,\n });\n\n if (response && response.ok()) {\n return response;\n }\n\n if (attempt < retry.maxRetries) {\n log.warn(\n `Attempt ${attempt}/${retry.maxRetries} for ${url} returned ${response?.status()}. Retrying in ${retry.delayMs / 1000}s...`\n );\n await sleep(retry.delayMs);\n }\n\n if (attempt === retry.maxRetries) return response;\n } catch (error) {\n lastError = error as Error;\n if (attempt < retry.maxRetries) {\n log.warn(\n `Attempt ${attempt}/${retry.maxRetries} for ${url} failed. Retrying in ${retry.delayMs / 1000}s...`\n );\n await sleep(retry.delayMs);\n }\n }\n }\n\n throw (\n lastError ??\n new Error(`Failed to load ${url} after ${retry.maxRetries} attempts`)\n );\n}\n","import type { BrowserContext } from \"playwright\";\nimport type { PageEntry, WebguardConfig } from \"../config/schema.js\";\nimport type { PageResult } from \"../types/index.js\";\nimport type { Audit } from \"../audits/index.js\";\nimport type { PluginRegistry } from \"../plugins/registry.js\";\nimport { runPageAudits } from \"./page-runner.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport async function runPagesParallel(\n pages: PageEntry[],\n config: WebguardConfig,\n browserContext: BrowserContext,\n audits: Audit[],\n runDir: string,\n registry: PluginRegistry,\n concurrency: number,\n failFast: boolean\n): Promise<PageResult[]> {\n const results: PageResult[] = new Array(pages.length);\n let currentIndex = 0;\n let aborted = false;\n\n async function worker(): Promise<void> {\n while (!aborted) {\n const index = currentIndex++;\n if (index >= pages.length) break;\n\n const pageEntry = pages[index];\n log.plain(` [${index + 1}/${pages.length}] ${pageEntry.name} (${pageEntry.path})`);\n\n const result = await runPageAudits(\n pageEntry,\n config,\n browserContext,\n audits,\n runDir,\n registry\n );\n results[index] = result;\n\n // Print inline results\n for (const audit of result.audits) {\n const icon = audit.passed\n ? \" \\u2713\"\n : audit.severity === \"warning\"\n ? \" \\u26A0\"\n : \" \\u2717\";\n const duration = audit.duration ? `${audit.duration}ms` : \"\";\n log.plain(\n `${icon} ${audit.audit.padEnd(20)} ${audit.message.padEnd(30)} ${duration}`\n );\n }\n log.plain(\"\");\n\n if (failFast && result.audits.some((a) => a.severity === \"fail\")) {\n log.warn(\"Fail fast enabled — stopping after first failure\");\n aborted = true;\n }\n }\n }\n\n const workerCount = Math.min(concurrency, pages.length);\n const workers = Array.from({ length: workerCount }, () => worker());\n\n await Promise.all(workers);\n\n return results.filter(Boolean);\n}\n","import path from \"path\";\nimport { ensureDir, cleanDir } from \"../utils/fs.js\";\n\nexport interface RunDirs {\n runDir: string;\n screenshotsDir: string;\n}\n\nexport function setupRunDirectory(outputBaseDir: string): RunDirs {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const runDir = path.join(outputBaseDir, `run-${timestamp}`);\n const screenshotsDir = path.join(runDir, \"screenshots\");\n\n // Clean previous runs\n cleanDir(outputBaseDir);\n\n // Create fresh directories\n ensureDir(screenshotsDir);\n\n return { runDir, screenshotsDir };\n}\n","import path from \"path\";\nimport type { RunResult } from \"../types/index.js\";\nimport { writeJson } from \"../utils/fs.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport function reportJson(result: RunResult, runDir: string): void {\n const filePath = path.join(runDir, \"results.json\");\n writeJson(filePath, result);\n log.dim(` JSON report: ${filePath}`);\n}\n","import chalk from \"chalk\";\nimport type { RunResult } from \"../types/index.js\";\n\nexport function reportTerminal(result: RunResult): void {\n const { summary } = result;\n\n console.log(\"\");\n console.log(chalk.bold(\"─\".repeat(60)));\n console.log(chalk.bold(\" Summary\"));\n console.log(chalk.bold(\"─\".repeat(60)));\n console.log(\"\");\n\n console.log(` Total audits: ${summary.totalAudits}`);\n console.log(\n ` ${chalk.green(\"✓ Passed:\")} ${summary.passed}`\n );\n\n if (summary.failed > 0) {\n console.log(\n ` ${chalk.red(\"✗ Failed:\")} ${summary.failed}`\n );\n }\n if (summary.warnings > 0) {\n console.log(\n ` ${chalk.yellow(\"⚠ Warnings:\")} ${summary.warnings}`\n );\n }\n if (summary.skipped > 0) {\n console.log(\n ` ${chalk.dim(\"○ Skipped:\")} ${summary.skipped}`\n );\n }\n\n console.log(\n ` Duration: ${(summary.duration / 1000).toFixed(1)}s`\n );\n console.log(\"\");\n\n // Show failed audits detail\n const failedAudits = result.pages.flatMap((p) =>\n p.audits.filter((a) => a.severity === \"fail\")\n );\n\n if (failedAudits.length > 0) {\n console.log(chalk.red.bold(\" Failed Audits:\"));\n for (const audit of failedAudits) {\n console.log(\n chalk.red(` ✗ ${audit.page} → ${audit.audit}: ${audit.message}`)\n );\n }\n console.log(\"\");\n }\n\n // Exit status hint\n if (summary.failed > 0) {\n console.log(\n chalk.red.bold(` Result: FAIL (${summary.failed} failure(s))`)\n );\n } else if (summary.warnings > 0) {\n console.log(\n chalk.yellow.bold(` Result: PASS with ${summary.warnings} warning(s)`)\n );\n } else {\n console.log(chalk.green.bold(\" Result: PASS\"));\n }\n\n console.log(\"\");\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport type { RunResult, PageResult, AuditResult } from \"../types/index.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport { log } from \"../utils/logger.js\";\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction severityIcon(severity: string): string {\n switch (severity) {\n case \"pass\":\n return \"&#x2713;\";\n case \"fail\":\n return \"&#x2717;\";\n case \"warning\":\n return \"&#x26A0;\";\n case \"skip\":\n return \"&#x25CB;\";\n default:\n return \"?\";\n }\n}\n\nfunction severityClass(severity: string): string {\n return `severity-${severity}`;\n}\n\nfunction renderAuditRow(audit: AuditResult): string {\n return `\n <tr class=\"${severityClass(audit.severity)}\">\n <td class=\"icon\">${severityIcon(audit.severity)}</td>\n <td>${escapeHtml(audit.audit)}</td>\n <td>${escapeHtml(audit.message)}</td>\n <td class=\"duration\">${audit.duration ? `${audit.duration}ms` : \"—\"}</td>\n </tr>`;\n}\n\nfunction renderPageSection(page: PageResult): string {\n const failCount = page.audits.filter((a) => a.severity === \"fail\").length;\n const status = failCount > 0 ? \"fail\" : \"pass\";\n\n return `\n <div class=\"page-section\">\n <h2 class=\"page-header ${status}\">\n <span class=\"page-name\">${escapeHtml(page.page)}</span>\n <span class=\"page-path\">${escapeHtml(page.path)}</span>\n <span class=\"page-duration\">${(page.duration / 1000).toFixed(1)}s</span>\n </h2>\n <table class=\"audit-table\">\n <thead>\n <tr>\n <th class=\"icon-col\"></th>\n <th>Audit</th>\n <th>Result</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n ${page.audits.map(renderAuditRow).join(\"\")}\n </tbody>\n </table>\n </div>`;\n}\n\nfunction buildHtml(result: RunResult): string {\n const { summary } = result;\n const overallStatus =\n summary.failed > 0 ? \"FAIL\" : summary.warnings > 0 ? \"PASS (with warnings)\" : \"PASS\";\n const statusClass = summary.failed > 0 ? \"fail\" : summary.warnings > 0 ? \"warning\" : \"pass\";\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Webguardx Report — ${escapeHtml(result.config.baseURL)}</title>\n <style>\n :root {\n --pass: #22c55e;\n --fail: #ef4444;\n --warning: #f59e0b;\n --skip: #94a3b8;\n --bg: #0f172a;\n --surface: #1e293b;\n --text: #e2e8f0;\n --text-dim: #94a3b8;\n --border: #334155;\n }\n\n * { box-sizing: border-box; margin: 0; padding: 0; }\n\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: var(--bg);\n color: var(--text);\n line-height: 1.6;\n padding: 2rem;\n }\n\n .container { max-width: 900px; margin: 0 auto; }\n\n header {\n text-align: center;\n margin-bottom: 2rem;\n padding-bottom: 1.5rem;\n border-bottom: 1px solid var(--border);\n }\n\n header h1 {\n font-size: 1.75rem;\n font-weight: 700;\n margin-bottom: 0.5rem;\n }\n\n header .meta {\n color: var(--text-dim);\n font-size: 0.875rem;\n }\n\n .summary-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 1rem;\n margin-bottom: 2rem;\n }\n\n .summary-card {\n background: var(--surface);\n border-radius: 8px;\n padding: 1rem;\n text-align: center;\n border: 1px solid var(--border);\n }\n\n .summary-card .value {\n font-size: 2rem;\n font-weight: 700;\n }\n\n .summary-card .label {\n font-size: 0.75rem;\n color: var(--text-dim);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n\n .summary-card.pass .value { color: var(--pass); }\n .summary-card.fail .value { color: var(--fail); }\n .summary-card.warning .value { color: var(--warning); }\n .summary-card.skip .value { color: var(--skip); }\n\n .overall-status {\n text-align: center;\n font-size: 1.25rem;\n font-weight: 700;\n padding: 0.75rem;\n border-radius: 8px;\n margin-bottom: 2rem;\n }\n\n .overall-status.pass { background: rgba(34,197,94,0.15); color: var(--pass); }\n .overall-status.fail { background: rgba(239,68,68,0.15); color: var(--fail); }\n .overall-status.warning { background: rgba(245,158,11,0.15); color: var(--warning); }\n\n .page-section {\n background: var(--surface);\n border-radius: 8px;\n margin-bottom: 1.5rem;\n border: 1px solid var(--border);\n overflow: hidden;\n }\n\n .page-header {\n padding: 1rem 1.25rem;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n border-bottom: 1px solid var(--border);\n }\n\n .page-header.fail { border-left: 4px solid var(--fail); }\n .page-header.pass { border-left: 4px solid var(--pass); }\n\n .page-name { font-weight: 600; }\n .page-path { color: var(--text-dim); font-size: 0.875rem; }\n .page-duration { margin-left: auto; color: var(--text-dim); font-size: 0.875rem; }\n\n .audit-table {\n width: 100%;\n border-collapse: collapse;\n }\n\n .audit-table th {\n text-align: left;\n padding: 0.5rem 1rem;\n font-size: 0.75rem;\n text-transform: uppercase;\n color: var(--text-dim);\n border-bottom: 1px solid var(--border);\n }\n\n .audit-table td {\n padding: 0.6rem 1rem;\n border-bottom: 1px solid var(--border);\n }\n\n .audit-table tr:last-child td { border-bottom: none; }\n\n .icon-col { width: 40px; }\n .icon { text-align: center; font-size: 1.1rem; }\n .duration { color: var(--text-dim); font-size: 0.875rem; }\n\n .severity-pass .icon { color: var(--pass); }\n .severity-fail .icon { color: var(--fail); }\n .severity-warning .icon { color: var(--warning); }\n .severity-skip .icon { color: var(--skip); }\n\n footer {\n text-align: center;\n margin-top: 2rem;\n padding-top: 1rem;\n border-top: 1px solid var(--border);\n color: var(--text-dim);\n font-size: 0.75rem;\n }\n\n footer a { color: var(--text-dim); }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <header>\n <h1>Webguardx Report</h1>\n <div class=\"meta\">\n ${escapeHtml(result.config.baseURL)} &bull;\n ${escapeHtml(result.timestamp)} &bull;\n ${result.config.auditsEnabled.join(\", \")}\n </div>\n </header>\n\n <div class=\"overall-status ${statusClass}\">${overallStatus}</div>\n\n <div class=\"summary-grid\">\n <div class=\"summary-card\">\n <div class=\"value\">${summary.totalAudits}</div>\n <div class=\"label\">Total</div>\n </div>\n <div class=\"summary-card pass\">\n <div class=\"value\">${summary.passed}</div>\n <div class=\"label\">Passed</div>\n </div>\n <div class=\"summary-card fail\">\n <div class=\"value\">${summary.failed}</div>\n <div class=\"label\">Failed</div>\n </div>\n <div class=\"summary-card warning\">\n <div class=\"value\">${summary.warnings}</div>\n <div class=\"label\">Warnings</div>\n </div>\n <div class=\"summary-card skip\">\n <div class=\"value\">${summary.skipped}</div>\n <div class=\"label\">Skipped</div>\n </div>\n <div class=\"summary-card\">\n <div class=\"value\">${(summary.duration / 1000).toFixed(1)}s</div>\n <div class=\"label\">Duration</div>\n </div>\n </div>\n\n ${result.pages.map(renderPageSection).join(\"\")}\n\n <footer>\n Generated by <a href=\"https://github.com/user/webguardx\">webguardx</a>\n </footer>\n </div>\n</body>\n</html>`;\n}\n\nexport function reportHtml(result: RunResult, runDir: string): void {\n const filePath = path.join(runDir, \"report.html\");\n ensureDir(runDir);\n fs.writeFileSync(filePath, buildHtml(result), \"utf-8\");\n log.dim(` HTML report: ${filePath}`);\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport type { RunResult, PageResult, AuditResult } from \"../types/index.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport { log } from \"../utils/logger.js\";\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n}\n\nfunction buildTestCase(audit: AuditResult): string {\n const name = escapeXml(`${audit.page} - ${audit.audit}`);\n const time = audit.duration ? (audit.duration / 1000).toFixed(3) : \"0.000\";\n\n if (audit.severity === \"pass\") {\n return ` <testcase name=\"${name}\" classname=\"${escapeXml(audit.page)}\" time=\"${time}\" />\\n`;\n }\n\n if (audit.severity === \"skip\") {\n return ` <testcase name=\"${name}\" classname=\"${escapeXml(audit.page)}\" time=\"${time}\">\\n <skipped message=\"${escapeXml(audit.message)}\" />\\n </testcase>\\n`;\n }\n\n const tag = audit.severity === \"fail\" ? \"failure\" : \"failure\";\n return ` <testcase name=\"${name}\" classname=\"${escapeXml(audit.page)}\" time=\"${time}\">\\n <${tag} message=\"${escapeXml(audit.message)}\" type=\"${escapeXml(audit.severity)}\">${escapeXml(audit.message)}</${tag}>\\n </testcase>\\n`;\n}\n\nfunction buildTestSuite(page: PageResult, index: number): string {\n const tests = page.audits.length;\n const failures = page.audits.filter((a) => a.severity === \"fail\").length;\n const skipped = page.audits.filter((a) => a.severity === \"skip\").length;\n const time = (page.duration / 1000).toFixed(3);\n\n let xml = ` <testsuite name=\"${escapeXml(page.page)}\" tests=\"${tests}\" failures=\"${failures}\" skipped=\"${skipped}\" time=\"${time}\" id=\"${index}\">\\n`;\n for (const audit of page.audits) {\n xml += buildTestCase(audit);\n }\n xml += ` </testsuite>\\n`;\n return xml;\n}\n\nexport function reportJunit(result: RunResult, runDir: string): void {\n const { summary } = result;\n const time = (summary.duration / 1000).toFixed(3);\n\n let xml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n`;\n xml += `<testsuites name=\"webguardx\" tests=\"${summary.totalAudits}\" failures=\"${summary.failed}\" skipped=\"${summary.skipped}\" time=\"${time}\">\\n`;\n\n result.pages.forEach((page, i) => {\n xml += buildTestSuite(page, i);\n });\n\n xml += `</testsuites>\\n`;\n\n const filePath = path.join(runDir, \"results.xml\");\n ensureDir(runDir);\n fs.writeFileSync(filePath, xml, \"utf-8\");\n log.dim(` JUnit report: ${filePath}`);\n}\n","import type { RunResult } from \"../types/index.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport function reportScreenshots(result: RunResult): void {\n const captured = result.pages.filter((p) => p.screenshotPath);\n if (captured.length > 0) {\n log.dim(` Screenshots: ${captured.length} page(s) captured`);\n }\n}\n","import type { RunResult } from \"../types/index.js\";\nimport type { WebguardConfig } from \"../config/schema.js\";\nimport type { Reporter } from \"../plugins/types.js\";\nimport { reportJson } from \"./json.js\";\nimport { reportTerminal } from \"./terminal.js\";\nimport { reportHtml } from \"./html.js\";\nimport { reportJunit } from \"./junit.js\";\nimport { reportScreenshots } from \"./screenshot.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport async function runReporters(\n result: RunResult,\n config: WebguardConfig,\n runDir: string,\n pluginReporters: Reporter[] = []\n): Promise<void> {\n const formats = config.output.formats;\n\n if (formats.includes(\"terminal\")) {\n reportTerminal(result);\n }\n\n log.dim(\" Output:\");\n\n if (formats.includes(\"json\")) {\n reportJson(result, runDir);\n }\n\n if (formats.includes(\"html\")) {\n reportHtml(result, runDir);\n }\n\n if (formats.includes(\"junit\")) {\n reportJunit(result, runDir);\n }\n\n if (config.output.screenshots) {\n reportScreenshots(result);\n }\n\n // Plugin reporters\n for (const reporter of pluginReporters) {\n try {\n await reporter.run(result, runDir, config);\n log.dim(` ${reporter.name}: done`);\n } catch (err) {\n log.warn(`Reporter '${reporter.name}' failed: ${(err as Error).message}`);\n }\n }\n\n log.plain(\"\");\n}\n","import type { WebguardPlugin, Reporter, LifecycleHooks } from \"./types.js\";\nimport type { Audit } from \"../audits/index.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport class PluginRegistry {\n private plugins: WebguardPlugin[] = [];\n\n register(plugin: WebguardPlugin): void {\n this.plugins.push(plugin);\n }\n\n getPluginAudits(): Audit[] {\n return this.plugins.flatMap((p) => p.audits ?? []);\n }\n\n getPluginReporters(): Reporter[] {\n return this.plugins.flatMap((p) => p.reporters ?? []);\n }\n\n async runHook<K extends keyof LifecycleHooks>(\n hookName: K,\n ctx: Parameters<LifecycleHooks[K]>[0]\n ): Promise<void> {\n for (const plugin of this.plugins) {\n const hook = plugin.hooks?.[hookName];\n if (hook) {\n try {\n await (hook as (ctx: any) => Promise<void> | void)(ctx);\n } catch (err) {\n log.warn(\n `Plugin '${plugin.name}' hook '${hookName}' failed: ${(err as Error).message}`\n );\n }\n }\n }\n }\n}\n","import type { WebguardPlugin } from \"./types.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport async function loadPlugins(\n pluginEntries: Array<WebguardPlugin | string>\n): Promise<WebguardPlugin[]> {\n const plugins: WebguardPlugin[] = [];\n\n for (const entry of pluginEntries) {\n if (typeof entry === \"string\") {\n try {\n const { createJiti } = await import(\"jiti\");\n const jiti = createJiti(import.meta.url);\n const mod = await jiti.import(entry);\n const plugin = (mod as any).default ?? mod;\n plugins.push(plugin as WebguardPlugin);\n log.dim(` Loaded plugin: ${plugin.name ?? entry}`);\n } catch (err) {\n log.warn(`Failed to load plugin '${entry}': ${(err as Error).message}`);\n }\n } else {\n plugins.push(entry);\n }\n }\n\n return plugins;\n}\n","import type { NotificationChannel } from \"./types.js\";\n\nexport interface WebhookOptions {\n method?: \"POST\" | \"PUT\";\n headers?: Record<string, string>;\n onlyOnFailure?: boolean;\n}\n\nexport function createWebhookNotifier(\n url: string,\n options: WebhookOptions = {}\n): NotificationChannel {\n return {\n name: `webhook:${new URL(url).hostname}`,\n async send(result, config) {\n if (options.onlyOnFailure && result.summary.failed === 0) return;\n\n await fetch(url, {\n method: options.method ?? \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n body: JSON.stringify({\n tool: \"webguardx\",\n status: result.summary.failed > 0 ? \"fail\" : \"pass\",\n baseURL: config.baseURL,\n timestamp: result.timestamp,\n summary: result.summary,\n }),\n });\n },\n };\n}\n","import type { NotificationChannel } from \"./types.js\";\n\nexport interface SlackOptions {\n channel?: string;\n onlyOnFailure?: boolean;\n}\n\nexport function createSlackNotifier(\n webhookUrl: string,\n options: SlackOptions = {}\n): NotificationChannel {\n return {\n name: \"slack\",\n async send(result, config) {\n if (options.onlyOnFailure && result.summary.failed === 0) return;\n\n const color = result.summary.failed > 0 ? \"#ef4444\" : \"#22c55e\";\n const status = result.summary.failed > 0 ? \"FAIL\" : \"PASS\";\n const { summary } = result;\n\n await fetch(webhookUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n channel: options.channel,\n attachments: [\n {\n color,\n title: `Webguardx: ${status}`,\n title_link: config.baseURL,\n text: `${summary.passed} passed, ${summary.failed} failed, ${summary.warnings} warnings`,\n fields: [\n { title: \"Base URL\", value: config.baseURL, short: true },\n { title: \"Pages\", value: `${config.pages.length}`, short: true },\n { title: \"Duration\", value: `${(summary.duration / 1000).toFixed(1)}s`, short: true },\n ],\n footer: \"webguardx\",\n ts: Math.floor(Date.now() / 1000),\n },\n ],\n }),\n });\n },\n };\n}\n","import type { RunResult } from \"../types/index.js\";\nimport type { WebguardConfig } from \"../config/schema.js\";\nimport type { NotificationChannel } from \"./types.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport type { NotificationChannel } from \"./types.js\";\nexport { createWebhookNotifier } from \"./webhook.js\";\nexport type { WebhookOptions } from \"./webhook.js\";\nexport { createSlackNotifier } from \"./slack.js\";\nexport type { SlackOptions } from \"./slack.js\";\n\nexport async function sendNotifications(\n channels: NotificationChannel[],\n result: RunResult,\n config: WebguardConfig\n): Promise<void> {\n for (const channel of channels) {\n try {\n await channel.send(result, config);\n log.dim(` Notification sent: ${channel.name}`);\n } catch (err) {\n log.warn(\n `Notification '${channel.name}' failed: ${(err as Error).message}`\n );\n }\n }\n}\n","import path from \"path\";\nimport fs from \"fs\";\nimport type { RunResult } from \"../types/index.js\";\nimport { log } from \"../utils/logger.js\";\n\nconst BASELINE_FILENAME = \"baseline.json\";\n\nexport function saveBaseline(result: RunResult, outputDir: string): void {\n const baselinePath = path.join(outputDir, BASELINE_FILENAME);\n fs.writeFileSync(baselinePath, JSON.stringify(result, null, 2));\n log.success(`Baseline saved: ${baselinePath}`);\n}\n\nexport function loadBaseline(outputDir: string): RunResult | null {\n const baselinePath = path.join(outputDir, BASELINE_FILENAME);\n if (!fs.existsSync(baselinePath)) return null;\n try {\n return JSON.parse(fs.readFileSync(baselinePath, \"utf-8\"));\n } catch {\n log.warn(\"Failed to parse baseline file\");\n return null;\n }\n}\n\nexport function baselineExists(outputDir: string): boolean {\n return fs.existsSync(path.join(outputDir, BASELINE_FILENAME));\n}\n","import type { RunResult } from \"../types/index.js\";\nimport type { BaselineComparison, AuditChange } from \"./types.js\";\n\nexport function compareRuns(\n baseline: RunResult,\n current: RunResult\n): BaselineComparison {\n const changes: AuditChange[] = [];\n\n // Build lookup maps: \"page::audit\" -> { severity, message }\n const baselineMap = new Map<string, { severity: string; message: string }>();\n for (const page of baseline.pages) {\n for (const audit of page.audits) {\n baselineMap.set(`${page.page}::${audit.audit}`, {\n severity: audit.severity,\n message: audit.message,\n });\n }\n }\n\n const currentMap = new Map<string, { severity: string; message: string }>();\n for (const page of current.pages) {\n for (const audit of page.audits) {\n const key = `${page.page}::${audit.audit}`;\n const entry = { severity: audit.severity, message: audit.message };\n currentMap.set(key, entry);\n\n const prev = baselineMap.get(key);\n if (!prev) {\n changes.push({\n page: page.page,\n audit: audit.audit,\n type: \"new\",\n current: entry,\n });\n } else if (prev.severity !== audit.severity) {\n const type =\n audit.severity === \"pass\" || audit.severity === \"skip\"\n ? \"improvement\"\n : \"regression\";\n changes.push({\n page: page.page,\n audit: audit.audit,\n type,\n baseline: prev,\n current: entry,\n });\n } else {\n changes.push({\n page: page.page,\n audit: audit.audit,\n type: \"unchanged\",\n baseline: prev,\n current: entry,\n });\n }\n }\n }\n\n // Detect removed audits\n for (const [key, val] of baselineMap) {\n if (!currentMap.has(key)) {\n const [page, audit] = key.split(\"::\");\n changes.push({ page, audit, type: \"removed\", baseline: val });\n }\n }\n\n return {\n baselineTimestamp: baseline.timestamp,\n currentTimestamp: current.timestamp,\n changes,\n summary: {\n regressions: changes.filter((c) => c.type === \"regression\").length,\n improvements: changes.filter((c) => c.type === \"improvement\").length,\n unchanged: changes.filter((c) => c.type === \"unchanged\").length,\n newAudits: changes.filter((c) => c.type === \"new\").length,\n removedAudits: changes.filter((c) => c.type === \"removed\").length,\n },\n };\n}\n"],"mappings":"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","names":["chalk","path","fs","import_playwright","import_path","import_fs","import_path","fs","path","fs","path","import_playwright","import_path","path","import_fs","import_path","path","fs","import_fs","import_path","path","fs","import_playwright","import_path","AxeBuilder","path","import_path","path","import_path","path","import_path","path","import_path","path","import_chalk","chalk","import_fs","import_path","path","fs","import_fs","import_path","path","fs","import_path","import_fs","path","fs"]}
1
+ {"version":3,"sources":["../src/index.ts","../node_modules/tsup/assets/cjs_shims.js","../src/config/schema.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/utils/colors.ts","../src/utils/logger.ts","../src/runner/index.ts","../src/auth/strategies/api-login.ts","../src/utils/fs.ts","../src/auth/strategies/form-login.ts","../src/auth/strategies/cookie-inject.ts","../src/auth/strategies/bearer-token.ts","../src/auth/index.ts","../src/audits/http-status.ts","../src/audits/content-visibility.ts","../src/audits/accessibility.ts","../src/utils/sanitize.ts","../src/audits/lighthouse.ts","../src/audits/broken-links.ts","../src/audits/console-errors.ts","../src/audits/index.ts","../src/runner/page-runner.ts","../src/utils/sleep.ts","../src/runner/retry.ts","../src/runner/parallel.ts","../src/runner/setup.ts","../src/reporters/json.ts","../src/reporters/terminal.ts","../src/reporters/html.ts","../src/reporters/junit.ts","../src/reporters/screenshot.ts","../src/reporters/index.ts","../src/plugins/registry.ts","../src/plugins/loader.ts","../src/notifications/webhook.ts","../src/notifications/slack.ts","../src/notifications/index.ts","../src/baseline/storage.ts","../src/baseline/diff.ts"],"sourcesContent":["// Core API\nexport { defineConfig } from \"./config/defaults.js\";\nexport { loadConfig } from \"./config/loader.js\";\nexport { run } from \"./runner/index.js\";\n\n// Types\nexport type { WebguardConfig, PageEntry, AuthConfig } from \"./config/schema.js\";\nexport type { AuditResult, PageResult, RunResult, AuditSeverity } from \"./types/index.js\";\nexport type { RunOptions } from \"./runner/index.js\";\nexport type { Audit, AuditContext } from \"./audits/index.js\";\n\n// Plugin system\nexport type { WebguardPlugin, Reporter, LifecycleHooks } from \"./plugins/types.js\";\nexport { PluginRegistry } from \"./plugins/registry.js\";\nexport { loadPlugins } from \"./plugins/loader.js\";\n\n// Notifications\nexport type { NotificationChannel } from \"./notifications/types.js\";\nexport { createWebhookNotifier } from \"./notifications/webhook.js\";\nexport { createSlackNotifier } from \"./notifications/slack.js\";\nexport { sendNotifications } from \"./notifications/index.js\";\n\n// Baseline\nexport type { BaselineComparison, AuditChange } from \"./baseline/types.js\";\nexport { saveBaseline, loadBaseline, compareRuns } from \"./baseline/index.js\";\n\n// Audits (for custom composition)\nexport { HttpStatusAudit } from \"./audits/http-status.js\";\nexport { ContentVisibilityAudit } from \"./audits/content-visibility.js\";\nexport { AccessibilityAudit } from \"./audits/accessibility.js\";\nexport { LighthouseAudit } from \"./audits/lighthouse.js\";\nexport { BrokenLinksAudit } from \"./audits/broken-links.js\";\nexport { ConsoleErrorsAudit } from \"./audits/console-errors.js\";\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { z } from \"zod\";\n\nconst AuthApiLoginSchema = z.object({\n method: z.literal(\"api-login\"),\n loginUrl: z.string().url(),\n payload: z.record(z.string()),\n headers: z.record(z.string()).optional(),\n});\n\nconst AuthFormLoginSchema = z.object({\n method: z.literal(\"form-login\"),\n loginUrl: z.string().url(),\n fields: z.array(\n z.object({\n selector: z.string(),\n value: z.string(),\n })\n ),\n submitSelector: z.string(),\n waitAfterLogin: z.string().optional(),\n});\n\nconst AuthCookieSchema = z.object({\n method: z.literal(\"cookie\"),\n cookies: z.array(\n z.object({\n name: z.string(),\n value: z.string(),\n domain: z.string(),\n path: z.string().default(\"/\"),\n })\n ),\n});\n\nconst AuthBearerSchema = z.object({\n method: z.literal(\"bearer-token\"),\n token: z.string(),\n});\n\nconst AuthNoneSchema = z.object({\n method: z.literal(\"none\"),\n});\n\nconst AuthSchema = z.discriminatedUnion(\"method\", [\n AuthApiLoginSchema,\n AuthFormLoginSchema,\n AuthCookieSchema,\n AuthBearerSchema,\n AuthNoneSchema,\n]);\n\nconst PageSchema = z.object({\n name: z.string(),\n path: z.string(),\n expectedStatus: z.number().default(200),\n skipAudits: z.array(z.string()).optional(),\n});\n\nconst LighthouseThresholdsSchema = z\n .object({\n performance: z.number().min(0).max(100).default(50),\n accessibility: z.number().min(0).max(100).default(90),\n bestPractices: z.number().min(0).max(100).default(80),\n seo: z.number().min(0).max(100).default(80),\n })\n .partial();\n\nexport const WebguardConfigSchema = z.object({\n baseURL: z.string().url(),\n\n pages: z.array(PageSchema).min(1),\n\n auth: AuthSchema.default({ method: \"none\" }),\n\n // Open record — built-in keys have defaults, custom audit keys are allowed\n audits: z\n .record(z.string(), z.boolean())\n .default({\n httpStatus: true,\n contentVisibility: true,\n accessibility: true,\n lighthouse: false,\n brokenLinks: false,\n consoleErrors: true,\n }),\n\n // Custom audits defined inline in config\n customAudits: z.array(z.any()).default([]),\n\n // Plugins — objects or string paths to npm packages / local files\n plugins: z.array(z.any()).default([]),\n\n wcagTags: z\n .array(z.string())\n .default([\"wcag2a\", \"wcag2aa\", \"wcag21a\", \"wcag21aa\"]),\n\n lighthouseThresholds: LighthouseThresholdsSchema.default({}),\n\n retry: z\n .object({\n maxRetries: z.number().min(1).default(3),\n delayMs: z.number().min(0).default(5000),\n })\n .default({}),\n\n runner: z\n .object({\n concurrency: z.number().min(1).default(1),\n failFast: z.boolean().default(false),\n })\n .default({}),\n\n browser: z\n .object({\n headless: z.boolean().default(true),\n timeout: z.number().default(60000),\n viewport: z\n .object({\n width: z.number().default(1280),\n height: z.number().default(720),\n })\n .default({}),\n })\n .default({}),\n\n output: z\n .object({\n dir: z.string().default(\"./webguard-results\"),\n formats: z\n .array(z.enum([\"terminal\", \"html\", \"json\", \"junit\"]))\n .default([\"terminal\", \"html\", \"json\"]),\n screenshots: z.boolean().default(true),\n screenshotOnFailOnly: z.boolean().default(false),\n })\n .default({}),\n\n baseline: z\n .object({\n enabled: z.boolean().default(false),\n updateOnPass: z.boolean().default(true),\n })\n .default({}),\n\n notifications: z.array(z.any()).default([]),\n});\n\nexport type WebguardConfig = z.infer<typeof WebguardConfigSchema>;\nexport type PageEntry = z.infer<typeof PageSchema>;\nexport type AuthConfig = z.infer<typeof AuthSchema>;\nexport type AuditsConfig = WebguardConfig[\"audits\"];\n","import { z } from \"zod\";\nimport { WebguardConfigSchema, type WebguardConfig } from \"./schema.js\";\n\ntype WebguardConfigInput = z.input<typeof WebguardConfigSchema>;\n\nexport function defineConfig(config: WebguardConfigInput): WebguardConfig {\n return WebguardConfigSchema.parse(config);\n}\n","import path from \"path\";\nimport fs from \"fs\";\nimport { WebguardConfigSchema, type WebguardConfig } from \"./schema.js\";\nimport { log } from \"../utils/logger.js\";\n\nconst CONFIG_NAMES = [\n \"webguard.config.ts\",\n \"webguard.config.js\",\n \"webguard.config.mjs\",\n \"webguard.config.json\",\n];\n\nexport async function loadConfig(\n configPath?: string\n): Promise<WebguardConfig> {\n const resolvedPath = configPath\n ? path.resolve(configPath)\n : findConfigFile();\n\n if (!resolvedPath) {\n throw new Error(\n `No webguard config found. Run \"webguardx init\" to create one, or specify --config <path>.`\n );\n }\n\n log.info(`Loading config from ${path.relative(process.cwd(), resolvedPath)}`);\n\n let rawConfig: unknown;\n\n if (resolvedPath.endsWith(\".json\")) {\n const content = fs.readFileSync(resolvedPath, \"utf-8\");\n rawConfig = JSON.parse(content);\n } else {\n // Use jiti for runtime TypeScript/ESM loading\n const { createJiti } = await import(\"jiti\");\n const jiti = createJiti(import.meta.url);\n const mod = await jiti.import(resolvedPath);\n rawConfig = (mod as any).default ?? mod;\n }\n\n const result = WebguardConfigSchema.safeParse(rawConfig);\n\n if (!result.success) {\n const errors = result.error.issues\n .map((i) => ` - ${i.path.join(\".\")}: ${i.message}`)\n .join(\"\\n\");\n throw new Error(`Invalid webguard config:\\n${errors}`);\n }\n\n return result.data;\n}\n\nfunction findConfigFile(): string | null {\n const cwd = process.cwd();\n for (const name of CONFIG_NAMES) {\n const fullPath = path.join(cwd, name);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n","// Lightweight ANSI color utility — avoids chalk v5 ESM/CJS interop issues\nconst enabled =\n process.env.NO_COLOR === undefined &&\n process.env.FORCE_COLOR !== \"0\" &&\n process.stdout.isTTY !== false;\n\nfunction wrap(open: string, close: string) {\n return enabled ? (s: string) => `${open}${s}${close}` : (s: string) => s;\n}\n\nexport const c = {\n bold: wrap(\"\\x1b[1m\", \"\\x1b[22m\"),\n dim: wrap(\"\\x1b[2m\", \"\\x1b[22m\"),\n red: wrap(\"\\x1b[31m\", \"\\x1b[39m\"),\n green: wrap(\"\\x1b[32m\", \"\\x1b[39m\"),\n yellow: wrap(\"\\x1b[33m\", \"\\x1b[39m\"),\n blue: wrap(\"\\x1b[34m\", \"\\x1b[39m\"),\n cyan: wrap(\"\\x1b[36m\", \"\\x1b[39m\"),\n gray: wrap(\"\\x1b[90m\", \"\\x1b[39m\"),\n bgRed: wrap(\"\\x1b[41m\", \"\\x1b[49m\"),\n bgGreen: wrap(\"\\x1b[42m\", \"\\x1b[49m\"),\n};\n","import { c } from \"./colors.js\";\n\nexport const log = {\n info(msg: string) {\n console.log(c.blue(\"i\"), msg);\n },\n success(msg: string) {\n console.log(c.green(\"✓\"), msg);\n },\n warn(msg: string) {\n console.log(c.yellow(\"⚠\"), msg);\n },\n error(msg: string) {\n console.log(c.red(\"✗\"), msg);\n },\n dim(msg: string) {\n console.log(c.dim(msg));\n },\n plain(msg: string) {\n console.log(msg);\n },\n};\n","import { chromium } from \"playwright\";\nimport type { WebguardConfig } from \"../config/schema.js\";\nimport type { RunResult, PageResult } from \"../types/index.js\";\nimport { authenticate } from \"../auth/index.js\";\nimport { getEnabledAudits } from \"../audits/index.js\";\nimport { runPageAudits } from \"./page-runner.js\";\nimport { runPagesParallel } from \"./parallel.js\";\nimport { setupRunDirectory } from \"./setup.js\";\nimport { runReporters } from \"../reporters/index.js\";\nimport { PluginRegistry, loadPlugins } from \"../plugins/index.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport interface RunOptions {\n headed?: boolean;\n pagesFilter?: string[];\n auditsFilter?: string[];\n}\n\nexport async function run(\n config: WebguardConfig,\n options: RunOptions = {}\n): Promise<RunResult> {\n const start = Date.now();\n\n // Override headless from CLI\n if (options.headed !== undefined) {\n config.browser.headless = !options.headed;\n }\n\n // Load plugins\n const registry = new PluginRegistry();\n if (config.plugins.length > 0) {\n const plugins = await loadPlugins(config.plugins);\n for (const plugin of plugins) {\n registry.register(plugin);\n }\n }\n\n // Setup run directory\n const { runDir } = setupRunDirectory(config.output.dir);\n\n // Authenticate\n const authResult = await authenticate(config.auth, runDir);\n\n // Launch browser\n const browser = await chromium.launch({\n headless: config.browser.headless,\n });\n\n const contextOptions: any = {\n viewport: config.browser.viewport,\n };\n\n if (authResult?.storageStatePath) {\n contextOptions.storageState = authResult.storageStatePath;\n }\n if (authResult?.extraHeaders) {\n contextOptions.extraHTTPHeaders = authResult.extraHeaders;\n }\n\n const browserContext = await browser.newContext(contextOptions);\n\n // beforeAll hook\n await registry.runHook(\"beforeAll\", { config, browserContext });\n\n // Get enabled audits (built-in + plugin + custom)\n let audits = getEnabledAudits(\n config.audits,\n registry.getPluginAudits(),\n config.customAudits\n );\n\n // Filter audits if specified\n if (options.auditsFilter?.length) {\n audits = audits.filter((a) => options.auditsFilter!.includes(a.name));\n }\n\n const enabledAuditNames = audits.map((a) => a.name);\n\n // Filter pages if specified\n let pages = config.pages;\n if (options.pagesFilter?.length) {\n pages = pages.filter((p) => options.pagesFilter!.includes(p.name));\n }\n\n log.plain(\"\");\n log.info(`Base URL: ${config.baseURL}`);\n log.info(`Pages: ${pages.length}`);\n log.info(`Audits: ${enabledAuditNames.join(\", \")}`);\n if (config.plugins.length > 0) {\n log.info(`Plugins: ${config.plugins.length}`);\n }\n if (config.runner.concurrency > 1) {\n log.info(`Workers: ${config.runner.concurrency}`);\n }\n log.plain(\"\");\n\n // Run audits on each page\n let pageResults: PageResult[];\n\n if (config.runner.concurrency > 1) {\n // Parallel execution\n pageResults = await runPagesParallel(\n pages,\n config,\n browserContext,\n audits,\n runDir,\n registry,\n config.runner.concurrency,\n config.runner.failFast\n );\n } else {\n // Sequential execution\n pageResults = [];\n\n for (let i = 0; i < pages.length; i++) {\n const pageEntry = pages[i];\n log.plain(` [${i + 1}/${pages.length}] ${pageEntry.name} (${pageEntry.path})`);\n\n const result = await runPageAudits(\n pageEntry,\n config,\n browserContext,\n audits,\n runDir,\n registry\n );\n pageResults.push(result);\n\n // Print inline results\n for (const audit of result.audits) {\n const icon = audit.passed ? \" \\u2713\" : audit.severity === \"warning\" ? \" \\u26A0\" : \" \\u2717\";\n const duration = audit.duration ? `${audit.duration}ms` : \"\";\n log.plain(`${icon} ${audit.audit.padEnd(20)} ${audit.message.padEnd(30)} ${duration}`);\n }\n log.plain(\"\");\n\n // Fail fast\n if (config.runner.failFast && result.audits.some((a) => a.severity === \"fail\")) {\n log.warn(\"Fail fast enabled — stopping after first failure\");\n break;\n }\n }\n }\n\n await browserContext.close();\n await browser.close();\n\n // Build summary\n const allAudits = pageResults.flatMap((p) => p.audits);\n const runResult: RunResult = {\n timestamp: new Date().toISOString(),\n config: {\n baseURL: config.baseURL,\n totalPages: pages.length,\n auditsEnabled: enabledAuditNames,\n },\n pages: pageResults,\n summary: {\n totalAudits: allAudits.length,\n passed: allAudits.filter((a) => a.severity === \"pass\").length,\n failed: allAudits.filter((a) => a.severity === \"fail\").length,\n warnings: allAudits.filter((a) => a.severity === \"warning\").length,\n skipped: allAudits.filter((a) => a.severity === \"skip\").length,\n duration: Date.now() - start,\n },\n };\n\n // afterAll hook\n await registry.runHook(\"afterAll\", { config, result: runResult });\n\n // Run reporters (built-in + plugin)\n await runReporters(runResult, config, runDir, registry.getPluginReporters());\n\n return runResult;\n}\n","import { request } from \"playwright\";\nimport path from \"path\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport type { AuthResult } from \"../index.js\";\n\ninterface ApiLoginConfig {\n method: \"api-login\";\n loginUrl: string;\n payload: Record<string, string>;\n headers?: Record<string, string>;\n}\n\nexport async function apiLogin(\n config: ApiLoginConfig,\n outputDir: string\n): Promise<AuthResult> {\n const authDir = path.join(outputDir, \".auth\");\n ensureDir(authDir);\n const storagePath = path.join(authDir, \"storageState.json\");\n\n const origin = new URL(config.loginUrl).origin;\n const context = await request.newContext({ baseURL: origin });\n\n const response = await context.post(config.loginUrl, {\n data: config.payload,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n ...config.headers,\n },\n });\n\n if (!response.ok()) {\n const body = await response.text();\n await context.dispose();\n throw new Error(`Login failed (HTTP ${response.status()}): ${body}`);\n }\n\n await context.storageState({ path: storagePath });\n await context.dispose();\n\n return { storageStatePath: storagePath };\n}\n","import fs from \"fs\";\nimport path from \"path\";\n\nexport function ensureDir(dir: string): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n\nexport function cleanDir(dir: string): void {\n if (fs.existsSync(dir)) {\n fs.rmSync(dir, { recursive: true, force: true });\n }\n}\n\nexport function ensureCleanDir(dir: string): void {\n cleanDir(dir);\n fs.mkdirSync(dir, { recursive: true });\n}\n\nexport function writeJson(filePath: string, data: unknown): void {\n ensureDir(path.dirname(filePath));\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2));\n}\n","import { chromium } from \"playwright\";\nimport path from \"path\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport type { AuthResult } from \"../index.js\";\n\ninterface FormLoginConfig {\n method: \"form-login\";\n loginUrl: string;\n fields: Array<{ selector: string; value: string }>;\n submitSelector: string;\n waitAfterLogin?: string;\n}\n\nexport async function formLogin(\n config: FormLoginConfig,\n outputDir: string\n): Promise<AuthResult> {\n const authDir = path.join(outputDir, \".auth\");\n ensureDir(authDir);\n const storagePath = path.join(authDir, \"storageState.json\");\n\n const browser = await chromium.launch({ headless: true });\n const context = await browser.newContext();\n const page = await context.newPage();\n\n await page.goto(config.loginUrl);\n\n for (const field of config.fields) {\n await page.fill(field.selector, field.value);\n }\n\n await page.click(config.submitSelector);\n\n if (config.waitAfterLogin) {\n if (config.waitAfterLogin.startsWith(\"http\")) {\n await page.waitForURL(config.waitAfterLogin);\n } else {\n await page.waitForSelector(config.waitAfterLogin);\n }\n } else {\n await page.waitForLoadState(\"networkidle\");\n }\n\n await context.storageState({ path: storagePath });\n await browser.close();\n\n return { storageStatePath: storagePath };\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport type { AuthResult } from \"../index.js\";\n\ninterface CookieConfig {\n method: \"cookie\";\n cookies: Array<{\n name: string;\n value: string;\n domain: string;\n path: string;\n }>;\n}\n\nexport async function cookieInject(\n config: CookieConfig,\n outputDir: string\n): Promise<AuthResult> {\n const authDir = path.join(outputDir, \".auth\");\n ensureDir(authDir);\n const storagePath = path.join(authDir, \"storageState.json\");\n\n const storageState = {\n cookies: config.cookies.map((c) => ({\n name: c.name,\n value: c.value,\n domain: c.domain,\n path: c.path || \"/\",\n expires: -1,\n httpOnly: false,\n secure: true,\n sameSite: \"Lax\" as const,\n })),\n origins: [],\n };\n\n fs.writeFileSync(storagePath, JSON.stringify(storageState, null, 2));\n return { storageStatePath: storagePath };\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport type { AuthResult } from \"../index.js\";\n\ninterface BearerConfig {\n method: \"bearer-token\";\n token: string;\n}\n\nexport async function bearerToken(\n config: BearerConfig,\n outputDir: string\n): Promise<AuthResult> {\n const authDir = path.join(outputDir, \".auth\");\n ensureDir(authDir);\n const storagePath = path.join(authDir, \"storageState.json\");\n\n fs.writeFileSync(\n storagePath,\n JSON.stringify({ cookies: [], origins: [] })\n );\n\n return {\n storageStatePath: storagePath,\n extraHeaders: { Authorization: `Bearer ${config.token}` },\n };\n}\n","import type { AuthConfig } from \"../config/schema.js\";\nimport { apiLogin } from \"./strategies/api-login.js\";\nimport { formLogin } from \"./strategies/form-login.js\";\nimport { cookieInject } from \"./strategies/cookie-inject.js\";\nimport { bearerToken } from \"./strategies/bearer-token.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport interface AuthResult {\n storageStatePath: string;\n extraHeaders?: Record<string, string>;\n}\n\nexport async function authenticate(\n authConfig: AuthConfig,\n outputDir: string\n): Promise<AuthResult | null> {\n if (authConfig.method === \"none\") {\n return null;\n }\n\n log.info(`Authenticating via ${authConfig.method}...`);\n\n let result: AuthResult;\n\n switch (authConfig.method) {\n case \"api-login\":\n result = await apiLogin(authConfig, outputDir);\n break;\n case \"form-login\":\n result = await formLogin(authConfig, outputDir);\n break;\n case \"cookie\":\n result = await cookieInject(authConfig, outputDir);\n break;\n case \"bearer-token\":\n result = await bearerToken(authConfig, outputDir);\n break;\n }\n\n log.success(\"Authenticated successfully\");\n return result;\n}\n","import type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport const HttpStatusAudit: Audit = {\n name: \"httpStatus\",\n description: \"Verify the page returns the expected HTTP status code\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const status = ctx.navigationResponse?.status() ?? 0;\n const expected = ctx.pageEntry.expectedStatus ?? 200;\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: status === expected,\n severity: status === expected ? \"pass\" : \"fail\",\n message:\n status === expected\n ? `HTTP ${status} OK`\n : `Expected HTTP ${expected}, got ${status}`,\n details: { status, expected },\n };\n },\n};\n","import type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport const ContentVisibilityAudit: Audit = {\n name: \"contentVisibility\",\n description: \"Verify the page has visible rendered content\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const { page } = ctx;\n\n const bodyVisible = await page\n .locator(\"body\")\n .isVisible()\n .catch(() => false);\n\n if (!bodyVisible) {\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: false,\n severity: \"fail\",\n message: \"Page body is not visible\",\n details: { bodyVisible: false, textLength: 0, elementCount: 0 },\n };\n }\n\n const bodyText = await page\n .locator(\"body\")\n .innerText()\n .catch(() => \"\");\n const textLength = bodyText.trim().length;\n\n const elementCount = await page\n .locator(\n \"body h1, body h2, body p, body main, body div, body section, body nav, body header\"\n )\n .count();\n\n const passed = textLength > 0 && elementCount > 0;\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed,\n severity: passed ? \"pass\" : \"fail\",\n message: passed\n ? `${elementCount} elements visible`\n : `Content check failed (text: ${textLength} chars, elements: ${elementCount})`,\n details: { bodyVisible: true, textLength, elementCount },\n };\n },\n};\n","import AxeBuilder from \"@axe-core/playwright\";\nimport path from \"path\";\nimport type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\nimport { sanitize } from \"../utils/sanitize.js\";\nimport { writeJson } from \"../utils/fs.js\";\n\nexport const AccessibilityAudit: Audit = {\n name: \"accessibility\",\n description: \"WCAG accessibility audit via axe-core\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const results = await new AxeBuilder({ page: ctx.page })\n .withTags(ctx.config.wcagTags)\n .analyze();\n\n const violations = results.violations;\n\n if (violations.length > 0) {\n const summary = violations.map((v) => ({\n rule: v.id,\n impact: v.impact,\n description: v.description,\n helpUrl: v.helpUrl,\n elements: v.nodes.length,\n }));\n\n const pageDir = path.join(\n ctx.runDir,\n \"screenshots\",\n sanitize(ctx.pageEntry.name)\n );\n writeJson(path.join(pageDir, \"a11y-violations.json\"), summary);\n }\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: violations.length === 0,\n severity: violations.length === 0 ? \"pass\" : \"warning\",\n message:\n violations.length === 0\n ? \"0 violations\"\n : `${violations.length} violation(s)`,\n details: {\n violationCount: violations.length,\n violations: violations.map((v) => ({\n rule: v.id,\n impact: v.impact,\n description: v.description,\n elements: v.nodes.length,\n })),\n },\n };\n },\n};\n","export function sanitize(name: string): string {\n return name.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n}\n","import path from \"path\";\nimport type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\nimport { sanitize } from \"../utils/sanitize.js\";\nimport { writeJson, ensureDir } from \"../utils/fs.js\";\n\nexport const LighthouseAudit: Audit = {\n name: \"lighthouse\",\n description:\n \"Lighthouse performance, accessibility, best practices, and SEO audit\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n let lighthouse: any;\n let chromeLauncher: any;\n\n try {\n lighthouse = await import(\"lighthouse\");\n chromeLauncher = await import(\"chrome-launcher\");\n } catch {\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: false,\n severity: \"skip\",\n message:\n 'Lighthouse not installed. Run: npm install lighthouse chrome-launcher',\n };\n }\n\n const chrome = await chromeLauncher.launch({\n chromeFlags: [\"--headless\", \"--no-sandbox\"],\n });\n\n const url = `${ctx.config.baseURL}${ctx.pageEntry.path}`;\n const thresholds = ctx.config.lighthouseThresholds;\n\n try {\n const result = await lighthouse.default(url, {\n port: chrome.port,\n output: \"json\",\n logLevel: \"error\",\n onlyCategories: [\n \"performance\",\n \"accessibility\",\n \"best-practices\",\n \"seo\",\n ],\n });\n\n await chrome.kill();\n\n if (!result?.lhr) {\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: false,\n severity: \"fail\",\n message: \"Lighthouse failed to produce results\",\n };\n }\n\n const scores = {\n performance: Math.round(\n (result.lhr.categories.performance?.score ?? 0) * 100\n ),\n accessibility: Math.round(\n (result.lhr.categories.accessibility?.score ?? 0) * 100\n ),\n bestPractices: Math.round(\n (result.lhr.categories[\"best-practices\"]?.score ?? 0) * 100\n ),\n seo: Math.round((result.lhr.categories.seo?.score ?? 0) * 100),\n };\n\n const failures: string[] = [];\n if (thresholds.performance && scores.performance < thresholds.performance)\n failures.push(\n `Performance: ${scores.performance} < ${thresholds.performance}`\n );\n if (\n thresholds.accessibility &&\n scores.accessibility < thresholds.accessibility\n )\n failures.push(\n `Accessibility: ${scores.accessibility} < ${thresholds.accessibility}`\n );\n if (\n thresholds.bestPractices &&\n scores.bestPractices < thresholds.bestPractices\n )\n failures.push(\n `Best Practices: ${scores.bestPractices} < ${thresholds.bestPractices}`\n );\n if (thresholds.seo && scores.seo < thresholds.seo)\n failures.push(`SEO: ${scores.seo} < ${thresholds.seo}`);\n\n const pageDir = path.join(\n ctx.runDir,\n \"screenshots\",\n sanitize(ctx.pageEntry.name)\n );\n ensureDir(pageDir);\n writeJson(path.join(pageDir, \"lighthouse-report.json\"), result.lhr);\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: failures.length === 0,\n severity: failures.length > 0 ? \"fail\" : \"pass\",\n message:\n failures.length > 0\n ? `Failed: ${failures.join(\"; \")}`\n : `perf=${scores.performance} a11y=${scores.accessibility} bp=${scores.bestPractices} seo=${scores.seo}`,\n details: { scores, thresholds, failures },\n };\n } catch (err) {\n await chrome.kill().catch(() => {});\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: false,\n severity: \"fail\",\n message: `Lighthouse error: ${(err as Error).message}`,\n };\n }\n },\n};\n","import type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport const BrokenLinksAudit: Audit = {\n name: \"brokenLinks\",\n description: \"Find broken links (4xx/5xx) on the page\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const links: string[] = await ctx.page.$$eval(\"a[href]\", (anchors) =>\n anchors\n .map((a) => a.getAttribute(\"href\"))\n .filter((href): href is string => !!href)\n );\n\n const baseOrigin = new URL(ctx.config.baseURL).origin;\n const uniqueLinks = [\n ...new Set(\n links\n .map((href) => {\n try {\n return new URL(href, ctx.config.baseURL).href;\n } catch {\n return null;\n }\n })\n .filter(\n (url): url is string =>\n !!url &&\n (url.startsWith(\"http://\") || url.startsWith(\"https://\"))\n )\n ),\n ];\n\n const broken: Array<{ url: string; status: number }> = [];\n\n for (const url of uniqueLinks) {\n try {\n const response = await ctx.page.request.head(url, { timeout: 10000 });\n if (response.status() >= 400) {\n broken.push({ url, status: response.status() });\n }\n } catch {\n broken.push({ url, status: 0 });\n }\n }\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: broken.length === 0,\n severity: broken.length > 0 ? \"warning\" : \"pass\",\n message:\n broken.length === 0\n ? `All ${uniqueLinks.length} links valid`\n : `${broken.length} broken link(s) of ${uniqueLinks.length}`,\n details: { totalLinks: uniqueLinks.length, broken },\n };\n },\n};\n","import type { Audit, AuditContext } from \"./index.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport const ConsoleErrorsAudit: Audit = {\n name: \"consoleErrors\",\n description: \"Capture browser console errors and warnings\",\n\n async run(ctx: AuditContext): Promise<AuditResult> {\n const messages = ctx.consoleMessages;\n\n const errors = messages.filter((m) => m.type === \"error\");\n const warnings = messages.filter((m) => m.type === \"warning\");\n\n return {\n audit: this.name,\n page: ctx.pageEntry.name,\n passed: errors.length === 0,\n severity:\n errors.length > 0 ? \"fail\" : warnings.length > 0 ? \"warning\" : \"pass\",\n message:\n errors.length === 0 && warnings.length === 0\n ? \"0 errors\"\n : `${errors.length} error(s), ${warnings.length} warning(s)`,\n details: {\n errors: errors.map((e) => e.text),\n warnings: warnings.map((w) => w.text),\n },\n };\n },\n};\n","import type { Page, BrowserContext, Response } from \"playwright\";\nimport type { PageEntry, WebguardConfig } from \"../config/schema.js\";\nimport type { AuditResult } from \"../types/index.js\";\n\nexport interface AuditContext {\n page: Page;\n browserContext: BrowserContext;\n pageEntry: PageEntry;\n config: WebguardConfig;\n runDir: string;\n navigationResponse: Response | null;\n consoleMessages: Array<{ type: string; text: string }>;\n}\n\nexport interface Audit {\n name: string;\n description: string;\n run(ctx: AuditContext): Promise<AuditResult>;\n}\n\nimport { HttpStatusAudit } from \"./http-status.js\";\nimport { ContentVisibilityAudit } from \"./content-visibility.js\";\nimport { AccessibilityAudit } from \"./accessibility.js\";\nimport { LighthouseAudit } from \"./lighthouse.js\";\nimport { BrokenLinksAudit } from \"./broken-links.js\";\nimport { ConsoleErrorsAudit } from \"./console-errors.js\";\n\nconst BUILTIN_AUDITS: Record<string, Audit> = {\n httpStatus: HttpStatusAudit,\n contentVisibility: ContentVisibilityAudit,\n accessibility: AccessibilityAudit,\n lighthouse: LighthouseAudit,\n brokenLinks: BrokenLinksAudit,\n consoleErrors: ConsoleErrorsAudit,\n};\n\nexport function getEnabledAudits(\n auditsConfig: Record<string, boolean>,\n pluginAudits: Audit[] = [],\n customAudits: Audit[] = []\n): Audit[] {\n const allAudits: Record<string, Audit> = { ...BUILTIN_AUDITS };\n\n // Register plugin-provided audits\n for (const audit of [...pluginAudits, ...customAudits]) {\n allAudits[audit.name] = audit;\n }\n\n const enabled: Audit[] = [];\n for (const [name, audit] of Object.entries(allAudits)) {\n // Custom/plugin audits default to enabled unless explicitly disabled\n const isEnabled = auditsConfig[name] ?? true;\n if (isEnabled) {\n enabled.push(audit);\n }\n }\n return enabled;\n}\n\nexport function getAuditByName(name: string): Audit | undefined {\n return BUILTIN_AUDITS[name];\n}\n","import path from \"path\";\nimport type { BrowserContext } from \"playwright\";\nimport type { PageEntry, WebguardConfig } from \"../config/schema.js\";\nimport type { AuditResult, PageResult } from \"../types/index.js\";\nimport type { Audit, AuditContext } from \"../audits/index.js\";\nimport type { PluginRegistry } from \"../plugins/registry.js\";\nimport { navigateWithRetry } from \"./retry.js\";\nimport { sanitize } from \"../utils/sanitize.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport async function runPageAudits(\n pageEntry: PageEntry,\n config: WebguardConfig,\n browserContext: BrowserContext,\n audits: Audit[],\n runDir: string,\n registry?: PluginRegistry\n): Promise<PageResult> {\n const start = Date.now();\n const url = `${config.baseURL}${pageEntry.path}`;\n const page = await browserContext.newPage();\n\n // beforePage hook\n if (registry) {\n await registry.runHook(\"beforePage\", { config, pageEntry, page });\n }\n\n // Attach console listener before navigation\n const consoleMessages: Array<{ type: string; text: string }> = [];\n page.on(\"console\", (msg) => {\n consoleMessages.push({ type: msg.type(), text: msg.text() });\n });\n\n // Navigate with retry\n let navigationResponse = null;\n try {\n navigationResponse = await navigateWithRetry(\n page,\n url,\n config.retry,\n \"domcontentloaded\"\n );\n } catch (err) {\n log.error(`Failed to navigate to ${url}: ${(err as Error).message}`);\n }\n\n // Build audit context\n const ctx: AuditContext = {\n page,\n browserContext,\n pageEntry,\n config,\n runDir,\n navigationResponse,\n consoleMessages,\n };\n\n // Filter out skipped audits for this page\n const pageAudits = audits.filter(\n (a) => !pageEntry.skipAudits?.includes(a.name)\n );\n\n // Run each audit\n const auditResults: AuditResult[] = [];\n for (const audit of pageAudits) {\n // beforeAudit hook\n if (registry) {\n await registry.runHook(\"beforeAudit\", { audit, auditContext: ctx });\n }\n\n const auditStart = Date.now();\n let result: AuditResult;\n try {\n result = await audit.run(ctx);\n result.duration = Date.now() - auditStart;\n } catch (err) {\n result = {\n audit: audit.name,\n page: pageEntry.name,\n passed: false,\n severity: \"fail\",\n message: `Audit error: ${(err as Error).message}`,\n duration: Date.now() - auditStart,\n };\n }\n auditResults.push(result);\n\n // afterAudit hook\n if (registry) {\n await registry.runHook(\"afterAudit\", { audit, result });\n }\n }\n\n // Capture screenshot\n let screenshotPath: string | undefined;\n if (config.output.screenshots) {\n const anyFailed = auditResults.some((r) => !r.passed);\n if (!config.output.screenshotOnFailOnly || anyFailed) {\n try {\n const pageDir = path.join(runDir, \"screenshots\", sanitize(pageEntry.name));\n ensureDir(pageDir);\n const status = anyFailed ? \"fail\" : \"pass\";\n screenshotPath = path.join(pageDir, `page-${status}.png`);\n await page.screenshot({ path: screenshotPath, fullPage: true });\n } catch {\n // Screenshot failed, not critical\n }\n }\n }\n\n const pageResult: PageResult = {\n page: pageEntry.name,\n path: pageEntry.path,\n url,\n audits: auditResults,\n screenshotPath,\n duration: Date.now() - start,\n };\n\n // afterPage hook\n if (registry) {\n await registry.runHook(\"afterPage\", { config, pageEntry, pageResult });\n }\n\n await page.close();\n\n return pageResult;\n}\n","export function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { Page, Response } from \"playwright\";\nimport { sleep } from \"../utils/sleep.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport interface RetryConfig {\n maxRetries: number;\n delayMs: number;\n}\n\nexport async function navigateWithRetry(\n page: Page,\n url: string,\n retry: RetryConfig,\n waitUntil: \"domcontentloaded\" | \"networkidle\" | \"load\" = \"domcontentloaded\"\n): Promise<Response | null> {\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= retry.maxRetries; attempt++) {\n try {\n const response = await page.goto(url, {\n waitUntil,\n timeout: 30_000,\n });\n\n if (response && response.ok()) {\n return response;\n }\n\n if (attempt < retry.maxRetries) {\n log.warn(\n `Attempt ${attempt}/${retry.maxRetries} for ${url} returned ${response?.status()}. Retrying in ${retry.delayMs / 1000}s...`\n );\n await sleep(retry.delayMs);\n }\n\n if (attempt === retry.maxRetries) return response;\n } catch (error) {\n lastError = error as Error;\n if (attempt < retry.maxRetries) {\n log.warn(\n `Attempt ${attempt}/${retry.maxRetries} for ${url} failed. Retrying in ${retry.delayMs / 1000}s...`\n );\n await sleep(retry.delayMs);\n }\n }\n }\n\n throw (\n lastError ??\n new Error(`Failed to load ${url} after ${retry.maxRetries} attempts`)\n );\n}\n","import type { BrowserContext } from \"playwright\";\nimport type { PageEntry, WebguardConfig } from \"../config/schema.js\";\nimport type { PageResult } from \"../types/index.js\";\nimport type { Audit } from \"../audits/index.js\";\nimport type { PluginRegistry } from \"../plugins/registry.js\";\nimport { runPageAudits } from \"./page-runner.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport async function runPagesParallel(\n pages: PageEntry[],\n config: WebguardConfig,\n browserContext: BrowserContext,\n audits: Audit[],\n runDir: string,\n registry: PluginRegistry,\n concurrency: number,\n failFast: boolean\n): Promise<PageResult[]> {\n const results: PageResult[] = new Array(pages.length);\n let currentIndex = 0;\n let aborted = false;\n\n async function worker(): Promise<void> {\n while (!aborted) {\n const index = currentIndex++;\n if (index >= pages.length) break;\n\n const pageEntry = pages[index];\n log.plain(` [${index + 1}/${pages.length}] ${pageEntry.name} (${pageEntry.path})`);\n\n const result = await runPageAudits(\n pageEntry,\n config,\n browserContext,\n audits,\n runDir,\n registry\n );\n results[index] = result;\n\n // Print inline results\n for (const audit of result.audits) {\n const icon = audit.passed\n ? \" \\u2713\"\n : audit.severity === \"warning\"\n ? \" \\u26A0\"\n : \" \\u2717\";\n const duration = audit.duration ? `${audit.duration}ms` : \"\";\n log.plain(\n `${icon} ${audit.audit.padEnd(20)} ${audit.message.padEnd(30)} ${duration}`\n );\n }\n log.plain(\"\");\n\n if (failFast && result.audits.some((a) => a.severity === \"fail\")) {\n log.warn(\"Fail fast enabled — stopping after first failure\");\n aborted = true;\n }\n }\n }\n\n const workerCount = Math.min(concurrency, pages.length);\n const workers = Array.from({ length: workerCount }, () => worker());\n\n await Promise.all(workers);\n\n return results.filter(Boolean);\n}\n","import path from \"path\";\nimport { ensureDir, cleanDir } from \"../utils/fs.js\";\n\nexport interface RunDirs {\n runDir: string;\n screenshotsDir: string;\n}\n\nexport function setupRunDirectory(outputBaseDir: string): RunDirs {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const runDir = path.join(outputBaseDir, `run-${timestamp}`);\n const screenshotsDir = path.join(runDir, \"screenshots\");\n\n // Clean previous runs\n cleanDir(outputBaseDir);\n\n // Create fresh directories\n ensureDir(screenshotsDir);\n\n return { runDir, screenshotsDir };\n}\n","import path from \"path\";\nimport type { RunResult } from \"../types/index.js\";\nimport { writeJson } from \"../utils/fs.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport function reportJson(result: RunResult, runDir: string): void {\n const filePath = path.join(runDir, \"results.json\");\n writeJson(filePath, result);\n log.dim(` JSON report: ${filePath}`);\n}\n","import { c } from \"../utils/colors.js\";\nimport type { RunResult } from \"../types/index.js\";\n\nexport function reportTerminal(result: RunResult): void {\n const { summary } = result;\n\n console.log(\"\");\n console.log(c.bold(\"─\".repeat(60)));\n console.log(c.bold(\" Summary\"));\n console.log(c.bold(\"─\".repeat(60)));\n console.log(\"\");\n\n console.log(` Total audits: ${summary.totalAudits}`);\n console.log(\n ` ${c.green(\"✓ Passed:\")} ${summary.passed}`\n );\n\n if (summary.failed > 0) {\n console.log(\n ` ${c.red(\"✗ Failed:\")} ${summary.failed}`\n );\n }\n if (summary.warnings > 0) {\n console.log(\n ` ${c.yellow(\"⚠ Warnings:\")} ${summary.warnings}`\n );\n }\n if (summary.skipped > 0) {\n console.log(\n ` ${c.dim(\"○ Skipped:\")} ${summary.skipped}`\n );\n }\n\n console.log(\n ` Duration: ${(summary.duration / 1000).toFixed(1)}s`\n );\n console.log(\"\");\n\n // Show failed audits detail\n const failedAudits = result.pages.flatMap((p) =>\n p.audits.filter((a) => a.severity === \"fail\")\n );\n\n if (failedAudits.length > 0) {\n console.log(c.bold(c.red(\" Failed Audits:\")));\n for (const audit of failedAudits) {\n console.log(\n c.red(` ✗ ${audit.page} → ${audit.audit}: ${audit.message}`)\n );\n }\n console.log(\"\");\n }\n\n // Exit status hint\n if (summary.failed > 0) {\n console.log(\n c.bold(c.red(` Result: FAIL (${summary.failed} failure(s))`))\n );\n } else if (summary.warnings > 0) {\n console.log(\n c.bold(c.yellow(` Result: PASS with ${summary.warnings} warning(s)`))\n );\n } else {\n console.log(c.bold(c.green(\" Result: PASS\")));\n }\n\n console.log(\"\");\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport type { RunResult, PageResult, AuditResult } from \"../types/index.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport { log } from \"../utils/logger.js\";\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction severityIcon(severity: string): string {\n switch (severity) {\n case \"pass\":\n return \"&#x2713;\";\n case \"fail\":\n return \"&#x2717;\";\n case \"warning\":\n return \"&#x26A0;\";\n case \"skip\":\n return \"&#x25CB;\";\n default:\n return \"?\";\n }\n}\n\nfunction severityClass(severity: string): string {\n return `severity-${severity}`;\n}\n\nfunction renderAuditRow(audit: AuditResult): string {\n return `\n <tr class=\"${severityClass(audit.severity)}\">\n <td class=\"icon\">${severityIcon(audit.severity)}</td>\n <td>${escapeHtml(audit.audit)}</td>\n <td>${escapeHtml(audit.message)}</td>\n <td class=\"duration\">${audit.duration ? `${audit.duration}ms` : \"—\"}</td>\n </tr>`;\n}\n\nfunction renderPageSection(page: PageResult): string {\n const failCount = page.audits.filter((a) => a.severity === \"fail\").length;\n const status = failCount > 0 ? \"fail\" : \"pass\";\n\n return `\n <div class=\"page-section\">\n <h2 class=\"page-header ${status}\">\n <span class=\"page-name\">${escapeHtml(page.page)}</span>\n <span class=\"page-path\">${escapeHtml(page.path)}</span>\n <span class=\"page-duration\">${(page.duration / 1000).toFixed(1)}s</span>\n </h2>\n <table class=\"audit-table\">\n <thead>\n <tr>\n <th class=\"icon-col\"></th>\n <th>Audit</th>\n <th>Result</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n ${page.audits.map(renderAuditRow).join(\"\")}\n </tbody>\n </table>\n </div>`;\n}\n\nfunction buildHtml(result: RunResult): string {\n const { summary } = result;\n const overallStatus =\n summary.failed > 0 ? \"FAIL\" : summary.warnings > 0 ? \"PASS (with warnings)\" : \"PASS\";\n const statusClass = summary.failed > 0 ? \"fail\" : summary.warnings > 0 ? \"warning\" : \"pass\";\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Webguardx Report — ${escapeHtml(result.config.baseURL)}</title>\n <style>\n :root {\n --pass: #22c55e;\n --fail: #ef4444;\n --warning: #f59e0b;\n --skip: #94a3b8;\n --bg: #0f172a;\n --surface: #1e293b;\n --text: #e2e8f0;\n --text-dim: #94a3b8;\n --border: #334155;\n }\n\n * { box-sizing: border-box; margin: 0; padding: 0; }\n\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: var(--bg);\n color: var(--text);\n line-height: 1.6;\n padding: 2rem;\n }\n\n .container { max-width: 900px; margin: 0 auto; }\n\n header {\n text-align: center;\n margin-bottom: 2rem;\n padding-bottom: 1.5rem;\n border-bottom: 1px solid var(--border);\n }\n\n header h1 {\n font-size: 1.75rem;\n font-weight: 700;\n margin-bottom: 0.5rem;\n }\n\n header .meta {\n color: var(--text-dim);\n font-size: 0.875rem;\n }\n\n .summary-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 1rem;\n margin-bottom: 2rem;\n }\n\n .summary-card {\n background: var(--surface);\n border-radius: 8px;\n padding: 1rem;\n text-align: center;\n border: 1px solid var(--border);\n }\n\n .summary-card .value {\n font-size: 2rem;\n font-weight: 700;\n }\n\n .summary-card .label {\n font-size: 0.75rem;\n color: var(--text-dim);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n\n .summary-card.pass .value { color: var(--pass); }\n .summary-card.fail .value { color: var(--fail); }\n .summary-card.warning .value { color: var(--warning); }\n .summary-card.skip .value { color: var(--skip); }\n\n .overall-status {\n text-align: center;\n font-size: 1.25rem;\n font-weight: 700;\n padding: 0.75rem;\n border-radius: 8px;\n margin-bottom: 2rem;\n }\n\n .overall-status.pass { background: rgba(34,197,94,0.15); color: var(--pass); }\n .overall-status.fail { background: rgba(239,68,68,0.15); color: var(--fail); }\n .overall-status.warning { background: rgba(245,158,11,0.15); color: var(--warning); }\n\n .page-section {\n background: var(--surface);\n border-radius: 8px;\n margin-bottom: 1.5rem;\n border: 1px solid var(--border);\n overflow: hidden;\n }\n\n .page-header {\n padding: 1rem 1.25rem;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n border-bottom: 1px solid var(--border);\n }\n\n .page-header.fail { border-left: 4px solid var(--fail); }\n .page-header.pass { border-left: 4px solid var(--pass); }\n\n .page-name { font-weight: 600; }\n .page-path { color: var(--text-dim); font-size: 0.875rem; }\n .page-duration { margin-left: auto; color: var(--text-dim); font-size: 0.875rem; }\n\n .audit-table {\n width: 100%;\n border-collapse: collapse;\n }\n\n .audit-table th {\n text-align: left;\n padding: 0.5rem 1rem;\n font-size: 0.75rem;\n text-transform: uppercase;\n color: var(--text-dim);\n border-bottom: 1px solid var(--border);\n }\n\n .audit-table td {\n padding: 0.6rem 1rem;\n border-bottom: 1px solid var(--border);\n }\n\n .audit-table tr:last-child td { border-bottom: none; }\n\n .icon-col { width: 40px; }\n .icon { text-align: center; font-size: 1.1rem; }\n .duration { color: var(--text-dim); font-size: 0.875rem; }\n\n .severity-pass .icon { color: var(--pass); }\n .severity-fail .icon { color: var(--fail); }\n .severity-warning .icon { color: var(--warning); }\n .severity-skip .icon { color: var(--skip); }\n\n footer {\n text-align: center;\n margin-top: 2rem;\n padding-top: 1rem;\n border-top: 1px solid var(--border);\n color: var(--text-dim);\n font-size: 0.75rem;\n }\n\n footer a { color: var(--text-dim); }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <header>\n <h1>Webguardx Report</h1>\n <div class=\"meta\">\n ${escapeHtml(result.config.baseURL)} &bull;\n ${escapeHtml(result.timestamp)} &bull;\n ${result.config.auditsEnabled.join(\", \")}\n </div>\n </header>\n\n <div class=\"overall-status ${statusClass}\">${overallStatus}</div>\n\n <div class=\"summary-grid\">\n <div class=\"summary-card\">\n <div class=\"value\">${summary.totalAudits}</div>\n <div class=\"label\">Total</div>\n </div>\n <div class=\"summary-card pass\">\n <div class=\"value\">${summary.passed}</div>\n <div class=\"label\">Passed</div>\n </div>\n <div class=\"summary-card fail\">\n <div class=\"value\">${summary.failed}</div>\n <div class=\"label\">Failed</div>\n </div>\n <div class=\"summary-card warning\">\n <div class=\"value\">${summary.warnings}</div>\n <div class=\"label\">Warnings</div>\n </div>\n <div class=\"summary-card skip\">\n <div class=\"value\">${summary.skipped}</div>\n <div class=\"label\">Skipped</div>\n </div>\n <div class=\"summary-card\">\n <div class=\"value\">${(summary.duration / 1000).toFixed(1)}s</div>\n <div class=\"label\">Duration</div>\n </div>\n </div>\n\n ${result.pages.map(renderPageSection).join(\"\")}\n\n <footer>\n Generated by <a href=\"https://github.com/user/webguardx\">webguardx</a>\n </footer>\n </div>\n</body>\n</html>`;\n}\n\nexport function reportHtml(result: RunResult, runDir: string): void {\n const filePath = path.join(runDir, \"report.html\");\n ensureDir(runDir);\n fs.writeFileSync(filePath, buildHtml(result), \"utf-8\");\n log.dim(` HTML report: ${filePath}`);\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport type { RunResult, PageResult, AuditResult } from \"../types/index.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport { log } from \"../utils/logger.js\";\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n}\n\nfunction buildTestCase(audit: AuditResult): string {\n const name = escapeXml(`${audit.page} - ${audit.audit}`);\n const time = audit.duration ? (audit.duration / 1000).toFixed(3) : \"0.000\";\n\n if (audit.severity === \"pass\") {\n return ` <testcase name=\"${name}\" classname=\"${escapeXml(audit.page)}\" time=\"${time}\" />\\n`;\n }\n\n if (audit.severity === \"skip\") {\n return ` <testcase name=\"${name}\" classname=\"${escapeXml(audit.page)}\" time=\"${time}\">\\n <skipped message=\"${escapeXml(audit.message)}\" />\\n </testcase>\\n`;\n }\n\n const tag = audit.severity === \"fail\" ? \"failure\" : \"failure\";\n return ` <testcase name=\"${name}\" classname=\"${escapeXml(audit.page)}\" time=\"${time}\">\\n <${tag} message=\"${escapeXml(audit.message)}\" type=\"${escapeXml(audit.severity)}\">${escapeXml(audit.message)}</${tag}>\\n </testcase>\\n`;\n}\n\nfunction buildTestSuite(page: PageResult, index: number): string {\n const tests = page.audits.length;\n const failures = page.audits.filter((a) => a.severity === \"fail\").length;\n const skipped = page.audits.filter((a) => a.severity === \"skip\").length;\n const time = (page.duration / 1000).toFixed(3);\n\n let xml = ` <testsuite name=\"${escapeXml(page.page)}\" tests=\"${tests}\" failures=\"${failures}\" skipped=\"${skipped}\" time=\"${time}\" id=\"${index}\">\\n`;\n for (const audit of page.audits) {\n xml += buildTestCase(audit);\n }\n xml += ` </testsuite>\\n`;\n return xml;\n}\n\nexport function reportJunit(result: RunResult, runDir: string): void {\n const { summary } = result;\n const time = (summary.duration / 1000).toFixed(3);\n\n let xml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n`;\n xml += `<testsuites name=\"webguardx\" tests=\"${summary.totalAudits}\" failures=\"${summary.failed}\" skipped=\"${summary.skipped}\" time=\"${time}\">\\n`;\n\n result.pages.forEach((page, i) => {\n xml += buildTestSuite(page, i);\n });\n\n xml += `</testsuites>\\n`;\n\n const filePath = path.join(runDir, \"results.xml\");\n ensureDir(runDir);\n fs.writeFileSync(filePath, xml, \"utf-8\");\n log.dim(` JUnit report: ${filePath}`);\n}\n","import type { RunResult } from \"../types/index.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport function reportScreenshots(result: RunResult): void {\n const captured = result.pages.filter((p) => p.screenshotPath);\n if (captured.length > 0) {\n log.dim(` Screenshots: ${captured.length} page(s) captured`);\n }\n}\n","import type { RunResult } from \"../types/index.js\";\nimport type { WebguardConfig } from \"../config/schema.js\";\nimport type { Reporter } from \"../plugins/types.js\";\nimport { reportJson } from \"./json.js\";\nimport { reportTerminal } from \"./terminal.js\";\nimport { reportHtml } from \"./html.js\";\nimport { reportJunit } from \"./junit.js\";\nimport { reportScreenshots } from \"./screenshot.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport async function runReporters(\n result: RunResult,\n config: WebguardConfig,\n runDir: string,\n pluginReporters: Reporter[] = []\n): Promise<void> {\n const formats = config.output.formats;\n\n if (formats.includes(\"terminal\")) {\n reportTerminal(result);\n }\n\n log.dim(\" Output:\");\n\n if (formats.includes(\"json\")) {\n reportJson(result, runDir);\n }\n\n if (formats.includes(\"html\")) {\n reportHtml(result, runDir);\n }\n\n if (formats.includes(\"junit\")) {\n reportJunit(result, runDir);\n }\n\n if (config.output.screenshots) {\n reportScreenshots(result);\n }\n\n // Plugin reporters\n for (const reporter of pluginReporters) {\n try {\n await reporter.run(result, runDir, config);\n log.dim(` ${reporter.name}: done`);\n } catch (err) {\n log.warn(`Reporter '${reporter.name}' failed: ${(err as Error).message}`);\n }\n }\n\n log.plain(\"\");\n}\n","import type { WebguardPlugin, Reporter, LifecycleHooks } from \"./types.js\";\nimport type { Audit } from \"../audits/index.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport class PluginRegistry {\n private plugins: WebguardPlugin[] = [];\n\n register(plugin: WebguardPlugin): void {\n this.plugins.push(plugin);\n }\n\n getPluginAudits(): Audit[] {\n return this.plugins.flatMap((p) => p.audits ?? []);\n }\n\n getPluginReporters(): Reporter[] {\n return this.plugins.flatMap((p) => p.reporters ?? []);\n }\n\n async runHook<K extends keyof LifecycleHooks>(\n hookName: K,\n ctx: Parameters<LifecycleHooks[K]>[0]\n ): Promise<void> {\n for (const plugin of this.plugins) {\n const hook = plugin.hooks?.[hookName];\n if (hook) {\n try {\n await (hook as (ctx: any) => Promise<void> | void)(ctx);\n } catch (err) {\n log.warn(\n `Plugin '${plugin.name}' hook '${hookName}' failed: ${(err as Error).message}`\n );\n }\n }\n }\n }\n}\n","import type { WebguardPlugin } from \"./types.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport async function loadPlugins(\n pluginEntries: Array<WebguardPlugin | string>\n): Promise<WebguardPlugin[]> {\n const plugins: WebguardPlugin[] = [];\n\n for (const entry of pluginEntries) {\n if (typeof entry === \"string\") {\n try {\n const { createJiti } = await import(\"jiti\");\n const jiti = createJiti(import.meta.url);\n const mod = await jiti.import(entry);\n const plugin = (mod as any).default ?? mod;\n plugins.push(plugin as WebguardPlugin);\n log.dim(` Loaded plugin: ${plugin.name ?? entry}`);\n } catch (err) {\n log.warn(`Failed to load plugin '${entry}': ${(err as Error).message}`);\n }\n } else {\n plugins.push(entry);\n }\n }\n\n return plugins;\n}\n","import type { NotificationChannel } from \"./types.js\";\n\nexport interface WebhookOptions {\n method?: \"POST\" | \"PUT\";\n headers?: Record<string, string>;\n onlyOnFailure?: boolean;\n}\n\nexport function createWebhookNotifier(\n url: string,\n options: WebhookOptions = {}\n): NotificationChannel {\n return {\n name: `webhook:${new URL(url).hostname}`,\n async send(result, config) {\n if (options.onlyOnFailure && result.summary.failed === 0) return;\n\n await fetch(url, {\n method: options.method ?? \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n body: JSON.stringify({\n tool: \"webguardx\",\n status: result.summary.failed > 0 ? \"fail\" : \"pass\",\n baseURL: config.baseURL,\n timestamp: result.timestamp,\n summary: result.summary,\n }),\n });\n },\n };\n}\n","import type { NotificationChannel } from \"./types.js\";\n\nexport interface SlackOptions {\n channel?: string;\n onlyOnFailure?: boolean;\n}\n\nexport function createSlackNotifier(\n webhookUrl: string,\n options: SlackOptions = {}\n): NotificationChannel {\n return {\n name: \"slack\",\n async send(result, config) {\n if (options.onlyOnFailure && result.summary.failed === 0) return;\n\n const color = result.summary.failed > 0 ? \"#ef4444\" : \"#22c55e\";\n const status = result.summary.failed > 0 ? \"FAIL\" : \"PASS\";\n const { summary } = result;\n\n await fetch(webhookUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n channel: options.channel,\n attachments: [\n {\n color,\n title: `Webguardx: ${status}`,\n title_link: config.baseURL,\n text: `${summary.passed} passed, ${summary.failed} failed, ${summary.warnings} warnings`,\n fields: [\n { title: \"Base URL\", value: config.baseURL, short: true },\n { title: \"Pages\", value: `${config.pages.length}`, short: true },\n { title: \"Duration\", value: `${(summary.duration / 1000).toFixed(1)}s`, short: true },\n ],\n footer: \"webguardx\",\n ts: Math.floor(Date.now() / 1000),\n },\n ],\n }),\n });\n },\n };\n}\n","import type { RunResult } from \"../types/index.js\";\nimport type { WebguardConfig } from \"../config/schema.js\";\nimport type { NotificationChannel } from \"./types.js\";\nimport { log } from \"../utils/logger.js\";\n\nexport type { NotificationChannel } from \"./types.js\";\nexport { createWebhookNotifier } from \"./webhook.js\";\nexport type { WebhookOptions } from \"./webhook.js\";\nexport { createSlackNotifier } from \"./slack.js\";\nexport type { SlackOptions } from \"./slack.js\";\n\nexport async function sendNotifications(\n channels: NotificationChannel[],\n result: RunResult,\n config: WebguardConfig\n): Promise<void> {\n for (const channel of channels) {\n try {\n await channel.send(result, config);\n log.dim(` Notification sent: ${channel.name}`);\n } catch (err) {\n log.warn(\n `Notification '${channel.name}' failed: ${(err as Error).message}`\n );\n }\n }\n}\n","import path from \"path\";\nimport fs from \"fs\";\nimport type { RunResult } from \"../types/index.js\";\nimport { log } from \"../utils/logger.js\";\n\nconst BASELINE_FILENAME = \"baseline.json\";\n\nexport function saveBaseline(result: RunResult, outputDir: string): void {\n const baselinePath = path.join(outputDir, BASELINE_FILENAME);\n fs.writeFileSync(baselinePath, JSON.stringify(result, null, 2));\n log.success(`Baseline saved: ${baselinePath}`);\n}\n\nexport function loadBaseline(outputDir: string): RunResult | null {\n const baselinePath = path.join(outputDir, BASELINE_FILENAME);\n if (!fs.existsSync(baselinePath)) return null;\n try {\n return JSON.parse(fs.readFileSync(baselinePath, \"utf-8\"));\n } catch {\n log.warn(\"Failed to parse baseline file\");\n return null;\n }\n}\n\nexport function baselineExists(outputDir: string): boolean {\n return fs.existsSync(path.join(outputDir, BASELINE_FILENAME));\n}\n","import type { RunResult } from \"../types/index.js\";\nimport type { BaselineComparison, AuditChange } from \"./types.js\";\n\nexport function compareRuns(\n baseline: RunResult,\n current: RunResult\n): BaselineComparison {\n const changes: AuditChange[] = [];\n\n // Build lookup maps: \"page::audit\" -> { severity, message }\n const baselineMap = new Map<string, { severity: string; message: string }>();\n for (const page of baseline.pages) {\n for (const audit of page.audits) {\n baselineMap.set(`${page.page}::${audit.audit}`, {\n severity: audit.severity,\n message: audit.message,\n });\n }\n }\n\n const currentMap = new Map<string, { severity: string; message: string }>();\n for (const page of current.pages) {\n for (const audit of page.audits) {\n const key = `${page.page}::${audit.audit}`;\n const entry = { severity: audit.severity, message: audit.message };\n currentMap.set(key, entry);\n\n const prev = baselineMap.get(key);\n if (!prev) {\n changes.push({\n page: page.page,\n audit: audit.audit,\n type: \"new\",\n current: entry,\n });\n } else if (prev.severity !== audit.severity) {\n const type =\n audit.severity === \"pass\" || audit.severity === \"skip\"\n ? \"improvement\"\n : \"regression\";\n changes.push({\n page: page.page,\n audit: audit.audit,\n type,\n baseline: prev,\n current: entry,\n });\n } else {\n changes.push({\n page: page.page,\n audit: audit.audit,\n type: \"unchanged\",\n baseline: prev,\n current: entry,\n });\n }\n }\n }\n\n // Detect removed audits\n for (const [key, val] of baselineMap) {\n if (!currentMap.has(key)) {\n const [page, audit] = key.split(\"::\");\n changes.push({ page, audit, type: \"removed\", baseline: val });\n }\n }\n\n return {\n baselineTimestamp: baseline.timestamp,\n currentTimestamp: current.timestamp,\n changes,\n summary: {\n regressions: changes.filter((c) => c.type === \"regression\").length,\n improvements: changes.filter((c) => c.type === \"improvement\").length,\n unchanged: changes.filter((c) => c.type === \"unchanged\").length,\n newAudits: changes.filter((c) => c.type === \"new\").length,\n removedAudits: changes.filter((c) => c.type === \"removed\").length,\n },\n };\n}\n"],"mappings":"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","names":["path","fs","import_playwright","import_path","import_fs","import_path","fs","path","fs","path","import_playwright","import_path","path","import_fs","import_path","path","c","fs","import_fs","import_path","path","fs","import_playwright","import_path","AxeBuilder","path","import_path","path","enabled","import_path","path","import_path","path","import_path","path","import_fs","import_path","path","fs","import_fs","import_path","path","fs","import_path","import_fs","path","fs","c"]}