@shadowcoderr/context-graph 0.3.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 (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/dist/analyzers/a11y-extractor.d.ts +15 -0
  4. package/dist/analyzers/a11y-extractor.d.ts.map +1 -0
  5. package/dist/analyzers/a11y-extractor.js +148 -0
  6. package/dist/analyzers/a11y-extractor.js.map +1 -0
  7. package/dist/analyzers/dom-analyzer.d.ts +20 -0
  8. package/dist/analyzers/dom-analyzer.d.ts.map +1 -0
  9. package/dist/analyzers/dom-analyzer.js +126 -0
  10. package/dist/analyzers/dom-analyzer.js.map +1 -0
  11. package/dist/analyzers/locator-generator.d.ts +13 -0
  12. package/dist/analyzers/locator-generator.d.ts.map +1 -0
  13. package/dist/analyzers/locator-generator.js +381 -0
  14. package/dist/analyzers/locator-generator.js.map +1 -0
  15. package/dist/analyzers/network-logger.d.ts +15 -0
  16. package/dist/analyzers/network-logger.d.ts.map +1 -0
  17. package/dist/analyzers/network-logger.js +71 -0
  18. package/dist/analyzers/network-logger.js.map +1 -0
  19. package/dist/cli/index.d.ts +2 -0
  20. package/dist/cli/index.d.ts.map +1 -0
  21. package/dist/cli/index.js +155 -0
  22. package/dist/cli/index.js.map +1 -0
  23. package/dist/config/defaults.d.ts +3 -0
  24. package/dist/config/defaults.d.ts.map +1 -0
  25. package/dist/config/defaults.js +54 -0
  26. package/dist/config/defaults.js.map +1 -0
  27. package/dist/config/loader.d.ts +3 -0
  28. package/dist/config/loader.d.ts.map +1 -0
  29. package/dist/config/loader.js +75 -0
  30. package/dist/config/loader.js.map +1 -0
  31. package/dist/config/schema.d.ts +168 -0
  32. package/dist/config/schema.d.ts.map +1 -0
  33. package/dist/config/schema.js +104 -0
  34. package/dist/config/schema.js.map +1 -0
  35. package/dist/core/browser-adapter.d.ts +24 -0
  36. package/dist/core/browser-adapter.d.ts.map +1 -0
  37. package/dist/core/browser-adapter.js +208 -0
  38. package/dist/core/browser-adapter.js.map +1 -0
  39. package/dist/core/capture-engine.d.ts +52 -0
  40. package/dist/core/capture-engine.d.ts.map +1 -0
  41. package/dist/core/capture-engine.js +593 -0
  42. package/dist/core/capture-engine.js.map +1 -0
  43. package/dist/core/runtime.d.ts +38 -0
  44. package/dist/core/runtime.d.ts.map +1 -0
  45. package/dist/core/runtime.js +648 -0
  46. package/dist/core/runtime.js.map +1 -0
  47. package/dist/prompts/init-prompt.d.ts +12 -0
  48. package/dist/prompts/init-prompt.d.ts.map +1 -0
  49. package/dist/prompts/init-prompt.js +128 -0
  50. package/dist/prompts/init-prompt.js.map +1 -0
  51. package/dist/registry/components-registry.d.ts +97 -0
  52. package/dist/registry/components-registry.d.ts.map +1 -0
  53. package/dist/registry/components-registry.js +469 -0
  54. package/dist/registry/components-registry.js.map +1 -0
  55. package/dist/registry/index.d.ts +2 -0
  56. package/dist/registry/index.d.ts.map +1 -0
  57. package/dist/registry/index.js +7 -0
  58. package/dist/registry/index.js.map +1 -0
  59. package/dist/security/patterns.d.ts +4 -0
  60. package/dist/security/patterns.d.ts.map +1 -0
  61. package/dist/security/patterns.js +65 -0
  62. package/dist/security/patterns.js.map +1 -0
  63. package/dist/security/redactor.d.ts +26 -0
  64. package/dist/security/redactor.d.ts.map +1 -0
  65. package/dist/security/redactor.js +128 -0
  66. package/dist/security/redactor.js.map +1 -0
  67. package/dist/security/validator.d.ts +11 -0
  68. package/dist/security/validator.d.ts.map +1 -0
  69. package/dist/security/validator.js +62 -0
  70. package/dist/security/validator.js.map +1 -0
  71. package/dist/storage/engine.d.ts +45 -0
  72. package/dist/storage/engine.d.ts.map +1 -0
  73. package/dist/storage/engine.js +479 -0
  74. package/dist/storage/engine.js.map +1 -0
  75. package/dist/storage/manifest.d.ts +10 -0
  76. package/dist/storage/manifest.d.ts.map +1 -0
  77. package/dist/storage/manifest.js +98 -0
  78. package/dist/storage/manifest.js.map +1 -0
  79. package/dist/storage/serializer.d.ts +9 -0
  80. package/dist/storage/serializer.d.ts.map +1 -0
  81. package/dist/storage/serializer.js +22 -0
  82. package/dist/storage/serializer.js.map +1 -0
  83. package/dist/types/capture.d.ts +206 -0
  84. package/dist/types/capture.d.ts.map +1 -0
  85. package/dist/types/capture.js +3 -0
  86. package/dist/types/capture.js.map +1 -0
  87. package/dist/types/config.d.ts +63 -0
  88. package/dist/types/config.d.ts.map +1 -0
  89. package/dist/types/config.js +3 -0
  90. package/dist/types/config.js.map +1 -0
  91. package/dist/types/registry.d.ts +94 -0
  92. package/dist/types/registry.d.ts.map +1 -0
  93. package/dist/types/registry.js +3 -0
  94. package/dist/types/registry.js.map +1 -0
  95. package/dist/types/storage.d.ts +57 -0
  96. package/dist/types/storage.d.ts.map +1 -0
  97. package/dist/types/storage.js +3 -0
  98. package/dist/types/storage.js.map +1 -0
  99. package/dist/utils/hash.d.ts +3 -0
  100. package/dist/utils/hash.d.ts.map +1 -0
  101. package/dist/utils/hash.js +26 -0
  102. package/dist/utils/hash.js.map +1 -0
  103. package/dist/utils/logger.d.ts +20 -0
  104. package/dist/utils/logger.d.ts.map +1 -0
  105. package/dist/utils/logger.js +86 -0
  106. package/dist/utils/logger.js.map +1 -0
  107. package/dist/utils/pom-generator.d.ts +12 -0
  108. package/dist/utils/pom-generator.d.ts.map +1 -0
  109. package/dist/utils/pom-generator.js +83 -0
  110. package/dist/utils/pom-generator.js.map +1 -0
  111. package/dist/utils/validators.d.ts +7 -0
  112. package/dist/utils/validators.d.ts.map +1 -0
  113. package/dist/utils/validators.js +51 -0
  114. package/dist/utils/validators.js.map +1 -0
  115. package/package.json +70 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 shadowcoderr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # ContextGraph
2
+
3
+ > **A deterministic "Flight Data Recorder" for web applications** — captures rich, AI-ready context from browser sessions in restricted enterprise environments where MCP is unavailable.
4
+
5
+ [![Version](https://img.shields.io/badge/version-0.3.0-blue)](package.json)
6
+ [![Node](https://img.shields.io/badge/node-%3E%3D18.0.0-green)](package.json)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue)](tsconfig.json)
8
+ [![Playwright](https://img.shields.io/badge/Playwright-1.40%2B-orange)](package.json)
9
+ [![License](https://img.shields.io/badge/license-MIT-lightgrey)](LICENSE)
10
+
11
+ ---
12
+
13
+ ## Why ContextGraph?
14
+
15
+ IDE-based AI agents (Copilot, Cursor, etc.) are blind to your running browser. Without MCP, they cannot see the live DOM, accessibility tree, or real API traffic of the app you are testing. In enterprise environments, MCP and cloud-based recording tools are often blocked by security policy.
16
+
17
+ ContextGraph solves this by acting as a **pre-processor** — it bridges the gap between manual exploration and AI-powered test generation using only Playwright, which is already whitelisted on most QA teams' machines.
18
+
19
+ ```
20
+ Your Browser Session
21
+
22
+
23
+ ContextGraph ← You are here
24
+ (Playwright-native)
25
+
26
+
27
+ Structured Output ← DOM, Locators, A11y Tree, Network
28
+ (Local Filesystem)
29
+
30
+
31
+ AI Agent / LLM ← Receives clean, noise-free context
32
+ (Copilot / Cursor / Claude)
33
+
34
+
35
+ Generated Tests ← Playwright .spec.ts files
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Quick Start
41
+
42
+ ### Prerequisites
43
+
44
+ - **Node.js** 18.0.0 or higher
45
+ - **Microsoft Edge** (installed — used as the capture browser)
46
+ - **Windows 10/11** (primary support; Linux/macOS in beta)
47
+
48
+ ### Install
49
+
50
+ ```bash
51
+ npm install -g context-graph
52
+ ```
53
+
54
+ Verify:
55
+
56
+ ```bash
57
+ context-graph --version
58
+ # Context Graph v0.3.0
59
+ ```
60
+
61
+ ### Capture Your First Page (2 minutes)
62
+
63
+ ```bash
64
+ # 1. Start a capture session
65
+ context-graph --mode browser --url https://your-app.com
66
+
67
+ # 2. Navigate through the app — every page you visit is captured
68
+ # 3. Press Ctrl+C when done
69
+
70
+ # 4. Inspect results
71
+ cat context-graph-output/global_manifest.json
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Key Features
77
+
78
+ | Feature | Description |
79
+ |---|---|
80
+ | 🎯 **Guided Capture** | Captures only what you navigate — no autonomous crawling |
81
+ | 🧹 **Clean DOM Output** | Scripts, event handlers, and noise stripped before saving |
82
+ | 🔑 **Smart Locators** | 5+ selector strategies per element, ranked by resilience |
83
+ | ♿ **Accessibility Tree** | Full ARIA/role hierarchy for semantic understanding |
84
+ | 🌐 **Network Logging** | All HTTP traffic captured with automatic PII redaction |
85
+ | 🔒 **Security by Design** | Credentials, tokens, PII never touch the filesystem |
86
+ | 🧩 **Component Registry** | Tracks reusable UI patterns across captured pages |
87
+ | 📦 **100% Offline** | Zero cloud dependencies, zero telemetry, runs inside enterprise perimeter |
88
+
89
+ ---
90
+
91
+ ## Operating Modes
92
+
93
+ ### Browser Mode — Passive Observer
94
+
95
+ Best for: understanding app structure, feeding AI with full UI context.
96
+
97
+ ```bash
98
+ context-graph --mode browser --url https://app.example.com
99
+ ```
100
+
101
+ ### Recorder Mode — Action Capture
102
+
103
+ Best for: converting manual test walkthroughs into replayable scripts.
104
+
105
+ ```bash
106
+ context-graph --mode recorder --url https://app.example.com
107
+ ```
108
+
109
+ ---
110
+
111
+ ## What You Get
112
+
113
+ For each captured page, ContextGraph generates:
114
+
115
+ - **Sanitized DOM** - Clean HTML with scripts removed
116
+ - **Accessibility Tree** - Full ARIA hierarchy and semantic structure
117
+ - **Smart Locators** - Ranked Playwright selectors (Role → TestID → Label → Text)
118
+ - **Network Log** - HTTP traffic with automatic PII redaction
119
+ - **Screenshots** - Full-page visual captures
120
+ - **Component Registry** - Cross-page UI pattern tracking
121
+
122
+ ---
123
+
124
+ ## Feeding Output to an AI Agent
125
+
126
+ ### What to Give the AI
127
+
128
+ For test generation, provide the AI these files from a single captured page:
129
+
130
+ | File | Why it Matters |
131
+ |---|---|
132
+ | `metadata.json` | URL, page title, timing context |
133
+ | `a11y_tree.json` | Semantic structure — what the page *means* |
134
+ | `locators.json` | Ready-to-use, ranked Playwright selectors |
135
+ | `dom_snapshot.html` | Full structural HTML if deep context is needed |
136
+ | `network/traffic_log.jsonl` | What API calls the page makes |
137
+
138
+ ### Example Prompt Structure
139
+
140
+ ```
141
+ I am testing the following web page:
142
+ URL: https://app.example.com/login
143
+
144
+ Here is the accessibility tree:
145
+ [paste a11y_tree.json]
146
+
147
+ Here are the available locators:
148
+ [paste locators.json]
149
+
150
+ Here is the API traffic observed:
151
+ [paste relevant entries from traffic_log.jsonl]
152
+
153
+ Generate a Playwright test that:
154
+ 1. Navigates to the login page
155
+ 2. Enters valid credentials
156
+ 3. Asserts the dashboard is shown
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Documentation
162
+
163
+ 📖 **[Complete User Guide](docs/USER_GUIDE.md)** - Advanced configuration, CLI reference, troubleshooting, and architecture details.
164
+
165
+ ---
166
+
167
+ ## Installation
168
+
169
+ ```bash
170
+ npm install -g context-graph
171
+ ```
172
+
173
+ ---
174
+
175
+ ## License
176
+
177
+ MIT — © Shadow Coderr
178
+
179
+ ---
180
+
181
+ ## Issues & Support
182
+
183
+ 🐛 **[Report Issues](https://github.com/shadowcoderr/ContextGraph/issues)** - Bug reports and feature requests
184
+
185
+ 💬 **[Discussions](https://github.com/shadowcoderr/ContextGraph/discussions)** - Community support and questions
@@ -0,0 +1,15 @@
1
+ import { Page } from '@playwright/test';
2
+ import { AccessibilityTree } from '../types/capture';
3
+ export declare class AccessibilityExtractor {
4
+ extract(page: Page, _includeHidden?: boolean): Promise<AccessibilityTree>;
5
+ /**
6
+ * Transform CDP accessibility tree format to our format
7
+ */
8
+ private transformCDPSnapshot;
9
+ /**
10
+ * Build accessibility tree from DOM when Playwright accessibility API is unavailable
11
+ */
12
+ private buildFromDOM;
13
+ private transformSnapshot;
14
+ }
15
+ //# sourceMappingURL=a11y-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y-extractor.d.ts","sourceRoot":"","sources":["../../src/analyzers/a11y-extractor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,qBAAa,sBAAsB;IAC3B,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,GAAE,OAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwCtF;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA0C5B;;OAEG;YACW,YAAY;IA+C1B,OAAO,CAAC,iBAAiB;CAkB1B"}
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AccessibilityExtractor = void 0;
4
+ class AccessibilityExtractor {
5
+ async extract(page, _includeHidden = false) {
6
+ try {
7
+ // Wait for page to be ready
8
+ await page.waitForLoadState('domcontentloaded', { timeout: 5000 }).catch(() => { });
9
+ // Try to get accessibility snapshot via CDP
10
+ let snapshot = null;
11
+ try {
12
+ // Use CDP (Chrome DevTools Protocol) for accessibility snapshot
13
+ const client = await page.context().newCDPSession(page);
14
+ snapshot = await client.send('Accessibility.getFullAXTree');
15
+ if (snapshot && snapshot.nodes && snapshot.nodes.length > 0) {
16
+ // Transform CDP format to our format
17
+ return this.transformCDPSnapshot(snapshot.nodes[0], snapshot.nodes);
18
+ }
19
+ }
20
+ catch (cdpError) {
21
+ // CDP not available, fall through to DOM-based approach
22
+ }
23
+ // Fallback: build accessibility tree from DOM
24
+ snapshot = await this.buildFromDOM(page);
25
+ return this.transformSnapshot(snapshot);
26
+ }
27
+ catch (error) {
28
+ // Final fallback: build from DOM
29
+ try {
30
+ const domSnapshot = await this.buildFromDOM(page);
31
+ return this.transformSnapshot(domSnapshot);
32
+ }
33
+ catch (domError) {
34
+ // Ultimate fallback
35
+ return {
36
+ role: 'WebArea',
37
+ name: await page.title().catch(() => ''),
38
+ children: [],
39
+ };
40
+ }
41
+ }
42
+ }
43
+ /**
44
+ * Transform CDP accessibility tree format to our format
45
+ */
46
+ transformCDPSnapshot(rootNode, allNodes) {
47
+ const buildNode = (node) => {
48
+ const children = [];
49
+ if (node.childIds && node.childIds.length > 0) {
50
+ for (const childId of node.childIds) {
51
+ const childNode = allNodes.find((n) => n.nodeId === childId);
52
+ if (childNode) {
53
+ children.push(buildNode(childNode));
54
+ }
55
+ }
56
+ }
57
+ const result = {
58
+ role: node.role?.value || 'unknown',
59
+ name: node.name?.value || '',
60
+ children: children.length > 0 ? children : [],
61
+ value: node.value?.value,
62
+ required: node.properties?.find((p) => p.name === 'required')?.value?.value === true,
63
+ disabled: node.properties?.find((p) => p.name === 'disabled')?.value?.value === true,
64
+ focused: node.properties?.find((p) => p.name === 'focused')?.value?.value === true,
65
+ };
66
+ // Add optional properties only if they exist
67
+ const checked = node.properties?.find((p) => p.name === 'checked')?.value?.value;
68
+ if (checked !== undefined)
69
+ result.checked = checked;
70
+ const pressed = node.properties?.find((p) => p.name === 'pressed')?.value?.value;
71
+ if (pressed !== undefined)
72
+ result.pressed = pressed;
73
+ const selected = node.properties?.find((p) => p.name === 'selected')?.value?.value;
74
+ if (selected !== undefined)
75
+ result.selected = selected;
76
+ const expanded = node.properties?.find((p) => p.name === 'expanded')?.value?.value;
77
+ if (expanded !== undefined)
78
+ result.expanded = expanded;
79
+ return result;
80
+ };
81
+ return buildNode(rootNode);
82
+ }
83
+ /**
84
+ * Build accessibility tree from DOM when Playwright accessibility API is unavailable
85
+ */
86
+ async buildFromDOM(page) {
87
+ return await page.evaluate(() => {
88
+ const buildA11yNode = (element) => {
89
+ const role = element.getAttribute('role') ||
90
+ (element.tagName === 'BUTTON' ? 'button' :
91
+ element.tagName === 'INPUT' ? 'textbox' :
92
+ element.tagName === 'A' ? 'link' :
93
+ element.tagName === 'FORM' ? 'form' :
94
+ element.tagName === 'HEADER' ? 'banner' :
95
+ element.tagName === 'NAV' ? 'navigation' :
96
+ element.tagName === 'MAIN' ? 'main' :
97
+ element.tagName === 'FOOTER' ? 'contentinfo' : 'generic');
98
+ const name = element.getAttribute('aria-label') ||
99
+ element.getAttribute('aria-labelledby') ||
100
+ element.innerText?.trim() ||
101
+ element.getAttribute('alt') ||
102
+ element.getAttribute('title') ||
103
+ '';
104
+ const children = [];
105
+ for (let i = 0; i < element.children.length; i++) {
106
+ const child = buildA11yNode(element.children[i]);
107
+ if (child)
108
+ children.push(child);
109
+ }
110
+ const result = {
111
+ role,
112
+ name: name.substring(0, 100), // Limit name length
113
+ children: children.length > 0 ? children : [],
114
+ disabled: element.hasAttribute('disabled'),
115
+ required: element.hasAttribute('required'),
116
+ };
117
+ const checked = element.checked;
118
+ if (checked)
119
+ result.checked = checked;
120
+ const expanded = element.getAttribute('aria-expanded') === 'true';
121
+ if (expanded)
122
+ result.expanded = expanded;
123
+ return result;
124
+ };
125
+ return buildA11yNode(document.documentElement);
126
+ });
127
+ }
128
+ transformSnapshot(snapshot) {
129
+ return {
130
+ role: snapshot.role || 'unknown',
131
+ name: snapshot.name || '',
132
+ children: snapshot.children ? snapshot.children.map((child) => this.transformSnapshot(child)) : [],
133
+ value: snapshot.value,
134
+ required: snapshot.required,
135
+ disabled: snapshot.disabled,
136
+ focused: snapshot.focused,
137
+ multiline: snapshot.multiline,
138
+ protected: snapshot.protected,
139
+ checked: snapshot.checked,
140
+ pressed: snapshot.pressed,
141
+ selected: snapshot.selected,
142
+ expanded: snapshot.expanded,
143
+ level: snapshot.level,
144
+ };
145
+ }
146
+ }
147
+ exports.AccessibilityExtractor = AccessibilityExtractor;
148
+ //# sourceMappingURL=a11y-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y-extractor.js","sourceRoot":"","sources":["../../src/analyzers/a11y-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { Page } from '@playwright/test';
2
+ export declare class DOMAnalyzer {
3
+ private serializeFrameContent;
4
+ analyze(page: Page): Promise<{
5
+ html: string;
6
+ frames: Array<{
7
+ url: string;
8
+ name: string;
9
+ content: string;
10
+ }>;
11
+ }>;
12
+ getPerformanceMetrics(page: Page): Promise<{
13
+ domNodes: number;
14
+ scripts: number;
15
+ stylesheets: number;
16
+ images: number;
17
+ totalRequests: number;
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=dom-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/dom-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAS,MAAM,kBAAkB,CAAC;AAE/C,qBAAa,WAAW;YAGR,qBAAqB;IAyC7B,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IA4D7G,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;QAC/C,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CAkBH"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DOMAnalyzer = void 0;
4
+ class DOMAnalyzer {
5
+ async serializeFrameContent(frame) {
6
+ try {
7
+ return await frame.evaluate(() => {
8
+ const serialize = (node) => {
9
+ if (!node)
10
+ return '';
11
+ const nodeType = node.nodeType;
12
+ const Node = window.Node;
13
+ if (nodeType === Node.DOCUMENT_NODE)
14
+ return '<!DOCTYPE html>' + serialize(node.documentElement);
15
+ if (nodeType === Node.ELEMENT_NODE) {
16
+ const el = node;
17
+ let tag = el.tagName.toLowerCase();
18
+ let attrs = '';
19
+ for (let i = 0; i < el.attributes.length; i++) {
20
+ const a = el.attributes[i];
21
+ attrs += ` ${a.name}="${a.value}"`;
22
+ }
23
+ let inner = '';
24
+ // Shadow DOM
25
+ if (el.shadowRoot) {
26
+ inner += '<!--cc-shadow-start-->';
27
+ const sr = el.shadowRoot;
28
+ for (let i = 0; i < sr.childNodes.length; i++) {
29
+ inner += serialize(sr.childNodes[i]);
30
+ }
31
+ inner += '<!--cc-shadow-end-->';
32
+ }
33
+ for (let i = 0; i < el.childNodes.length; i++) {
34
+ inner += serialize(el.childNodes[i]);
35
+ }
36
+ return `<${tag}${attrs}>${inner}</${tag}>`;
37
+ }
38
+ if (nodeType === Node.TEXT_NODE)
39
+ return node.nodeValue.replace(/</g, '&lt;');
40
+ return '';
41
+ };
42
+ return serialize(document);
43
+ });
44
+ }
45
+ catch (error) {
46
+ return '';
47
+ }
48
+ }
49
+ async analyze(page) {
50
+ // Get the main document serialized including shadow roots
51
+ const html = await page.evaluate(() => {
52
+ const serialize = (node) => {
53
+ if (!node)
54
+ return '';
55
+ const nodeType = node.nodeType;
56
+ const Node = window.Node;
57
+ if (nodeType === Node.DOCUMENT_NODE)
58
+ return '<!DOCTYPE html>' + serialize(node.documentElement);
59
+ if (nodeType === Node.ELEMENT_NODE) {
60
+ const el = node;
61
+ let tag = el.tagName.toLowerCase();
62
+ let attrs = '';
63
+ for (let i = 0; i < el.attributes.length; i++) {
64
+ const a = el.attributes[i];
65
+ attrs += ` ${a.name}="${a.value}"`;
66
+ }
67
+ let inner = '';
68
+ // Shadow DOM
69
+ if (el.shadowRoot) {
70
+ inner += '<!--cc-shadow-start-->';
71
+ const sr = el.shadowRoot;
72
+ for (let i = 0; i < sr.childNodes.length; i++) {
73
+ inner += serialize(sr.childNodes[i]);
74
+ }
75
+ inner += '<!--cc-shadow-end-->';
76
+ }
77
+ for (let i = 0; i < el.childNodes.length; i++) {
78
+ inner += serialize(el.childNodes[i]);
79
+ }
80
+ return `<${tag}${attrs}>${inner}</${tag}>`;
81
+ }
82
+ if (nodeType === Node.TEXT_NODE)
83
+ return node.nodeValue ? node.nodeValue.replace(/</g, '&lt;') : '';
84
+ return '';
85
+ };
86
+ return serialize(document);
87
+ });
88
+ // Gather frames content
89
+ const frames = [];
90
+ const framesList = page.frames();
91
+ for (let i = 0; i < framesList.length; i++) {
92
+ const frame = framesList[i];
93
+ if (frame === page.mainFrame())
94
+ continue; // Skip main frame
95
+ const content = await this.serializeFrameContent(frame);
96
+ frames.push({ url: frame.url(), name: frame.name(), content });
97
+ }
98
+ // Remove script tags and inline JavaScript from main html
99
+ let sanitized = html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
100
+ sanitized = sanitized.replace(/<script[^>]*\/\>/gi, '');
101
+ sanitized = sanitized.replace(/\s+on\w+="[^"]*"/gi, '');
102
+ sanitized = sanitized.replace(/\s+on\w+='[^']*'/gi, '');
103
+ // Add capture timestamp
104
+ const timestamp = new Date().toISOString();
105
+ sanitized = sanitized.replace(/<html([^>]*)>/, `<html$1 data-cc-captured="${timestamp}">`);
106
+ return { html: sanitized, frames };
107
+ }
108
+ async getPerformanceMetrics(page) {
109
+ const metrics = await page.evaluate(() => {
110
+ const domNodes = document.getElementsByTagName('*').length;
111
+ const scripts = document.querySelectorAll('script').length;
112
+ const stylesheets = document.querySelectorAll('link[rel="stylesheet"]').length;
113
+ const images = document.querySelectorAll('img').length;
114
+ return {
115
+ domNodes,
116
+ scripts,
117
+ stylesheets,
118
+ images,
119
+ totalRequests: 0, // Will be calculated from network events
120
+ };
121
+ });
122
+ return metrics;
123
+ }
124
+ }
125
+ exports.DOMAnalyzer = DOMAnalyzer;
126
+ //# sourceMappingURL=dom-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/dom-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { Page } from '@playwright/test';
2
+ import { LocatorsData } from '../types/capture';
3
+ export declare class LocatorGenerator {
4
+ generateLocators(page: Page): Promise<LocatorsData>;
5
+ private generateElementLocator;
6
+ private getRole;
7
+ private getAssociatedLabel;
8
+ /**
9
+ * Calculate match count and uniqueness for a locator strategy
10
+ */
11
+ private getMatchCount;
12
+ }
13
+ //# sourceMappingURL=locator-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locator-generator.d.ts","sourceRoot":"","sources":["../../src/analyzers/locator-generator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAA2B,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGzE,qBAAa,gBAAgB;IACrB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;YAmG3C,sBAAsB;YAyKtB,OAAO;YAuCP,kBAAkB;IAoChC;;OAEG;YACW,aAAa;CA4C5B"}