@navinjoseph/web-perf-core 1.0.0-beta.3

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 (77) hide show
  1. package/dist/audits/accessibility.d.ts +10 -0
  2. package/dist/audits/accessibility.d.ts.map +1 -0
  3. package/dist/audits/accessibility.js +258 -0
  4. package/dist/audits/accessibility.js.map +1 -0
  5. package/dist/audits/best-practices.d.ts +10 -0
  6. package/dist/audits/best-practices.d.ts.map +1 -0
  7. package/dist/audits/best-practices.js +696 -0
  8. package/dist/audits/best-practices.js.map +1 -0
  9. package/dist/audits/constants.d.ts +8 -0
  10. package/dist/audits/constants.d.ts.map +1 -0
  11. package/dist/audits/constants.js +278 -0
  12. package/dist/audits/constants.js.map +1 -0
  13. package/dist/audits/performance.d.ts +11 -0
  14. package/dist/audits/performance.d.ts.map +1 -0
  15. package/dist/audits/performance.js +497 -0
  16. package/dist/audits/performance.js.map +1 -0
  17. package/dist/audits/pwa.d.ts +10 -0
  18. package/dist/audits/pwa.d.ts.map +1 -0
  19. package/dist/audits/pwa.js +396 -0
  20. package/dist/audits/pwa.js.map +1 -0
  21. package/dist/audits/security.d.ts +10 -0
  22. package/dist/audits/security.d.ts.map +1 -0
  23. package/dist/audits/security.js +249 -0
  24. package/dist/audits/security.js.map +1 -0
  25. package/dist/audits/seo.d.ts +10 -0
  26. package/dist/audits/seo.d.ts.map +1 -0
  27. package/dist/audits/seo.js +471 -0
  28. package/dist/audits/seo.js.map +1 -0
  29. package/dist/browser.d.ts +21 -0
  30. package/dist/browser.d.ts.map +1 -0
  31. package/dist/browser.js +178 -0
  32. package/dist/browser.js.map +1 -0
  33. package/dist/dom-collector.d.ts +45 -0
  34. package/dist/dom-collector.d.ts.map +1 -0
  35. package/dist/dom-collector.js +173 -0
  36. package/dist/dom-collector.js.map +1 -0
  37. package/dist/formatter.d.ts +60 -0
  38. package/dist/formatter.d.ts.map +1 -0
  39. package/dist/formatter.js +164 -0
  40. package/dist/formatter.js.map +1 -0
  41. package/dist/id-generator.d.ts +22 -0
  42. package/dist/id-generator.d.ts.map +1 -0
  43. package/dist/id-generator.js +29 -0
  44. package/dist/id-generator.js.map +1 -0
  45. package/dist/index.d.ts +17 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +23 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/orchestrator.d.ts +41 -0
  50. package/dist/orchestrator.d.ts.map +1 -0
  51. package/dist/orchestrator.js +194 -0
  52. package/dist/orchestrator.js.map +1 -0
  53. package/dist/reporters/html.d.ts +6 -0
  54. package/dist/reporters/html.d.ts.map +1 -0
  55. package/dist/reporters/html.js +688 -0
  56. package/dist/reporters/html.js.map +1 -0
  57. package/dist/reporters/index.d.ts +4 -0
  58. package/dist/reporters/index.d.ts.map +1 -0
  59. package/dist/reporters/index.js +17 -0
  60. package/dist/reporters/index.js.map +1 -0
  61. package/dist/reporters/json.d.ts +6 -0
  62. package/dist/reporters/json.d.ts.map +1 -0
  63. package/dist/reporters/json.js +7 -0
  64. package/dist/reporters/json.js.map +1 -0
  65. package/dist/reporters/terminal.d.ts +6 -0
  66. package/dist/reporters/terminal.d.ts.map +1 -0
  67. package/dist/reporters/terminal.js +180 -0
  68. package/dist/reporters/terminal.js.map +1 -0
  69. package/dist/reporters/types.d.ts +2 -0
  70. package/dist/reporters/types.d.ts.map +1 -0
  71. package/dist/reporters/types.js +2 -0
  72. package/dist/reporters/types.js.map +1 -0
  73. package/dist/types.d.ts +80 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/types.js +36 -0
  76. package/dist/types.js.map +1 -0
  77. package/package.json +54 -0
