synapse-hub 2.4.1 → 2.4.2

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 (75) hide show
  1. package/.agents/rules/graphify.md +14 -14
  2. package/.agents/rules/mandatory-playwright-live.md +29 -29
  3. package/.agents/skills/bats-testing-patterns/resources/implementation-playbook.md +614 -614
  4. package/.agents/skills/clean-pom-crafter/examples/standard_test_case.groovy +28 -28
  5. package/.agents/skills/clean-pom-crafter/references/pom_patterns.groovy +138 -138
  6. package/.agents/skills/e2e-testing-patterns/resources/implementation-playbook.md +522 -522
  7. package/.agents/skills/failure-autopsy-and-healing/references/healing_matrix.md +64 -64
  8. package/.agents/skills/failure-autopsy-and-healing/references/qa_investigation_protocol.md +56 -56
  9. package/.agents/skills/failure-autopsy-and-healing/scripts/triage_failures.sh +98 -98
  10. package/.agents/skills/katalon-cli-runner/references/groovy-patterns.md +209 -209
  11. package/.agents/skills/katalon-cli-runner/references/katalon-api.md +155 -155
  12. package/.agents/skills/katalon-cli-runner/references/runner_commands.md +67 -67
  13. package/.agents/skills/playwright-live-interaction/references/advanced_superpowers.md +160 -160
  14. package/.agents/skills/playwright-live-interaction/references/compact_accessibility_snapshots.md +75 -75
  15. package/.agents/skills/playwright-live-interaction/references/recipes.md +388 -388
  16. package/.agents/skills/playwright-live-interaction/references/swarm_orchestration.md +134 -134
  17. package/.agents/skills/wcag-audit-patterns/resources/implementation-playbook.md +541 -541
  18. package/.agents/templates/completion_report.md +57 -57
  19. package/.agents/workflows/graphify.md +10 -10
  20. package/.cursor/rules/language.mdc +7 -7
  21. package/README.en.md +1 -1
  22. package/README.md +1 -1
  23. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-06_api_contract_drift.json +21 -21
  24. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-07_api_contract_drift.json +21 -21
  25. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-08_api_contract_drift.json +21 -21
  26. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-09_api_contract_drift.json +21 -21
  27. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-10_api_contract_drift.json +21 -21
  28. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-21_fake_pass_tautology.json +20 -20
  29. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-22_fake_pass_tautology.json +20 -20
  30. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-23_fake_pass_tautology.json +20 -20
  31. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-24_fake_pass_tautology.json +20 -20
  32. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-25_fake_pass_tautology.json +20 -20
  33. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-01_locator_drift.json +22 -22
  34. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-02_locator_drift.json +22 -22
  35. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-03_locator_drift.json +22 -22
  36. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-04_locator_drift.json +22 -22
  37. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-05_locator_drift.json +22 -22
  38. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-16_stale_and_mutation.json +21 -21
  39. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-17_stale_and_mutation.json +21 -21
  40. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-18_stale_and_mutation.json +21 -21
  41. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-19_stale_and_mutation.json +21 -21
  42. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-20_stale_and_mutation.json +22 -22
  43. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-11_timing_and_race.json +21 -21
  44. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-12_timing_and_race.json +21 -21
  45. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-13_timing_and_race.json +21 -21
  46. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-14_timing_and_race.json +21 -21
  47. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-15_timing_and_race.json +21 -21
  48. package/benchmarks/qa_eval/reports/BENCHMARK_REPORT.md +94 -69
  49. package/benchmarks/qa_eval/reports/eval_results.json +460 -104
  50. package/bin/agent-qa.js +0 -0
  51. package/docs/ARCHITECTURE.md +12 -1
  52. package/package.json +1 -1
  53. package/scripts/install.ps1 +112 -112
  54. package/scripts/lint_skills.ps1 +57 -57
  55. package/skills_manifest.json +1 -1
  56. package/synapse.config.json +1 -1
  57. package/tools/__init__.py +1 -1
  58. package/tools/agent_canary.py +501 -501
  59. package/tools/api_fuzzer.py +11 -2
  60. package/tools/browser_helpers.js +2 -2
  61. package/tools/bump_version.py +1 -0
  62. package/tools/cli.py +2 -2
  63. package/tools/dashboard_generator.py +2 -2
  64. package/tools/e2e_flow_prober.sh +0 -0
  65. package/tools/generate_allure_report.sh +0 -0
  66. package/tools/generate_test_reports.sh +0 -0
  67. package/tools/mcp_excel_server.py +3 -1
  68. package/tools/mcp_excel_server.sh +0 -0
  69. package/tools/mcp_server.py +1 -1
  70. package/tools/pinpoint_failure.py +88 -88
  71. package/tools/update_sentinel.py +3 -3
  72. package/tools/verify_all.sh +0 -0
  73. package/tools/visual_som_helper.py +14 -3
  74. package/tools/welcome_page.py +1 -1
  75. package/benchmarks/qa_eval/reports/AB_METHODOLOGY_REPORT.md +0 -83
