lighthouse 13.0.3 → 13.2.0

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.
Files changed (139) hide show
  1. package/CONTRIBUTING.md +1 -1
  2. package/cli/bin.js +5 -0
  3. package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +10 -10
  4. package/cli/test/smokehouse/config/exclusions.js +44 -0
  5. package/cli/test/smokehouse/frontends/smokehouse-bin.js +5 -4
  6. package/cli/test/smokehouse/lighthouse-runners/devtools-mcp.d.ts +14 -0
  7. package/cli/test/smokehouse/lighthouse-runners/devtools-mcp.js +141 -0
  8. package/core/audits/accessibility/autocomplete-valid.d.ts +10 -0
  9. package/core/audits/accessibility/autocomplete-valid.js +44 -0
  10. package/core/audits/accessibility/presentation-role-conflict.d.ts +10 -0
  11. package/core/audits/accessibility/presentation-role-conflict.js +46 -0
  12. package/core/audits/accessibility/svg-img-alt.d.ts +10 -0
  13. package/core/audits/accessibility/svg-img-alt.js +44 -0
  14. package/core/audits/agentic/agent-accessibility-tree.d.ts +19 -0
  15. package/core/audits/agentic/agent-accessibility-tree.js +115 -0
  16. package/core/audits/agentic/llms-txt.d.ts +20 -0
  17. package/core/audits/agentic/llms-txt.js +111 -0
  18. package/core/audits/baseline.d.ts +25 -0
  19. package/core/audits/baseline.js +190 -0
  20. package/core/audits/insights/insight-audit.d.ts +2 -2
  21. package/core/audits/insights/insight-audit.js +16 -6
  22. package/core/audits/layout-shifts.js +1 -1
  23. package/core/audits/server-response-time.js +3 -3
  24. package/core/audits/webmcp-form-coverage.d.ts +16 -0
  25. package/core/audits/webmcp-form-coverage.js +90 -0
  26. package/core/audits/webmcp-registered-tools.d.ts +21 -0
  27. package/core/audits/webmcp-registered-tools.js +149 -0
  28. package/core/audits/webmcp-schema-validity.d.ts +22 -0
  29. package/core/audits/webmcp-schema-validity.js +141 -0
  30. package/core/computed/document-urls.js +4 -2
  31. package/core/computed/main-resource.js +5 -3
  32. package/core/computed/metrics/lantern-metric.js +4 -4
  33. package/core/computed/metrics/lcp-breakdown.js +1 -1
  34. package/core/computed/metrics/time-to-first-byte.js +1 -1
  35. package/core/computed/navigation-insights.js +2 -1
  36. package/core/computed/network-analysis.js +3 -1
  37. package/core/config/agentic-browsing-config.d.ts +12 -0
  38. package/core/config/agentic-browsing-config.js +73 -0
  39. package/core/config/default-config.js +8 -0
  40. package/core/gather/driver/wait-for-condition.js +11 -1
  41. package/core/gather/gatherers/accessibility.js +5 -1
  42. package/core/gather/gatherers/agentic/llms-txt.d.ts +10 -0
  43. package/core/gather/gatherers/agentic/llms-txt.js +28 -0
  44. package/core/gather/gatherers/inputs.js +2 -0
  45. package/core/gather/gatherers/meta-elements.js +1 -1
  46. package/core/gather/gatherers/trace-elements.js +1 -1
  47. package/core/gather/gatherers/trace.js +3 -0
  48. package/core/gather/gatherers/webmcp-schema.d.ts +25 -0
  49. package/core/gather/gatherers/webmcp-schema.js +105 -0
  50. package/core/gather/gatherers/webmcp.d.ts +58 -0
  51. package/core/gather/gatherers/webmcp.js +159 -0
  52. package/core/index.d.ts +1 -0
  53. package/core/index.js +1 -0
  54. package/core/lib/baseline/web-features-metadata.json +3 -0
  55. package/core/lib/cdt/generated/SourceMap.js +2 -2
  56. package/core/lib/deprecations-strings.d.ts +169 -89
  57. package/core/lib/deprecations-strings.js +119 -24
  58. package/core/lib/navigation-error.js +5 -2
  59. package/core/lib/network-recorder.js +2 -1
  60. package/core/lib/page-functions.d.ts +3 -3
  61. package/core/lib/page-functions.js +11 -4
  62. package/core/lib/tracehouse/trace-processor.d.ts +5 -4
  63. package/core/lib/tracehouse/trace-processor.js +85 -19
  64. package/core/runner.js +3 -0
  65. package/core/scoring.d.ts +25 -0
  66. package/dist/report/bundle.esm.js +31 -3
  67. package/dist/report/flow.js +32 -4
  68. package/dist/report/standalone.js +32 -4
  69. package/flow-report/src/summary/category.tsx +1 -1
  70. package/package.json +12 -11
  71. package/report/assets/styles.css +28 -0
  72. package/report/renderer/category-renderer.js +1 -1
  73. package/report/renderer/components.js +1 -1
  74. package/report/renderer/details-renderer.d.ts +5 -0
  75. package/report/renderer/details-renderer.js +16 -0
  76. package/report/renderer/report-utils.d.ts +2 -1
  77. package/report/renderer/report-utils.js +7 -2
  78. package/report/types/report-renderer.d.ts +1 -1
  79. package/report/types/report-result.d.ts +1 -1
  80. package/shared/localization/locales/ar-XB.json +72 -36
  81. package/shared/localization/locales/ar.json +72 -36
  82. package/shared/localization/locales/bg.json +72 -36
  83. package/shared/localization/locales/ca.json +72 -36
  84. package/shared/localization/locales/cs.json +72 -36
  85. package/shared/localization/locales/da.json +74 -38
  86. package/shared/localization/locales/de.json +72 -36
  87. package/shared/localization/locales/el.json +73 -37
  88. package/shared/localization/locales/en-GB.json +74 -38
  89. package/shared/localization/locales/en-US.json +257 -17
  90. package/shared/localization/locales/en-XL.json +257 -17
  91. package/shared/localization/locales/es-419.json +72 -36
  92. package/shared/localization/locales/es.json +73 -37
  93. package/shared/localization/locales/fi.json +72 -36
  94. package/shared/localization/locales/fil.json +74 -38
  95. package/shared/localization/locales/fr.json +162 -126
  96. package/shared/localization/locales/he.json +74 -38
  97. package/shared/localization/locales/hi.json +73 -37
  98. package/shared/localization/locales/hr.json +72 -36
  99. package/shared/localization/locales/hu.json +73 -37
  100. package/shared/localization/locales/id.json +74 -38
  101. package/shared/localization/locales/it.json +72 -36
  102. package/shared/localization/locales/ja.json +72 -36
  103. package/shared/localization/locales/ko.json +72 -36
  104. package/shared/localization/locales/lt.json +72 -36
  105. package/shared/localization/locales/lv.json +72 -36
  106. package/shared/localization/locales/nl.json +73 -37
  107. package/shared/localization/locales/no.json +72 -36
  108. package/shared/localization/locales/pl.json +72 -36
  109. package/shared/localization/locales/pt-PT.json +72 -36
  110. package/shared/localization/locales/pt.json +74 -38
  111. package/shared/localization/locales/ro.json +72 -36
  112. package/shared/localization/locales/ru.json +72 -36
  113. package/shared/localization/locales/sk.json +72 -36
  114. package/shared/localization/locales/sl.json +72 -36
  115. package/shared/localization/locales/sr-Latn.json +73 -37
  116. package/shared/localization/locales/sr.json +73 -37
  117. package/shared/localization/locales/sv.json +75 -39
  118. package/shared/localization/locales/ta.json +73 -37
  119. package/shared/localization/locales/te.json +72 -36
  120. package/shared/localization/locales/th.json +73 -37
  121. package/shared/localization/locales/tr.json +72 -36
  122. package/shared/localization/locales/uk.json +72 -36
  123. package/shared/localization/locales/vi.json +74 -38
  124. package/shared/localization/locales/zh-HK.json +72 -36
  125. package/shared/localization/locales/zh-TW.json +74 -38
  126. package/shared/localization/locales/zh.json +75 -39
  127. package/tsconfig.json +2 -0
  128. package/types/artifacts.d.ts +66 -30
  129. package/types/audit.d.ts +1 -1
  130. package/types/config.d.ts +2 -1
  131. package/types/gatherer.d.ts +1 -1
  132. package/types/lhr/audit-details.d.ts +10 -4
  133. package/types/lhr/flow-result.d.ts +1 -1
  134. package/types/lhr/lhr.d.ts +12 -1
  135. package/types/lhr/treemap.d.ts +1 -1
  136. package/types/protocol.d.ts +1 -1
  137. package/types/puppeteer.d.ts +1 -1
  138. package/types/user-flow.d.ts +1 -1
  139. package/types/utility-types.d.ts +1 -1