@@ -0,0 +1,178 @@
1
+ import { JSDOM, VirtualConsole } from "jsdom";
2
+ import fetch from "node-fetch";
3
+ /**
4
+ * Load a URL using jsdom with Shadow DOM support
5
+ */
6
+ export async function loadPage(url, options = {}) {
7
+ const timeout = options.timeout || 10000; // 10 second default
8
+ const maxSize = options.maxSize || 10_000_000; // 10MB default
9
+ try {
10
+ // Create abort controller for timeout
11
+ const controller = new AbortController();
12
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
13
+ const response = await fetch(url, {
14
+ headers: {
15
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
16
+ },
17
+ signal: controller.signal,
18
+ });
19
+ clearTimeout(timeoutId);
20
+ if (!response.ok) {
21
+ throw new Error(`Failed to fetch ${url}: ${response.statusText}`);
22
+ }
23
+ // Check content size before downloading
24
+ const contentLength = response.headers.get("content-length");
25
+ if (contentLength && parseInt(contentLength) > maxSize) {
26
+ throw new Error(`Page too large: ${contentLength} bytes (max: ${maxSize} bytes)`);
27
+ }
28
+ const html = await response.text();
29
+ // Check actual HTML size
30
+ if (html.length > maxSize) {
31
+ throw new Error(`HTML too large: ${html.length} bytes (max: ${maxSize} bytes)`);
32
+ }
33
+ // Create virtual console to suppress script errors from external scripts
34
+ const virtualConsole = new VirtualConsole();
35
+ virtualConsole.on("jsdomError", (error) => {
36
+ // Silently ignore JSDOM script errors from external scripts
37
+ // These are typically from third-party scripts that use APIs not supported by JSDOM
38
+ if (!error.message.includes("Could not parse CSS stylesheet")) {
39
+ // Only log non-CSS errors for debugging if needed
40
+ // console.error("JSDOM Error:", error.message);
41
+ }
42
+ });
43
+ // Create jsdom instance with Shadow DOM support
44
+ // Performance optimization: disable resource loading and script execution
45
+ // Most audits only need static HTML structure
46
+ const dom = new JSDOM(html, {
47
+ url,
48
+ pretendToBeVisual: true,
49
+ // Don't load external resources (huge perf gain) - omit resources option to disable
50
+ runScripts: !options.allowJs ? "outside-only" : undefined, // Only run scripts we inject (like axe-core)
51
+ virtualConsole,
52
+ beforeParse(window) {
53
+ // Polyfill browser APIs not supported by JSDOM
54
+ addBrowserPolyfills(window);
55
+ // Polyfill ShadowDOM if needed
56
+ if (!window.Element.prototype.attachShadow) {
57
+ window.Element.prototype.attachShadow = function () {
58
+ return this;
59
+ };
60
+ }
61
+ },
62
+ });
63
+ return {
64
+ document: dom.window.document,
65
+ window: dom.window,
66
+ html,
67
+ url,
68
+ };
69
+ }
70
+ catch (error) {
71
+ const message = error instanceof Error ? error.message : String(error);
72
+ throw new Error(`Failed to load page ${url}: ${message}`);
73
+ }
74
+ }
75
+ /**
76
+ * Get all elements including shadow DOM
77
+ */
78
+ export function getAllElements(element) {
79
+ const elements = [element];
80
+ // Add children
81
+ for (const child of element.children) {
82
+ elements.push(...getAllElements(child));
83
+ }
84
+ // Add shadow DOM children if available
85
+ if (element.shadowRoot) {
86
+ for (const child of element.shadowRoot.children) {
87
+ elements.push(...getAllElements(child));
88
+ }
89
+ }
90
+ return elements;
91
+ }
92
+ /**
93
+ * Build selector for an element (including shadow DOM path)
94
+ */
95
+ /**
96
+ * Add polyfills for browser APIs not supported by JSDOM
97
+ */
98
+ function addBrowserPolyfills(window) {
99
+ // Polyfill ReadableStream and related APIs
100
+ if (typeof window.ReadableStream === "undefined") {
101
+ window.ReadableStream = class ReadableStream {
102
+ constructor() {
103
+ // Minimal polyfill - just prevents errors
104
+ }
105
+ getReader() {
106
+ return {
107
+ read: () => Promise.resolve({ done: true, value: undefined }),
108
+ releaseLock: () => { },
109
+ closed: Promise.resolve(),
110
+ cancel: () => Promise.resolve(),
111
+ };
112
+ }
113
+ };
114
+ }
115
+ // Polyfill WritableStream
116
+ if (typeof window.WritableStream === "undefined") {
117
+ window.WritableStream = class WritableStream {
118
+ constructor() { }
119
+ getWriter() {
120
+ return {
121
+ write: () => Promise.resolve(),
122
+ close: () => Promise.resolve(),
123
+ abort: () => Promise.resolve(),
124
+ closed: Promise.resolve(),
125
+ ready: Promise.resolve(),
126
+ releaseLock: () => { },
127
+ };
128
+ }
129
+ };
130
+ }
131
+ // Polyfill TransformStream
132
+ if (typeof window.TransformStream === "undefined") {
133
+ window.TransformStream = class TransformStream {
134
+ readable;
135
+ writable;
136
+ constructor() {
137
+ this.readable = new window.ReadableStream();
138
+ this.writable = new window.WritableStream();
139
+ }
140
+ };
141
+ }
142
+ // Ensure window.window exists (some libraries expect this)
143
+ if (!window.window) {
144
+ window.window = window;
145
+ }
146
+ // Polyfill requestAnimationFrame if needed
147
+ if (!window.requestAnimationFrame) {
148
+ window.requestAnimationFrame = (callback) => {
149
+ return window.setTimeout(() => callback(Date.now()), 16);
150
+ };
151
+ }
152
+ // Polyfill cancelAnimationFrame if needed
153
+ if (!window.cancelAnimationFrame) {
154
+ window.cancelAnimationFrame = (id) => {
155
+ window.clearTimeout(id);
156
+ };
157
+ }
158
+ }
159
+ export function buildSelector(element) {
160
+ const path = [];
161
+ let current = element;
162
+ while (current && current.nodeType === 1) {
163
+ let selector = current.tagName.toLowerCase();
164
+ if (current.id) {
165
+ selector += `#${current.id}`;
166
+ }
167
+ else if (current.className) {
168
+ const classes = current.className.split(/\s+/).slice(0, 2).join(".");
169
+ if (classes) {
170
+ selector += `.${classes}`;
171
+ }
172
+ }
173
+ path.unshift(selector);
174
+ current = current.parentElement;
175
+ }
176
+ return path.join(" > ");
177
+ }
178
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAa,cAAc,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,MAAM,YAAY,CAAC;AAS/B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,GAAW,EACX,UAAqE,EAAE;IAEvE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC,oBAAoB;IAC9D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,UAAU,CAAC,CAAC,eAAe;IAE9D,IAAI,CAAC;QACH,sCAAsC;QACtC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAEhE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE;gBACP,YAAY,EACV,8DAA8D;aACjE;YACD,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,YAAY,CAAC,SAAS,CAAC,CAAC;QAExB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,wCAAwC;QACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC7D,IAAI,aAAa,IAAI,QAAQ,CAAC,aAAa,CAAC,GAAG,OAAO,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CACb,mBAAmB,aAAa,gBAAgB,OAAO,SAAS,CACjE,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,yBAAyB;QACzB,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,mBAAmB,IAAI,CAAC,MAAM,gBAAgB,OAAO,SAAS,CAC/D,CAAC;QACJ,CAAC;QAED,yEAAyE;QACzE,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;QAC5C,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;YACxC,4DAA4D;YAC5D,oFAAoF;YACpF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EAAE,CAAC;gBAC9D,kDAAkD;gBAClD,gDAAgD;YAClD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,gDAAgD;QAChD,0EAA0E;QAC1E,8CAA8C;QAC9C,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE;YAC1B,GAAG;YACH,iBAAiB,EAAE,IAAI;YACvB,oFAAoF;YACpF,UAAU,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,EAAE,6CAA6C;YACxG,cAAc;YACd,WAAW,CAAC,MAAiB;gBAC3B,+CAA+C;gBAC/C,mBAAmB,CAAC,MAAM,CAAC,CAAC;gBAE5B,+BAA+B;gBAC/B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;oBAC3C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,YAAY,GAAG;wBACtC,OAAO,IAA6B,CAAC;oBACvC,CAAC,CAAC;gBACJ,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,OAAO;YACL,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;YAC7B,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI;YACJ,GAAG;SACJ,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,KAAK,OAAO,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,QAAQ,GAAc,CAAC,OAAO,CAAC,CAAC;IAEtC,eAAe;IACf,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,uCAAuC;IACvC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;YAChD,QAAQ,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH;;GAEG;AACH,SAAS,mBAAmB,CAAC,MAAiB;IAC5C,2CAA2C;IAC3C,IAAI,OAAO,MAAM,CAAC,cAAc,KAAK,WAAW,EAAE,CAAC;QAChD,MAAc,CAAC,cAAc,GAAG,MAAM,cAAc;YACnD;gBACE,0CAA0C;YAC5C,CAAC;YACD,SAAS;gBACP,OAAO;oBACL,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;oBAC7D,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;oBACrB,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE;oBACzB,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;iBAChC,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;IAED,0BAA0B;IAC1B,IAAI,OAAO,MAAM,CAAC,cAAc,KAAK,WAAW,EAAE,CAAC;QAChD,MAAc,CAAC,cAAc,GAAG,MAAM,cAAc;YACnD,gBAAe,CAAC;YAChB,SAAS;gBACP,OAAO;oBACL,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;oBAC9B,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;oBAC9B,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;oBAC9B,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE;oBACzB,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE;oBACxB,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;iBACtB,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,IAAI,OAAO,MAAM,CAAC,eAAe,KAAK,WAAW,EAAE,CAAC;QACjD,MAAc,CAAC,eAAe,GAAG,MAAM,eAAe;YACrD,QAAQ,CAAM;YACd,QAAQ,CAAM;YACd;gBACE,IAAI,CAAC,QAAQ,GAAG,IAAK,MAAc,CAAC,cAAc,EAAE,CAAC;gBACrD,IAAI,CAAC,QAAQ,GAAG,IAAK,MAAc,CAAC,cAAc,EAAE,CAAC;YACvD,CAAC;SACF,CAAC;IACJ,CAAC;IAED,2DAA2D;IAC3D,IAAI,CAAE,MAAc,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAc,CAAC,MAAM,GAAG,MAAM,CAAC;IAClC,CAAC;IAED,2CAA2C;IAC3C,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;QAClC,MAAM,CAAC,qBAAqB,GAAG,CAAC,QAA8B,EAAE,EAAE;YAChE,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3D,CAAC,CAAC;IACJ,CAAC;IAED,0CAA0C;IAC1C,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;QACjC,MAAM,CAAC,oBAAoB,GAAG,CAAC,EAAU,EAAE,EAAE;YAC3C,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,OAAO,GAAmB,OAAO,CAAC;IAEtC,OAAO,OAAO,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QACzC,IAAI,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAE7C,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,QAAQ,IAAI,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;QAC/B,CAAC;aAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrE,IAAI,OAAO,EAAE,CAAC;gBACZ,QAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC;IAClC,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { BrowserPage } from "./browser.js";
2
+ /**
3
+ * Cached DOM elements to avoid multiple queries
4
+ * This provides massive performance improvement by traversing DOM once
5
+ */
6
+ export type CollectedElements = {
7
+ scripts: HTMLScriptElement[];
8
+ scriptsWithSrc: HTMLScriptElement[];
9
+ inlineScripts: HTMLScriptElement[];
10
+ inlineHeadScripts: HTMLScriptElement[];
11
+ stylesheets: HTMLLinkElement[];
12
+ styleLinks: HTMLLinkElement[];
13
+ fontLinks: HTMLLinkElement[];
14
+ images: HTMLImageElement[];
15
+ links: HTMLAnchorElement[];
16
+ passwordFields: HTMLInputElement[];
17
+ iframes: HTMLIFrameElement[];
18
+ metaCharset: HTMLMetaElement | null;
19
+ metaHttpEquiv: HTMLMetaElement | null;
20
+ metaRefresh: HTMLMetaElement | null;
21
+ metaViewport: HTMLMetaElement | null;
22
+ googleFontsLinks: HTMLLinkElement[];
23
+ googleFontsPreconnect: HTMLLinkElement | null;
24
+ fontPreloads: HTMLLinkElement[];
25
+ marquee: Element[];
26
+ blink: Element[];
27
+ font: Element[];
28
+ center: Element[];
29
+ elementsWithId: Element[];
30
+ allElements: Element[];
31
+ };
32
+ /**
33
+ * Collect all DOM elements in a single traversal
34
+ * This is much faster than multiple querySelectorAll calls
35
+ */
36
+ export declare function collectDOMElements(page: BrowserPage): CollectedElements;
37
+ /**
38
+ * Find render-blocking CSS stylesheets
39
+ */
40
+ export declare function findBlockingCSS(stylesheets: HTMLLinkElement[]): HTMLLinkElement[];
41
+ /**
42
+ * Find duplicate IDs in collected elements
43
+ */
44
+ export declare function findDuplicateIds(elementsWithId: Element[]): Map<string, Element[]>;
45
+ //# sourceMappingURL=dom-collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-collector.d.ts","sourceRoot":"","sources":["../src/dom-collector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAE9B,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,iBAAiB,EAAE,iBAAiB,EAAE,CAAC;IAGvC,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,SAAS,EAAE,eAAe,EAAE,CAAC;IAG7B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAG3B,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAG3B,cAAc,EAAE,gBAAgB,EAAE,CAAC;IAGnC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAG7B,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,aAAa,EAAE,eAAe,GAAG,IAAI,CAAC;IACtC,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IAGrC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,qBAAqB,EAAE,eAAe,GAAG,IAAI,CAAC;IAG9C,YAAY,EAAE,eAAe,EAAE,CAAC;IAGhC,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,MAAM,EAAE,OAAO,EAAE,CAAC;IAGlB,cAAc,EAAE,OAAO,EAAE,CAAC;IAG1B,WAAW,EAAE,OAAO,EAAE,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,iBAAiB,CAuJvE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,eAAe,EAAE,GAC7B,eAAe,EAAE,CAOnB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,OAAO,EAAE,GACxB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAsBxB"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Collect all DOM elements in a single traversal
3
+ * This is much faster than multiple querySelectorAll calls
4
+ */
5
+ export function collectDOMElements(page) {
6
+ const doc = page.document;
7
+ // Initialize collections
8
+ const collected = {
9
+ scripts: [],
10
+ scriptsWithSrc: [],
11
+ inlineScripts: [],
12
+ inlineHeadScripts: [],
13
+ stylesheets: [],
14
+ styleLinks: [],
15
+ fontLinks: [],
16
+ images: [],
17
+ links: [],
18
+ passwordFields: [],
19
+ iframes: [],
20
+ metaCharset: null,
21
+ metaHttpEquiv: null,
22
+ metaRefresh: null,
23
+ metaViewport: null,
24
+ googleFontsLinks: [],
25
+ googleFontsPreconnect: null,
26
+ fontPreloads: [],
27
+ marquee: [],
28
+ blink: [],
29
+ font: [],
30
+ center: [],
31
+ elementsWithId: [],
32
+ allElements: [],
33
+ };
34
+ // Single traversal of all elements
35
+ const allElements = doc.querySelectorAll("*");
36
+ collected.allElements = Array.from(allElements);
37
+ allElements.forEach((element) => {
38
+ const tagName = element.tagName.toLowerCase();
39
+ // Scripts
40
+ if (tagName === "script") {
41
+ const script = element;
42
+ collected.scripts.push(script);
43
+ if (script.hasAttribute("src")) {
44
+ collected.scriptsWithSrc.push(script);
45
+ }
46
+ else {
47
+ collected.inlineScripts.push(script);
48
+ if (script.closest("head")) {
49
+ collected.inlineHeadScripts.push(script);
50
+ }
51
+ }
52
+ }
53
+ // Links (stylesheets, fonts, preloads)
54
+ else if (tagName === "link") {
55
+ const link = element;
56
+ const rel = link.getAttribute("rel");
57
+ const href = link.getAttribute("href") || "";
58
+ if (rel === "stylesheet") {
59
+ collected.stylesheets.push(link);
60
+ collected.styleLinks.push(link);
61
+ // Font links
62
+ if (href.includes("font")) {
63
+ collected.fontLinks.push(link);
64
+ }
65
+ // Google Fonts
66
+ if (href.includes("fonts.googleapis.com")) {
67
+ collected.googleFontsLinks.push(link);
68
+ }
69
+ }
70
+ // Font preloads
71
+ if (rel === "preload" && link.getAttribute("as") === "font") {
72
+ collected.fontPreloads.push(link);
73
+ }
74
+ // Google Fonts preconnect
75
+ if (rel === "preconnect" &&
76
+ (href.includes("fonts.googleapis.com") ||
77
+ href.includes("fonts.gstatic.com"))) {
78
+ collected.googleFontsPreconnect = link;
79
+ }
80
+ }
81
+ // Images
82
+ else if (tagName === "img") {
83
+ collected.images.push(element);
84
+ }
85
+ // Anchors
86
+ else if (tagName === "a") {
87
+ collected.links.push(element);
88
+ }
89
+ // Iframes
90
+ else if (tagName === "iframe") {
91
+ collected.iframes.push(element);
92
+ }
93
+ // Input fields
94
+ else if (tagName === "input") {
95
+ const input = element;
96
+ if (input.type === "password") {
97
+ collected.passwordFields.push(input);
98
+ }
99
+ }
100
+ // Meta tags
101
+ else if (tagName === "meta") {
102
+ const meta = element;
103
+ const charset = meta.getAttribute("charset");
104
+ const httpEquiv = meta.getAttribute("http-equiv");
105
+ const name = meta.getAttribute("name");
106
+ if (charset) {
107
+ collected.metaCharset = meta;
108
+ }
109
+ if (httpEquiv === "Content-Type") {
110
+ collected.metaHttpEquiv = meta;
111
+ }
112
+ if (httpEquiv === "refresh") {
113
+ collected.metaRefresh = meta;
114
+ }
115
+ if (name === "viewport") {
116
+ collected.metaViewport = meta;
117
+ }
118
+ }
119
+ // Deprecated elements
120
+ else if (tagName === "marquee") {
121
+ collected.marquee.push(element);
122
+ }
123
+ else if (tagName === "blink") {
124
+ collected.blink.push(element);
125
+ }
126
+ else if (tagName === "font") {
127
+ collected.font.push(element);
128
+ }
129
+ else if (tagName === "center") {
130
+ collected.center.push(element);
131
+ }
132
+ // Elements with IDs
133
+ if (element.hasAttribute("id")) {
134
+ collected.elementsWithId.push(element);
135
+ }
136
+ });
137
+ return collected;
138
+ }
139
+ /**
140
+ * Find render-blocking CSS stylesheets
141
+ */
142
+ export function findBlockingCSS(stylesheets) {
143
+ return stylesheets.filter((link) => {
144
+ const media = link.getAttribute("media");
145
+ const disabled = link.hasAttribute("disabled");
146
+ // Blocking if no media attribute (or media="all") and not disabled
147
+ return !disabled && (!media || media === "all" || media === "screen");
148
+ });
149
+ }
150
+ /**
151
+ * Find duplicate IDs in collected elements
152
+ */
153
+ export function findDuplicateIds(elementsWithId) {
154
+ const idCount = new Map();
155
+ elementsWithId.forEach((element) => {
156
+ const id = element.getAttribute("id");
157
+ if (id) {
158
+ if (!idCount.has(id)) {
159
+ idCount.set(id, []);
160
+ }
161
+ idCount.get(id).push(element);
162
+ }
163
+ });
164
+ // Filter to only duplicates
165
+ const duplicates = new Map();
166
+ idCount.forEach((elements, id) => {
167
+ if (elements.length > 1) {
168
+ duplicates.set(id, elements);
169
+ }
170
+ });
171
+ return duplicates;
172
+ }
173
+ //# sourceMappingURL=dom-collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-collector.js","sourceRoot":"","sources":["../src/dom-collector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { Issue, PendingCheck, Summary, AuditReport } from "./types.js";
2
+ /**
3
+ * Format audit results into a complete audit report
4
+ */
5
+ export declare function formatResults(url: string, startTime: number, endTime: number, allIssues: Issue[], allPassed: PendingCheck[], allIncomplete?: Issue[]): AuditReport;
6
+ /**
7
+ * Generate summary statistics from issues
8
+ */
9
+ export declare function generateSummary(issues: Issue[]): Summary;
10
+ /**
11
+ * Merge multiple audit results into a single array
12
+ */
13
+ export declare function mergeAuditResults(results: Array<{
14
+ issues: Issue[];
15
+ passed: PendingCheck[];
16
+ }>): {
17
+ issues: Issue[];
18
+ passed: PendingCheck[];
19
+ };
20
+ /**
21
+ * Apply threshold checking to determine if audit passed
22
+ */
23
+ export declare function checkThresholds(summary: Summary, thresholds?: {
24
+ critical?: number;
25
+ serious?: number;
26
+ moderate?: number;
27
+ minor?: number;
28
+ }): {
29
+ passed: boolean;
30
+ violations: string[];
31
+ };
32
+ /**
33
+ * Sort issues by severity and then by category
34
+ */
35
+ export declare function sortIssues(issues: Issue[]): Issue[];
36
+ /**
37
+ * Group issues by category
38
+ */
39
+ export declare function groupByCategory(issues: Issue[]): Record<string, Issue[]>;
40
+ /**
41
+ * Group issues by severity
42
+ */
43
+ export declare function groupBySeverity(issues: Issue[]): Record<string, Issue[]>;
44
+ /**
45
+ * Filter issues by severity
46
+ */
47
+ export declare function filterBySeverity(issues: Issue[], severities: Array<"critical" | "serious" | "moderate" | "minor">): Issue[];
48
+ /**
49
+ * Filter issues by category
50
+ */
51
+ export declare function filterByCategory(issues: Issue[], categories: string[]): Issue[];
52
+ /**
53
+ * Get top N issues by severity
54
+ */
55
+ export declare function getTopIssues(issues: Issue[], count: number): Issue[];
56
+ /**
57
+ * Calculate percentage of passed checks
58
+ */
59
+ export declare function calculatePassRate(passed: number, total: number): number;
60
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvE;;GAEG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,KAAK,EAAE,EAClB,SAAS,EAAE,YAAY,EAAE,EACzB,aAAa,GAAE,KAAK,EAAO,GAC1B,WAAW,CAeb;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAmCxD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,KAAK,CAAC;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,MAAM,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC,GAC1D;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,MAAM,EAAE,YAAY,EAAE,CAAA;CAAE,CAU7C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACA;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CA+C3C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAanD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAWxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAaxE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,KAAK,EAAE,EACf,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC,GAC/D,KAAK,EAAE,CAET;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,KAAK,EAAE,EACf,UAAU,EAAE,MAAM,EAAE,GACnB,KAAK,EAAE,CAET;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CAEpE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvE"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Format audit results into a complete audit report
3
+ */
4
+ export function formatResults(url, startTime, endTime, allIssues, allPassed, allIncomplete = []) {
5
+ const duration = endTime - startTime;
6
+ // Generate summary statistics
7
+ const summary = generateSummary(allIssues);
8
+ return {
9
+ url,
10
+ timestamp: startTime,
11
+ duration,
12
+ issues: allIssues,
13
+ passed: allPassed,
14
+ incomplete: allIncomplete,
15
+ summary,
16
+ };
17
+ }
18
+ /**
19
+ * Generate summary statistics from issues
20
+ */
21
+ export function generateSummary(issues) {
22
+ const summary = {
23
+ total: issues.length,
24
+ bySeverity: {
25
+ critical: 0,
26
+ serious: 0,
27
+ moderate: 0,
28
+ minor: 0,
29
+ },
30
+ byCategory: {
31
+ images: 0,
32
+ interactive: 0,
33
+ forms: 0,
34
+ color: 0,
35
+ document: 0,
36
+ structure: 0,
37
+ aria: 0,
38
+ technical: 0,
39
+ },
40
+ passed: 0,
41
+ };
42
+ // Count by severity
43
+ issues.forEach((issue) => {
44
+ summary.bySeverity[issue.severity]++;
45
+ });
46
+ // Count by category
47
+ issues.forEach((issue) => {
48
+ if (issue.category in summary.byCategory) {
49
+ summary.byCategory[issue.category]++;
50
+ }
51
+ });
52
+ return summary;
53
+ }
54
+ /**
55
+ * Merge multiple audit results into a single array
56
+ */
57
+ export function mergeAuditResults(results) {
58
+ const allIssues = [];
59
+ const allPassed = [];
60
+ results.forEach((result) => {
61
+ allIssues.push(...result.issues);
62
+ allPassed.push(...result.passed);
63
+ });
64
+ return { issues: allIssues, passed: allPassed };
65
+ }
66
+ /**
67
+ * Apply threshold checking to determine if audit passed
68
+ */
69
+ export function checkThresholds(summary, thresholds) {
70
+ if (!thresholds) {
71
+ return { passed: true, violations: [] };
72
+ }
73
+ const violations = [];
74
+ if (thresholds.critical !== undefined &&
75
+ summary.bySeverity.critical > thresholds.critical) {
76
+ violations.push(`Critical issues: ${summary.bySeverity.critical} (threshold: ${thresholds.critical})`);
77
+ }
78
+ if (thresholds.serious !== undefined &&
79
+ summary.bySeverity.serious > thresholds.serious) {
80
+ violations.push(`Serious issues: ${summary.bySeverity.serious} (threshold: ${thresholds.serious})`);
81
+ }
82
+ if (thresholds.moderate !== undefined &&
83
+ summary.bySeverity.moderate > thresholds.moderate) {
84
+ violations.push(`Moderate issues: ${summary.bySeverity.moderate} (threshold: ${thresholds.moderate})`);
85
+ }
86
+ if (thresholds.minor !== undefined &&
87
+ summary.bySeverity.minor > thresholds.minor) {
88
+ violations.push(`Minor issues: ${summary.bySeverity.minor} (threshold: ${thresholds.minor})`);
89
+ }
90
+ return {
91
+ passed: violations.length === 0,
92
+ violations,
93
+ };
94
+ }
95
+ /**
96
+ * Sort issues by severity and then by category
97
+ */
98
+ export function sortIssues(issues) {
99
+ const severityOrder = { critical: 0, serious: 1, moderate: 2, minor: 3 };
100
+ return issues.slice().sort((a, b) => {
101
+ // First sort by severity
102
+ const severityDiff = severityOrder[a.severity] - severityOrder[b.severity];
103
+ if (severityDiff !== 0) {
104
+ return severityDiff;
105
+ }
106
+ // Then by category
107
+ return a.category.localeCompare(b.category);
108
+ });
109
+ }
110
+ /**
111
+ * Group issues by category
112
+ */
113
+ export function groupByCategory(issues) {
114
+ const grouped = {};
115
+ issues.forEach((issue) => {
116
+ if (!grouped[issue.category]) {
117
+ grouped[issue.category] = [];
118
+ }
119
+ grouped[issue.category].push(issue);
120
+ });
121
+ return grouped;
122
+ }
123
+ /**
124
+ * Group issues by severity
125
+ */
126
+ export function groupBySeverity(issues) {
127
+ const grouped = {
128
+ critical: [],
129
+ serious: [],
130
+ moderate: [],
131
+ minor: [],
132
+ };
133
+ issues.forEach((issue) => {
134
+ grouped[issue.severity].push(issue);
135
+ });
136
+ return grouped;
137
+ }
138
+ /**
139
+ * Filter issues by severity
140
+ */
141
+ export function filterBySeverity(issues, severities) {
142
+ return issues.filter((issue) => severities.includes(issue.severity));
143
+ }
144
+ /**
145
+ * Filter issues by category
146
+ */
147
+ export function filterByCategory(issues, categories) {
148
+ return issues.filter((issue) => categories.includes(issue.category));
149
+ }
150
+ /**
151
+ * Get top N issues by severity
152
+ */
153
+ export function getTopIssues(issues, count) {
154
+ return sortIssues(issues).slice(0, count);
155
+ }
156
+ /**
157
+ * Calculate percentage of passed checks
158
+ */
159
+ export function calculatePassRate(passed, total) {
160
+ if (total === 0)
161
+ return 100;
162
+ return Math.round((passed / total) * 100);
163
+ }
164
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"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"}