@@ -1,160 +1,160 @@
1
- # 5 Advanced Superpowers & 5 AI Paradigms for Playwright Live Interaction
2
-
3
- In-depth technical reference for complex testing scenarios across enterprise web test suites.
4
-
5
- ---
6
-
7
- ## 1. Five Native Advanced Superpowers
8
-
9
- ### 1.1. Zero-Second Auth (Bypass Login Form)
10
- ```javascript
11
- // Step 1: Save storage state after login
12
- async (page) => {
13
- await page.context().storageState({ path: '.agents/session.json' });
14
- return { status: "Session saved successfully" };
15
- }
16
-
17
- // Step 2: Load stored session in subsequent contexts
18
- const context = await browser.newContext({ storageState: '.agents/session.json' });
19
- ```
20
-
21
- ### 1.2. Network Interception & Direct Seeding
22
- ```javascript
23
- async (page) => {
24
- page.on('request', request => {
25
- if (request.url().includes('/api/') && request.method() === 'POST') {
26
- console.log('API URL:', request.url());
27
- console.log('Headers:', request.headers());
28
- console.log('Payload:', request.postData());
29
- }
30
- });
31
- }
32
- ```
33
-
34
- ### 1.3. Accessibility Tree (AOM Snapshot — 90% Token Reduction)
35
- ```javascript
36
- async (page) => {
37
- const a11yTree = await page.accessibility.snapshot({
38
- interestingOnly: true // Captures interactive elements only
39
- });
40
- return a11yTree;
41
- }
42
- ```
43
-
44
- ### 1.4. Multi-Context Dual Role Testing (Parallel Roles)
45
- ```javascript
46
- async (browser) => {
47
- const specialistContext = await browser.newContext();
48
- const leaderContext = await browser.newContext();
49
-
50
- const pageSpecialist = await specialistContext.newPage();
51
- const pageLeader = await leaderContext.newPage();
52
-
53
- // Specialist submits dossier
54
- await pageSpecialist.goto('https://app.example.com/planning');
55
- // Leader reviews and approves
56
- await pageLeader.goto('https://app.example.com/planning-approval');
57
- }
58
- ```
59
-
60
- ### 1.5. API Route Mocking (Negative Scenarios & Fault Injection)
61
- ```javascript
62
- async (page) => {
63
- await page.route('**/api/**', route => {
64
- route.fulfill({
65
- status: 500,
66
- contentType: 'application/json',
67
- body: JSON.stringify({ message: 'Database connection failed!' })
68
- });
69
- });
70
-
71
- await page.locator('button:has-text("Lưu")').click();
72
- await page.waitForTimeout(500);
73
- const toastMsg = await page.locator('.p-toast-message').innerText();
74
- return { toastMsg };
75
- }
76
- ```
77
-
78
- ---
79
-
80
- ## 2. Five AI Engineering Paradigms
81
-
82
- ### 2.1. Self-Healing Locator Engine (Multi-Tier Fallback)
83
- ```javascript
84
- async (page, targetName) => {
85
- const strategies = [
86
- () => page.locator(`button[formcontrolname="${targetName}"]`),
87
- () => page.getByRole('button', { name: targetName }),
88
- () => page.locator(`button:has-text("${targetName}")`),
89
- () => page.locator(`button[title*="${targetName}"]`),
90
- () => page.locator(`.p-button:has-text("${targetName}")`)
91
- ];
92
-
93
- for (const getLocator of strategies) {
94
- const loc = getLocator();
95
- if (await loc.count() > 0 && await loc.first().isVisible()) {
96
- return loc.first(); // Self-healed successfully
97
- }
98
- }
99
- throw new Error(`Self-healing failed: Element not found: ${targetName}`);
100
- }
101
- ```
102
-
103
- ### 2.2. Multimodal Visual Verification (GIS & Layout)
104
- ```javascript
105
- async (page) => {
106
- const mapElement = page.locator('div.ol-viewport');
107
- const screenshotBuffer = await mapElement.screenshot({ path: '.agents/screenshots/gis_canvas_live.png' });
108
- const box = await mapElement.boundingBox();
109
- return {
110
- isRenderedProperly: box && box.width > 300 && box.height > 200,
111
- width: box ? box.width : 0,
112
- height: box ? box.height : 0,
113
- screenshotPath: '.agents/screenshots/gis_canvas_live.png'
114
- };
115
- }
116
- ```
117
-
118
- ### 2.3. Autonomous Exploratory Fuzzing (Edge & Crash Hunting)
119
- ```javascript
120
- async (page) => {
121
- const edgePayloads = [
122
- "'-DROP TABLE--",
123
- "<script>alert(1)</script>",
124
- "-99999999",
125
- " ",
126
- "A".repeat(500)
127
- ];
128
- const results = [];
129
- const input = page.locator('input[formcontrolname="code"]').first();
130
-
131
- for (const payload of edgePayloads) {
132
- await input.fill(payload);
133
- await page.locator('button:has-text("Lưu"), button:has-text("Xác nhận")').first().click();
134
- await page.waitForTimeout(600);
135
-
136
- const hasCrash = await page.evaluate(() => {
137
- const text = document.body.innerText;
138
- return text.includes('500 Internal') || text.includes('HttpErrorResponse');
139
- });
140
- results.push({ payload, hasCrash });
141
- }
142
- return results;
143
- }
144
- ```
145
-
146
- ### 2.4. CDP Deep Profiling (RAM & Heap Monitoring)
147
- ```javascript
148
- async (page) => {
149
- const memoryInfo = await page.evaluate(() => {
150
- return window.performance && window.performance.memory ? {
151
- usedJSHeapSizeMB: (window.performance.memory.usedJSHeapSize / (1024 * 1024)).toFixed(2),
152
- totalJSHeapSizeMB: (window.performance.memory.totalJSHeapSize / (1024 * 1024)).toFixed(2)
153
- } : { note: "Memory API only available in Chromium" };
154
- });
155
- return memoryInfo;
156
- }
157
- ```
158
-
159
- ### 2.5. Multi-Agent Swarm Orchestration
160
- For swarm roles (Lead Orchestrator, Live Explorer, Code Crafter, Test Runner, Quality Gatekeeper, Scribe), refer to [swarm_orchestration.md](swarm_orchestration.md).
1
+ # 5 Advanced Superpowers & 5 AI Paradigms for Playwright Live Interaction
2
+
3
+ In-depth technical reference for complex testing scenarios across enterprise web test suites.
4
+
5
+ ---
6
+
7
+ ## 1. Five Native Advanced Superpowers
8
+
9
+ ### 1.1. Zero-Second Auth (Bypass Login Form)
10
+ ```javascript
11
+ // Step 1: Save storage state after login
12
+ async (page) => {
13
+ await page.context().storageState({ path: '.agents/session.json' });
14
+ return { status: "Session saved successfully" };
15
+ }
16
+
17
+ // Step 2: Load stored session in subsequent contexts
18
+ const context = await browser.newContext({ storageState: '.agents/session.json' });
19
+ ```
20
+
21
+ ### 1.2. Network Interception & Direct Seeding
22
+ ```javascript
23
+ async (page) => {
24
+ page.on('request', request => {
25
+ if (request.url().includes('/api/') && request.method() === 'POST') {
26
+ console.log('API URL:', request.url());
27
+ console.log('Headers:', request.headers());
28
+ console.log('Payload:', request.postData());
29
+ }
30
+ });
31
+ }
32
+ ```
33
+
34
+ ### 1.3. Accessibility Tree (AOM Snapshot — 90% Token Reduction)
35
+ ```javascript
36
+ async (page) => {
37
+ const a11yTree = await page.accessibility.snapshot({
38
+ interestingOnly: true // Captures interactive elements only
39
+ });
40
+ return a11yTree;
41
+ }
42
+ ```
43
+
44
+ ### 1.4. Multi-Context Dual Role Testing (Parallel Roles)
45
+ ```javascript
46
+ async (browser) => {
47
+ const specialistContext = await browser.newContext();
48
+ const leaderContext = await browser.newContext();
49
+
50
+ const pageSpecialist = await specialistContext.newPage();
51
+ const pageLeader = await leaderContext.newPage();
52
+
53
+ // Specialist submits dossier
54
+ await pageSpecialist.goto('https://app.example.com/planning');
55
+ // Leader reviews and approves
56
+ await pageLeader.goto('https://app.example.com/planning-approval');
57
+ }
58
+ ```
59
+
60
+ ### 1.5. API Route Mocking (Negative Scenarios & Fault Injection)
61
+ ```javascript
62
+ async (page) => {
63
+ await page.route('**/api/**', route => {
64
+ route.fulfill({
65
+ status: 500,
66
+ contentType: 'application/json',
67
+ body: JSON.stringify({ message: 'Database connection failed!' })
68
+ });
69
+ });
70
+
71
+ await page.locator('button:has-text("Lưu")').click();
72
+ await page.waitForTimeout(500);
73
+ const toastMsg = await page.locator('.p-toast-message').innerText();
74
+ return { toastMsg };
75
+ }
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 2. Five AI Engineering Paradigms
81
+
82
+ ### 2.1. Self-Healing Locator Engine (Multi-Tier Fallback)
83
+ ```javascript
84
+ async (page, targetName) => {
85
+ const strategies = [
86
+ () => page.locator(`button[formcontrolname="${targetName}"]`),
87
+ () => page.getByRole('button', { name: targetName }),
88
+ () => page.locator(`button:has-text("${targetName}")`),
89
+ () => page.locator(`button[title*="${targetName}"]`),
90
+ () => page.locator(`.p-button:has-text("${targetName}")`)
91
+ ];
92
+
93
+ for (const getLocator of strategies) {
94
+ const loc = getLocator();
95
+ if (await loc.count() > 0 && await loc.first().isVisible()) {
96
+ return loc.first(); // Self-healed successfully
97
+ }
98
+ }
99
+ throw new Error(`Self-healing failed: Element not found: ${targetName}`);
100
+ }
101
+ ```
102
+
103
+ ### 2.2. Multimodal Visual Verification (GIS & Layout)
104
+ ```javascript
105
+ async (page) => {
106
+ const mapElement = page.locator('div.ol-viewport');
107
+ const screenshotBuffer = await mapElement.screenshot({ path: '.agents/screenshots/gis_canvas_live.png' });
108
+ const box = await mapElement.boundingBox();
109
+ return {
110
+ isRenderedProperly: box && box.width > 300 && box.height > 200,
111
+ width: box ? box.width : 0,
112
+ height: box ? box.height : 0,
113
+ screenshotPath: '.agents/screenshots/gis_canvas_live.png'
114
+ };
115
+ }
116
+ ```
117
+
118
+ ### 2.3. Autonomous Exploratory Fuzzing (Edge & Crash Hunting)
119
+ ```javascript
120
+ async (page) => {
121
+ const edgePayloads = [
122
+ "'-DROP TABLE--",
123
+ "<script>alert(1)</script>",
124
+ "-99999999",
125
+ " ",
126
+ "A".repeat(500)
127
+ ];
128
+ const results = [];
129
+ const input = page.locator('input[formcontrolname="code"]').first();
130
+
131
+ for (const payload of edgePayloads) {
132
+ await input.fill(payload);
133
+ await page.locator('button:has-text("Lưu"), button:has-text("Xác nhận")').first().click();
134
+ await page.waitForTimeout(600);
135
+
136
+ const hasCrash = await page.evaluate(() => {
137
+ const text = document.body.innerText;
138
+ return text.includes('500 Internal') || text.includes('HttpErrorResponse');
139
+ });
140
+ results.push({ payload, hasCrash });
141
+ }
142
+ return results;
143
+ }
144
+ ```
145
+
146
+ ### 2.4. CDP Deep Profiling (RAM & Heap Monitoring)
147
+ ```javascript
148
+ async (page) => {
149
+ const memoryInfo = await page.evaluate(() => {
150
+ return window.performance && window.performance.memory ? {
151
+ usedJSHeapSizeMB: (window.performance.memory.usedJSHeapSize / (1024 * 1024)).toFixed(2),
152
+ totalJSHeapSizeMB: (window.performance.memory.totalJSHeapSize / (1024 * 1024)).toFixed(2)
153
+ } : { note: "Memory API only available in Chromium" };
154
+ });
155
+ return memoryInfo;
156
+ }
157
+ ```
158
+
159
+ ### 2.5. Multi-Agent Swarm Orchestration
160
+ For swarm roles (Lead Orchestrator, Live Explorer, Code Crafter, Test Runner, Quality Gatekeeper, Scribe), refer to [swarm_orchestration.md](swarm_orchestration.md).
@@ -1,75 +1,75 @@
1
- # Compact Accessibility-Tree Snapshots for PrimeNG Inspection
2
-
3
- *(Inherited from `vercel-labs/agent-browser`)*
4
-
5
- A token-efficient browser inspection technique for exploring enterprise Angular & PrimeNG single-page interface without dumping heavy raw DOM HTML.
6
-
7
- ---
8
-
9
- ## 1. Problem: The Raw HTML Token Trap
10
-
11
- On modern Angular/PrimeNG applications:
12
- - A single complex screen (e.g. `DataMiningPage` with GIS Canvas, sidebar, and multi-field dialogs) contains **3,000+ lines of HTML**.
13
- - Dumping raw DOM trees consumes **15,000 to 30,000 tokens** per inspection, cluttering the agent's context window.
14
-
15
- ---
16
-
17
- ## 2. Solution: Semantic Accessibility Snapshot
18
-
19
- Following the `agent-browser` architecture, we extract a **Compact Accessibility Tree** focused exclusively on interactive elements (`button`, `input`, `select`, `p-dropdown`, `p-calendar`, `p-table` headers and rows) assigned with lightweight identifier references (`@e1`, `@e2`, ...).
20
-
21
- ### 2.1. In-Browser JavaScript Extractor
22
- Inject the following lightweight snippet via Playwright browser evaluate:
23
-
24
- ```javascript
25
- (() => {
26
- const interactiveSelectors = [
27
- 'button:not([disabled])',
28
- 'input:not([type="hidden"])',
29
- 'select',
30
- 'textarea',
31
- 'p-dropdown',
32
- 'p-calendar input',
33
- 'p-multiselect',
34
- 'a[href]',
35
- '[role="button"]',
36
- '[role="dialog"]',
37
- '.p-toast-message'
38
- ];
39
-
40
- const elements = Array.from(document.querySelectorAll(interactiveSelectors.join(',')))
41
- .filter(el => {
42
- const rect = el.getBoundingClientRect();
43
- return rect.width > 0 && rect.height > 0 && window.getComputedStyle(el).visibility !== 'hidden';
44
- });
45
-
46
- return elements.map((el, idx) => {
47
- const tag = el.tagName.toLowerCase();
48
- const type = el.getAttribute('type') || '';
49
- const name = el.getAttribute('name') || el.getAttribute('formcontrolname') || '';
50
- const label = (el.innerText || el.placeholder || el.getAttribute('aria-label') || el.title || '').trim().replace(/\s+/g, ' ').slice(0, 50);
51
- const role = el.getAttribute('role') || tag;
52
- return `[@e${idx + 1}] <${tag}${type ? ' type=' + type : ''}${name ? ' name=' + name : ''}> "${label}"`;
53
- }).join('\n');
54
- })();
55
- ```
56
-
57
- ### 2.2. Sample Compact Output (Under 500 Tokens vs 25,000 Tokens)
58
-
59
- ```text
60
- [@e1] <input name=username> "Tên đăng nhập"
61
- [@e2] <input type=password name=password> "Mật khẩu"
62
- [@e3] <button type=submit> "Đăng nhập"
63
- [@e4] <p-dropdown name=layerSelect> "Chọn lớp dữ liệu"
64
- [@e5] <input placeholder="Nhập từ khóa tìm kiếm..."> "Tìm kiếm"
65
- [@e6] <button> "Thêm mới"
66
- [@e7] <button title="Xóa"> "Xóa"
67
- ```
68
-
69
- ---
70
-
71
- ## 3. Benefits for Enterprise Test Automation
72
-
73
- 1. **Token Savings:** Reduces DOM inspection size by **90% - 95%**.
74
- 2. **Speed:** Instant parsing in `< 20ms`.
75
- 3. **Selector Mapping:** Once an element reference `@eN` is identified on screen, map it directly into the Clean POM Page Class using `BasePage.x()`.
1
+ # Compact Accessibility-Tree Snapshots for PrimeNG Inspection
2
+
3
+ *(Inherited from `vercel-labs/agent-browser`)*
4
+
5
+ A token-efficient browser inspection technique for exploring enterprise Angular & PrimeNG single-page interface without dumping heavy raw DOM HTML.
6
+
7
+ ---
8
+
9
+ ## 1. Problem: The Raw HTML Token Trap
10
+
11
+ On modern Angular/PrimeNG applications:
12
+ - A single complex screen (e.g. `DataMiningPage` with GIS Canvas, sidebar, and multi-field dialogs) contains **3,000+ lines of HTML**.
13
+ - Dumping raw DOM trees consumes **15,000 to 30,000 tokens** per inspection, cluttering the agent's context window.
14
+
15
+ ---
16
+
17
+ ## 2. Solution: Semantic Accessibility Snapshot
18
+
19
+ Following the `agent-browser` architecture, we extract a **Compact Accessibility Tree** focused exclusively on interactive elements (`button`, `input`, `select`, `p-dropdown`, `p-calendar`, `p-table` headers and rows) assigned with lightweight identifier references (`@e1`, `@e2`, ...).
20
+
21
+ ### 2.1. In-Browser JavaScript Extractor
22
+ Inject the following lightweight snippet via Playwright browser evaluate:
23
+
24
+ ```javascript
25
+ (() => {
26
+ const interactiveSelectors = [
27
+ 'button:not([disabled])',
28
+ 'input:not([type="hidden"])',
29
+ 'select',
30
+ 'textarea',
31
+ 'p-dropdown',
32
+ 'p-calendar input',
33
+ 'p-multiselect',
34
+ 'a[href]',
35
+ '[role="button"]',
36
+ '[role="dialog"]',
37
+ '.p-toast-message'
38
+ ];
39
+
40
+ const elements = Array.from(document.querySelectorAll(interactiveSelectors.join(',')))
41
+ .filter(el => {
42
+ const rect = el.getBoundingClientRect();
43
+ return rect.width > 0 && rect.height > 0 && window.getComputedStyle(el).visibility !== 'hidden';
44
+ });
45
+
46
+ return elements.map((el, idx) => {
47
+ const tag = el.tagName.toLowerCase();
48
+ const type = el.getAttribute('type') || '';
49
+ const name = el.getAttribute('name') || el.getAttribute('formcontrolname') || '';
50
+ const label = (el.innerText || el.placeholder || el.getAttribute('aria-label') || el.title || '').trim().replace(/\s+/g, ' ').slice(0, 50);
51
+ const role = el.getAttribute('role') || tag;
52
+ return `[@e${idx + 1}] <${tag}${type ? ' type=' + type : ''}${name ? ' name=' + name : ''}> "${label}"`;
53
+ }).join('\n');
54
+ })();
55
+ ```
56
+
57
+ ### 2.2. Sample Compact Output (Under 500 Tokens vs 25,000 Tokens)
58
+
59
+ ```text
60
+ [@e1] <input name=username> "Tên đăng nhập"
61
+ [@e2] <input type=password name=password> "Mật khẩu"
62
+ [@e3] <button type=submit> "Đăng nhập"
63
+ [@e4] <p-dropdown name=layerSelect> "Chọn lớp dữ liệu"
64
+ [@e5] <input placeholder="Nhập từ khóa tìm kiếm..."> "Tìm kiếm"
65
+ [@e6] <button> "Thêm mới"
66
+ [@e7] <button title="Xóa"> "Xóa"
67
+ ```
68
+
69
+ ---
70
+
71
+ ## 3. Benefits for Enterprise Test Automation
72
+
73
+ 1. **Token Savings:** Reduces DOM inspection size by **90% - 95%**.
74
+ 2. **Speed:** Instant parsing in `< 20ms`.
75
+ 3. **Selector Mapping:** Once an element reference `@eN` is identified on screen, map it directly into the Clean POM Page Class using `BasePage.x()`.