package/CONTRIBUTING.md CHANGED
@@ -8,7 +8,7 @@ We tag issues that are good candidates for those new to the code with [`good fir
8
8
 
9
9
  ## Follow the coding style
10
10
 
11
- The `.eslintrc.cjs` file defines all. We use [JSDoc](http://usejsdoc.org/) with [TypeScript `checkJs`](https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#supported-jsdoc). Annotations are encouraged for all contributions.
11
+ The `.eslintrc.cjs` file defines all. We use [JSDoc](https://jsdoc.app/) with [TypeScript `checkJs`](https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#supported-jsdoc). Annotations are encouraged for all contributions.
12
12
 
13
13
  ## Learn about the architecture
14
14
 
package/cli/bin.js CHANGED
@@ -107,6 +107,11 @@ async function begin() {
107
107
  cliFlags.precomputedLanternData = data;
108
108
  }
109
109
 
110
+ if (!Array.isArray(cliFlags.chromeFlags)) {
111
+ cliFlags.chromeFlags = [cliFlags.chromeFlags];
112
+ }
113
+ cliFlags.chromeFlags.push('--enable-features=DevToolsWebMCPSupport');
114
+
110
115
  // By default, cliFlags.enableErrorReporting is undefined so the user is
111
116
  // prompted. This can be overridden with an explicit flag or by the cached
112
117
  // answer returned by askPermission().
@@ -3,7 +3,7 @@
3
3
  exports[`getAssertionReport works (multiple failing) 1`] = `
4
4
  "X difference at cumulative-layout-shift audit.details.items.length
5
5
  expected: []
6
- found: [{\\"cumulativeLayoutShiftMainFrame\\":0.09957584751767748,\\"newEngineResult\\":{\\"cumulativeLayoutShift\\":0.09957584751767748,\\"cumulativeLayoutShiftMainFrame\\":0.09957584751767748},\\"newEngineResultDiffered\\":false}]
6
+ found: [{\\"cumulativeLayoutShiftMainFrame\\":0.099576,\\"newEngineResult\\":{\\"cumulativeLayoutShift\\":0.099576,\\"cumulativeLayoutShiftMainFrame\\":0.099576},\\"newEngineResultDiffered\\":false}]
7
7
 
8
8
 
9
9
  X difference at cumulative-layout-shift audit.details.blah
@@ -17,7 +17,7 @@ exports[`getAssertionReport works (multiple failing) 1`] = `
17
17
  \\"description\\": \\"Cumulative Layout Shift measures the movement of visible elements within the viewport. [Learn more about the Cumulative Layout Shift metric](https://web.dev/articles/cls).\\",
18
18
  \\"score\\": 0.9,
19
19
  \\"scoreDisplayMode\\": \\"numeric\\",
20
- \\"numericValue\\": 0.09957584751767748,
20
+ \\"numericValue\\": 0.099576,
21
21
  \\"numericUnit\\": \\"unitless\\",
22
22
  \\"displayValue\\": \\"0.1\\",
23
23
  \\"scoringOptions\\": {
@@ -28,10 +28,10 @@ exports[`getAssertionReport works (multiple failing) 1`] = `
28
28
  \\"type\\": \\"debugdata\\",
29
29
  \\"items\\": [
30
30
  {
31
- \\"cumulativeLayoutShiftMainFrame\\": 0.09957584751767748,
31
+ \\"cumulativeLayoutShiftMainFrame\\": 0.099576,
32
32
  \\"newEngineResult\\": {
33
- \\"cumulativeLayoutShift\\": 0.09957584751767748,
34
- \\"cumulativeLayoutShiftMainFrame\\": 0.09957584751767748
33
+ \\"cumulativeLayoutShift\\": 0.099576,
34
+ \\"cumulativeLayoutShiftMainFrame\\": 0.099576
35
35
  },
36
36
  \\"newEngineResultDiffered\\": false
37
37
  }
@@ -43,7 +43,7 @@ exports[`getAssertionReport works (multiple failing) 1`] = `
43
43
  exports[`getAssertionReport works (trivial failing) 1`] = `
44
44
  "X difference at cumulative-layout-shift audit.details.items.length
45
45
  expected: []
46
- found: [{\\"cumulativeLayoutShiftMainFrame\\":0.09957584751767748,\\"newEngineResult\\":{\\"cumulativeLayoutShift\\":0.09957584751767748,\\"cumulativeLayoutShiftMainFrame\\":0.09957584751767748},\\"newEngineResultDiffered\\":false}]
46
+ found: [{\\"cumulativeLayoutShiftMainFrame\\":0.099576,\\"newEngineResult\\":{\\"cumulativeLayoutShift\\":0.099576,\\"cumulativeLayoutShiftMainFrame\\":0.099576},\\"newEngineResultDiffered\\":false}]
47
47
 
48
48
  found result:
49
49
  {
@@ -52,7 +52,7 @@ exports[`getAssertionReport works (trivial failing) 1`] = `
52
52
  \\"description\\": \\"Cumulative Layout Shift measures the movement of visible elements within the viewport. [Learn more about the Cumulative Layout Shift metric](https://web.dev/articles/cls).\\",
53
53
  \\"score\\": 0.9,
54
54
  \\"scoreDisplayMode\\": \\"numeric\\",
55
- \\"numericValue\\": 0.09957584751767748,
55
+ \\"numericValue\\": 0.099576,
56
56
  \\"numericUnit\\": \\"unitless\\",
57
57
  \\"displayValue\\": \\"0.1\\",
58
58
  \\"scoringOptions\\": {
@@ -63,10 +63,10 @@ exports[`getAssertionReport works (trivial failing) 1`] = `
63
63
  \\"type\\": \\"debugdata\\",
64
64
  \\"items\\": [
65
65
  {
66
- \\"cumulativeLayoutShiftMainFrame\\": 0.09957584751767748,
66
+ \\"cumulativeLayoutShiftMainFrame\\": 0.099576,
67
67
  \\"newEngineResult\\": {
68
- \\"cumulativeLayoutShift\\": 0.09957584751767748,
69
- \\"cumulativeLayoutShiftMainFrame\\": 0.09957584751767748
68
+ \\"cumulativeLayoutShift\\": 0.099576,
69
+ \\"cumulativeLayoutShiftMainFrame\\": 0.099576
70
70
  },
71
71
  \\"newEngineResultDiffered\\": false
72
72
  }
@@ -31,6 +31,50 @@ const exclusions = {
31
31
  // Disabled because is timing out.
32
32
  'oopif-scripts',
33
33
  ],
34
+ 'devtools-mcp': [
35
+ // Disabled because performance tracing related audits are not supported.
36
+ 'byte-efficiency',
37
+ 'byte-gzip',
38
+ 'dbw',
39
+ 'errors-expired-ssl',
40
+ 'errors-iframe-expired-ssl',
41
+ 'errors-infinite-loop',
42
+ 'forms-autocomplete',
43
+ 'fps-max-passive',
44
+ 'fps-max',
45
+ 'fps-overflow-x',
46
+ 'lantern-fetch',
47
+ 'lantern-idle-callback-long',
48
+ 'lantern-idle-callback-short',
49
+ 'lantern-online',
50
+ 'lantern-set-timeout',
51
+ 'lantern-xhr',
52
+ 'legacy-javascript',
53
+ 'metrics-debugger',
54
+ 'metrics-delayed-fcp',
55
+ 'metrics-delayed-lcp',
56
+ 'metrics-tricky-tti-late-fcp',
57
+ 'metrics-tricky-tti',
58
+ 'oopif-requests',
59
+ 'oopif-scripts',
60
+ 'perf-debug',
61
+ 'perf-diagnostics-animations',
62
+ 'perf-diagnostics-unsized-images',
63
+ 'perf-fonts',
64
+ 'perf-frame-metrics',
65
+ 'perf-preload',
66
+ 'perf-trace-elements',
67
+ 'redirects-client-paint-server',
68
+ 'redirects-history-push-state',
69
+ 'redirects-multiple-server',
70
+ 'redirects-scripts',
71
+ 'redirects-single-client',
72
+ 'redirects-single-server',
73
+ 'screenshot',
74
+ 'shift-attribution',
75
+ 'source-maps',
76
+ 'timing',
77
+ ],
34
78
  };
35
79
 
36
80
  for (const array of Object.values(exclusions)) {
@@ -33,9 +33,10 @@ const coreTestDefnsPath =
33
33
  * contingent on having built all the bundles.
34
34
  */
35
35
  const runnerPaths = {
36
- cli: '../lighthouse-runners/cli.js',
37
- bundle: '../lighthouse-runners/bundle.js',
38
- devtools: '../lighthouse-runners/devtools.js',
36
+ 'cli': '../lighthouse-runners/cli.js',
37
+ 'bundle': '../lighthouse-runners/bundle.js',
38
+ 'devtools': '../lighthouse-runners/devtools.js',
39
+ 'devtools-mcp': '../lighthouse-runners/devtools-mcp.js',
39
40
  };
40
41
 
41
42
  /**
@@ -146,7 +147,7 @@ async function begin() {
146
147
  },
147
148
  'runner': {
148
149
  default: 'cli',
149
- choices: ['cli', 'bundle', 'devtools'],
150
+ choices: ['cli', 'bundle', 'devtools', 'devtools-mcp'],
150
151
  describe: 'The method of running Lighthouse',
151
152
  },
152
153
  'tests-path': {
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Launch Chrome and do a full Lighthouse run via the Lighthouse DevTools MCP bundle.
3
+ * @param {string} url
4
+ * @param {LH.Config=} config
5
+ * @param {LocalConsole=} logger
6
+ * @param {Smokehouse.SmokehouseOptions['testRunnerOptions']=} testRunnerOptions
7
+ * @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts}>}
8
+ */
9
+ export function runLighthouse(url: string, config?: LH.Config | undefined, logger?: LocalConsole | undefined, testRunnerOptions?: Smokehouse.SmokehouseOptions["testRunnerOptions"] | undefined): Promise<{
10
+ lhr: LH.Result;
11
+ artifacts: LH.Artifacts;
12
+ }>;
13
+ import { LocalConsole } from '../lib/local-console.js';
14
+ //# sourceMappingURL=devtools-mcp.d.ts.map
@@ -0,0 +1,141 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ /**
8
+ * @fileoverview A runner that launches Chrome and executes Lighthouse via the
9
+ * DevTools MCP bundle.
10
+ */
11
+
12
+ import fs from 'fs';
13
+ import os from 'os';
14
+ import {Worker, isMainThread, parentPort, workerData} from 'worker_threads';
15
+ import {once} from 'events';
16
+
17
+ import puppeteer from 'puppeteer-core';
18
+ import * as ChromeLauncher from 'chrome-launcher';
19
+
20
+ import {LH_ROOT} from '../../../../shared/root.js';
21
+ import {loadArtifacts, saveArtifacts} from '../../../../core/lib/asset-saver.js';
22
+ import {LocalConsole} from '../lib/local-console.js';
23
+
24
+ // This runs only in the worker. The rest runs on the main thread.
25
+ if (!isMainThread && parentPort) {
26
+ (async () => {
27
+ const {url, config, testRunnerOptions} = workerData;
28
+ try {
29
+ const result = await runBundledLighthouse(url, config, testRunnerOptions);
30
+ // Save to assets directory because LighthouseError won't survive postMessage.
31
+ const assetsDir = fs.mkdtempSync(os.tmpdir() + '/smoke-mcp-assets-');
32
+ await saveArtifacts(result.artifacts, assetsDir);
33
+ const value = {
34
+ lhr: result.lhr,
35
+ assetsDir,
36
+ };
37
+ parentPort?.postMessage({type: 'result', value});
38
+ } catch (err) {
39
+ console.error(err);
40
+ parentPort?.postMessage({type: 'error', value: err.toString()});
41
+ }
42
+ })();
43
+ }
44
+
45
+ /**
46
+ * @param {string} url
47
+ * @param {LH.Config|undefined} config
48
+ * @param {Smokehouse.SmokehouseOptions['testRunnerOptions']} testRunnerOptions
49
+ * @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts}>}
50
+ */
51
+ async function runBundledLighthouse(url, config, testRunnerOptions) {
52
+ if (isMainThread || !parentPort) {
53
+ throw new Error('must be called in worker');
54
+ }
55
+
56
+ // Load bundle.
57
+ const {navigation} = await import(LH_ROOT + '/dist/lighthouse-devtools-mcp-bundle.js');
58
+
59
+ // Launch and connect to Chrome.
60
+ const launchedChrome = await ChromeLauncher.launch({
61
+ chromeFlags: [
62
+ testRunnerOptions?.headless ? '--headless=new' : '',
63
+ ],
64
+ });
65
+ const port = launchedChrome.port;
66
+
67
+ // Run Lighthouse.
68
+ try {
69
+ const logLevel = testRunnerOptions?.isDebug ? 'verbose' : 'info';
70
+
71
+ // Puppeteer is not included in the bundle, we must create the page here.
72
+ const browser = await puppeteer.connect({browserURL: `http://127.0.0.1:${port}`});
73
+ const page = await browser.newPage();
74
+
75
+ // navigation(page, requestor, options)
76
+ const runnerResult = await navigation(page, url, {config, flags: {port, logLevel}});
77
+
78
+ if (!runnerResult) throw new Error('No runnerResult');
79
+
80
+ return {
81
+ lhr: runnerResult.lhr,
82
+ artifacts: runnerResult.artifacts,
83
+ };
84
+ } finally {
85
+ // Clean up and return results.
86
+ launchedChrome.kill();
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Launch Chrome and do a full Lighthouse run via the Lighthouse DevTools MCP bundle.
92
+ * @param {string} url
93
+ * @param {LH.Config=} config
94
+ * @param {LocalConsole=} logger
95
+ * @param {Smokehouse.SmokehouseOptions['testRunnerOptions']=} testRunnerOptions
96
+ * @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts}>}
97
+ */
98
+ async function runLighthouse(url, config, logger, testRunnerOptions = {}) {
99
+ logger = logger || new LocalConsole();
100
+
101
+ const worker = new Worker(new URL(import.meta.url), {
102
+ stdout: true,
103
+ stderr: true,
104
+ workerData: {url, config, testRunnerOptions},
105
+ });
106
+ worker.stdout.setEncoding('utf8');
107
+ worker.stderr.setEncoding('utf8');
108
+ worker.stdout.addListener('data', (data) => {
109
+ logger.log(`[STDOUT] ${data}`);
110
+ });
111
+ worker.stderr.addListener('data', (data) => {
112
+ logger.log(`[STDERR] ${data}`);
113
+ });
114
+ const [workerResponse] = await once(worker, 'message');
115
+
116
+ if (workerResponse.type === 'error') {
117
+ const log = logger.getLog();
118
+ throw new Error(`Worker returned an error: ${workerResponse.value}
119
+ Log:
120
+ ${log}
121
+ `);
122
+ }
123
+
124
+ const result = workerResponse.value;
125
+ if (!result.lhr || !result.assetsDir) {
126
+ throw new Error(`invalid response from worker:
127
+ ${JSON.stringify(result, null, 2)}`);
128
+ }
129
+
130
+ const artifacts = loadArtifacts(result.assetsDir);
131
+ fs.rmSync(result.assetsDir, {recursive: true});
132
+
133
+ return {
134
+ lhr: result.lhr,
135
+ artifacts,
136
+ };
137
+ }
138
+
139
+ export {
140
+ runLighthouse,
141
+ };
@@ -0,0 +1,10 @@
1
+ export default AutocompleteValid;
2
+ declare class AutocompleteValid extends AxeAudit {
3
+ }
4
+ export namespace UIStrings {
5
+ let title: string;
6
+ let failureTitle: string;
7
+ let description: string;
8
+ }
9
+ import AxeAudit from './axe-audit.js';
10
+ //# sourceMappingURL=autocomplete-valid.d.ts.map
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ /**
8
+ * @fileoverview Ensures the autocomplete attribute is correct and suitable for the form field.
9
+ * See base class in axe-audit.js for audit() implementation.
10
+ */
11
+
12
+ import AxeAudit from './axe-audit.js';
13
+ import * as i18n from '../../lib/i18n/i18n.js';
14
+
15
+ const UIStrings = {
16
+ /** Title of an accessibility audit that evaluates if all form fields have valid autocomplete attributes. This title is descriptive of the successful state and is shown to users when no user action is required. */
17
+ title: '`autocomplete` attributes are used correctly',
18
+ /** Title of an accessibility audit that evaluates if all form fields have valid autocomplete attributes. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
19
+ failureTitle: '`autocomplete` attributes are not used correctly',
20
+ /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
21
+ description: 'The `autocomplete` attribute values must be valid and correctly applied for ' +
22
+ 'screen readers to function correctly. ' +
23
+ '[Learn more about valid autocomplete values](https://dequeuniversity.com/rules/axe/4.11/autocomplete-valid).',
24
+ };
25
+
26
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
27
+
28
+ class AutocompleteValid extends AxeAudit {
29
+ /**
30
+ * @return {LH.Audit.Meta}
31
+ */
32
+ static get meta() {
33
+ return {
34
+ id: 'autocomplete-valid',
35
+ title: str_(UIStrings.title),
36
+ failureTitle: str_(UIStrings.failureTitle),
37
+ description: str_(UIStrings.description),
38
+ requiredArtifacts: ['Accessibility'],
39
+ };
40
+ }
41
+ }
42
+
43
+ export default AutocompleteValid;
44
+ export {UIStrings};
@@ -0,0 +1,10 @@
1
+ export default PresentationRoleConflict;
2
+ declare class PresentationRoleConflict extends AxeAudit {
3
+ }
4
+ export namespace UIStrings {
5
+ let title: string;
6
+ let failureTitle: string;
7
+ let description: string;
8
+ }
9
+ import AxeAudit from './axe-audit.js';
10
+ //# sourceMappingURL=presentation-role-conflict.d.ts.map
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ /**
8
+ * @fileoverview Ensures elements which are marked to be removed from the accessibility tree are in fact removed.
9
+ * See base class in axe-audit.js for audit() implementation.
10
+ */
11
+
12
+ import AxeAudit from './axe-audit.js';
13
+ import * as i18n from '../../lib/i18n/i18n.js';
14
+
15
+ const UIStrings = {
16
+ /** Title of an accessibility audit that evaluates if elements with presentation role have conflicts. This title is descriptive of the successful state and is shown to users when no user action is required. */
17
+ title: 'Elements with `role="none"` or `role="presentation"` do not have conflicts',
18
+ /** Title of an accessibility audit that evaluates if elements with presentation role have conflicts. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
19
+ failureTitle: 'Elements with `role="none"` or `role="presentation"` have conflicts',
20
+ /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with \'Learn\' becomes link text to additional documentation. */
21
+ description: 'There are certain cases where the semantic role of an element with `role="none"` ' +
22
+ 'or `role="presentation"` does not resolve to none or presentation. To ensure the ' +
23
+ 'element remains removed from the accessibility tree, you should not add any global ' +
24
+ 'ARIA attributes to the element or make it focusable. ' +
25
+ '[Learn more about presentation role conflict](https://dequeuniversity.com/rules/axe/4.11/presentation-role-conflict).',
26
+ };
27
+
28
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
29
+
30
+ class PresentationRoleConflict extends AxeAudit {
31
+ /**
32
+ * @return {LH.Audit.Meta}
33
+ */
34
+ static get meta() {
35
+ return {
36
+ id: 'presentation-role-conflict',
37
+ title: str_(UIStrings.title),
38
+ failureTitle: str_(UIStrings.failureTitle),
39
+ description: str_(UIStrings.description),
40
+ requiredArtifacts: ['Accessibility'],
41
+ };
42
+ }
43
+ }
44
+
45
+ export default PresentationRoleConflict;
46
+ export {UIStrings};
@@ -0,0 +1,10 @@
1
+ export default SvgImgAlt;
2
+ declare class SvgImgAlt extends AxeAudit {
3
+ }
4
+ export namespace UIStrings {
5
+ let title: string;
6
+ let failureTitle: string;
7
+ let description: string;
8
+ }
9
+ import AxeAudit from './axe-audit.js';
10
+ //# sourceMappingURL=svg-img-alt.d.ts.map
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ /**
8
+ * @fileoverview Ensures SVG elements with an img role have an accessible text alternative.
9
+ * See base class in axe-audit.js for audit() implementation.
10
+ */
11
+
12
+ import AxeAudit from './axe-audit.js';
13
+ import * as i18n from '../../lib/i18n/i18n.js';
14
+
15
+ const UIStrings = {
16
+ /** Title of an accessibility audit that evaluates if SVG elements with an img role have an accessible text alternative. This title is descriptive of the successful state and is shown to users when no user action is required. */
17
+ title: 'SVG elements with an `img` role have an accessible text alternative',
18
+ /** Title of an accessibility audit that evaluates if SVG elements with an img role have an accessible text alternative. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
19
+ failureTitle: 'SVG elements with an `img` role do not have an accessible text alternative',
20
+ /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with \'Learn\' becomes link text to additional documentation. */
21
+ description: 'Ensures SVG elements with an `img`, `graphics-document` or `graphics-symbol` ' +
22
+ 'role have an accessible text alternative. ' +
23
+ '[Learn more about SVG alt text](https://dequeuniversity.com/rules/axe/4.11/svg-img-alt).',
24
+ };
25
+
26
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
27
+
28
+ class SvgImgAlt extends AxeAudit {
29
+ /**
30
+ * @return {LH.Audit.Meta}
31
+ */
32
+ static get meta() {
33
+ return {
34
+ id: 'svg-img-alt',
35
+ title: str_(UIStrings.title),
36
+ failureTitle: str_(UIStrings.failureTitle),
37
+ description: str_(UIStrings.description),
38
+ requiredArtifacts: ['Accessibility'],
39
+ };
40
+ }
41
+ }
42
+
43
+ export default SvgImgAlt;
44
+ export {UIStrings};
@@ -0,0 +1,19 @@
1
+ export default AgentAccessibilityTree;
2
+ declare class AgentAccessibilityTree extends Audit {
3
+ /**
4
+ * @param {LH.Artifacts} artifacts
5
+ * @return {LH.Audit.Product}
6
+ */
7
+ static audit(artifacts: LH.Artifacts): LH.Audit.Product;
8
+ }
9
+ export namespace UIStrings {
10
+ let title: string;
11
+ let failureTitle: string;
12
+ let description: string;
13
+ let columnRule: string;
14
+ let columnElement: string;
15
+ let failedSectionTitle: string;
16
+ let displayValuePassed: string;
17
+ }
18
+ import { Audit } from '../audit.js';
19
+ //# sourceMappingURL=agent-accessibility-tree.d.ts.map
@@ -0,0 +1,115 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import {Audit} from '../audit.js';
8
+ import * as i18n from '../../lib/i18n/i18n.js';
9
+
10
+ const UIStrings = {
11
+ /** Title shown when all agent accessibility checks pass. */
12
+ title: 'Accessibility tree is well-formed',
13
+ /** Title shown when one or more agent accessibility checks fail. */
14
+ failureTitle: 'Accessibility tree is not well-formed',
15
+ /** Description of a Lighthouse audit that tells the user *why* they need a well-formed accessibility tree. */
16
+ description: 'A well-formed accessibility tree helps AI agents to ' +
17
+ 'navigate and interact with the page.',
18
+ /** Label of a table column that identifies the accessibility rule that failed. */
19
+ columnRule: 'Failing Rule',
20
+ /** Label of a table column that identifies the HTML element that failed the rule. */
21
+ columnElement: 'Failing Element',
22
+ /** Title of the section containing failed accessibility checks. */
23
+ failedSectionTitle: 'Failed Audits',
24
+ /** Message shown when all accessibility checks pass. */
25
+ displayValuePassed: 'All audits passed',
26
+ };
27
+
28
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
29
+
30
+ const TARGET_RULES = new Set([
31
+ 'button-name',
32
+ 'input-button-name',
33
+ 'input-image-alt',
34
+ 'label',
35
+ 'link-name',
36
+ 'select-name',
37
+ 'document-title',
38
+ 'aria-allowed-attr',
39
+ 'aria-allowed-role',
40
+ 'aria-command-name',
41
+ 'aria-conditional-attr',
42
+ 'aria-dialog-name',
43
+ 'aria-hidden-body',
44
+ 'aria-hidden-focus',
45
+ 'aria-input-field-name',
46
+ 'aria-prohibited-attr',
47
+ 'aria-required-attr',
48
+ 'aria-required-children',
49
+ 'aria-required-parent',
50
+ 'aria-roles',
51
+ 'aria-text',
52
+ 'aria-toggle-field-name',
53
+ 'aria-tooltip-name',
54
+ 'aria-treeitem-name',
55
+ 'aria-valid-attr',
56
+ 'aria-valid-attr-value',
57
+ 'duplicate-id-aria',
58
+ 'definition-list',
59
+ 'table-duplicate-name',
60
+ 'tabindex',
61
+ 'autocomplete-valid',
62
+ 'presentation-role-conflict',
63
+ 'svg-img-alt',
64
+ ]);
65
+
66
+ class AgentAccessibilityTree extends Audit {
67
+ /**
68
+ * @return {LH.Audit.Meta}
69
+ */
70
+ static get meta() {
71
+ return {
72
+ id: 'agent-accessibility-tree',
73
+ title: str_(UIStrings.title),
74
+ failureTitle: str_(UIStrings.failureTitle),
75
+ description: str_(UIStrings.description),
76
+ requiredArtifacts: ['Accessibility'],
77
+ };
78
+ }
79
+
80
+ /**
81
+ * @param {LH.Artifacts} artifacts
82
+ * @return {LH.Audit.Product}
83
+ */
84
+ static audit(artifacts) {
85
+ const violations = (artifacts.Accessibility && artifacts.Accessibility.violations) || [];
86
+ const failedRules = violations.filter(v => TARGET_RULES.has(v.id));
87
+
88
+ /** @type {LH.Audit.Details.Table['headings']} */
89
+ const headings = [
90
+ {key: 'description', valueType: 'text', label: str_(i18n.UIStrings.columnDescription)},
91
+ {key: 'node', valueType: 'node', label: str_(UIStrings.columnElement)},
92
+ ];
93
+
94
+ const items = failedRules.map(rule => ({
95
+ description: rule.help || rule.description,
96
+ node: rule.nodes?.[0] ? Audit.makeNodeItem(rule.nodes[0].node) : undefined,
97
+ }));
98
+
99
+ const listItems = [];
100
+
101
+ if (items.length > 0) {
102
+ const table = Audit.makeTableDetails(headings, items);
103
+ listItems.push(Audit.makeListDetailSectionItem(table, str_(UIStrings.failedSectionTitle)));
104
+ }
105
+
106
+ return {
107
+ score: Number(items.length === 0),
108
+ details: listItems.length > 0 ? Audit.makeListDetails(listItems) : undefined,
109
+ displayValue: items.length === 0 ? str_(UIStrings.displayValuePassed) : undefined,
110
+ };
111
+ }
112
+ }
113
+
114
+ export default AgentAccessibilityTree;
115
+ export {UIStrings};
@@ -0,0 +1,20 @@
1
+ export default LlmsTxt;
2
+ declare class LlmsTxt extends Audit {
3
+ /**
4
+ * @param {LH.Artifacts} artifacts
5
+ * @return {LH.Audit.Product}
6
+ */
7
+ static audit(artifacts: LH.Artifacts): LH.Audit.Product;
8
+ }
9
+ export namespace UIStrings {
10
+ let title: string;
11
+ let failureTitle: string;
12
+ let description: string;
13
+ let displayValueHttpBadCode: string;
14
+ let explanation: string;
15
+ let missingH1: string;
16
+ let tooShort: string;
17
+ let missingLinks: string;
18
+ }
19
+ import { Audit } from '../audit.js';
20
+ //# sourceMappingURL=llms-txt.d.ts.map