explorbot 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +94 -0
- package/README.md +267 -0
- package/assets/sample-files/sample.docx +0 -0
- package/assets/sample-files/sample.mp3 +0 -0
- package/assets/sample-files/sample.mp4 +0 -0
- package/assets/sample-files/sample.pdf +21 -0
- package/assets/sample-files/sample.png +0 -0
- package/assets/sample-files/sample.xlsx +0 -0
- package/assets/sample-files/sample.zip +0 -0
- package/dist/assets/sample-files/sample.docx +0 -0
- package/dist/assets/sample-files/sample.mp3 +0 -0
- package/dist/assets/sample-files/sample.mp4 +0 -0
- package/dist/assets/sample-files/sample.pdf +21 -0
- package/dist/assets/sample-files/sample.png +0 -0
- package/dist/assets/sample-files/sample.xlsx +0 -0
- package/dist/assets/sample-files/sample.zip +0 -0
- package/dist/bin/explorbot-cli.js +683 -0
- package/dist/bin/explorbot-cli.js.map +1 -0
- package/dist/boat/api-tester/bin/apibot-cli.js +5 -0
- package/dist/boat/api-tester/bin/apibot-cli.js.map +1 -0
- package/dist/boat/api-tester/example/apibot.config.js +31 -0
- package/dist/boat/api-tester/example/apibot.config.js.map +1 -0
- package/dist/boat/api-tester/src/ai/chief/styles.js +13 -0
- package/dist/boat/api-tester/src/ai/chief/styles.js.map +1 -0
- package/dist/boat/api-tester/src/ai/chief.js +301 -0
- package/dist/boat/api-tester/src/ai/chief.js.map +1 -0
- package/dist/boat/api-tester/src/ai/curler-tools.js +263 -0
- package/dist/boat/api-tester/src/ai/curler-tools.js.map +1 -0
- package/dist/boat/api-tester/src/ai/curler.js +271 -0
- package/dist/boat/api-tester/src/ai/curler.js.map +1 -0
- package/dist/boat/api-tester/src/api-client.js +26 -0
- package/dist/boat/api-tester/src/api-client.js.map +1 -0
- package/dist/boat/api-tester/src/apibot.js +166 -0
- package/dist/boat/api-tester/src/apibot.js.map +1 -0
- package/dist/boat/api-tester/src/cli.js +262 -0
- package/dist/boat/api-tester/src/cli.js.map +1 -0
- package/dist/boat/api-tester/src/config.js +159 -0
- package/dist/boat/api-tester/src/config.js.map +1 -0
- package/dist/prompts/audit-rules.md +124 -0
- package/dist/rules/chief/general.md +11 -0
- package/dist/rules/chief/styles/curious.md +12 -0
- package/dist/rules/chief/styles/hacker.md +19 -0
- package/dist/rules/chief/styles/normal.md +11 -0
- package/dist/rules/chief/styles/psycho.md +17 -0
- package/dist/rules/navigator/multiple-locator.md +47 -0
- package/dist/rules/navigator/output.md +69 -0
- package/dist/rules/navigator/verification-actions.md +122 -0
- package/dist/rules/navigator/verification-output.md +53 -0
- package/dist/rules/planner/styles/curious.md +39 -0
- package/dist/rules/planner/styles/normal.md +21 -0
- package/dist/rules/planner/styles/psycho.md +14 -0
- package/dist/rules/researcher/list-element.md +11 -0
- package/dist/rules/researcher/screenshot-ui-map.md +30 -0
- package/dist/rules/researcher/section-ui-map.md +18 -0
- package/dist/rules/researcher/ui-map-table.md +18 -0
- package/dist/src/action-result.js +574 -0
- package/dist/src/action-result.js.map +1 -0
- package/dist/src/action.js +388 -0
- package/dist/src/action.js.map +1 -0
- package/dist/src/activity.js +86 -0
- package/dist/src/activity.js.map +1 -0
- package/dist/src/ai/agent.js +2 -0
- package/dist/src/ai/agent.js.map +1 -0
- package/dist/src/ai/bosun.js +443 -0
- package/dist/src/ai/bosun.js.map +1 -0
- package/dist/src/ai/captain/idle-mode.js +102 -0
- package/dist/src/ai/captain/idle-mode.js.map +1 -0
- package/dist/src/ai/captain/mixin.js +11 -0
- package/dist/src/ai/captain/mixin.js.map +1 -0
- package/dist/src/ai/captain/test-mode.js +251 -0
- package/dist/src/ai/captain/test-mode.js.map +1 -0
- package/dist/src/ai/captain/web-mode.js +124 -0
- package/dist/src/ai/captain/web-mode.js.map +1 -0
- package/dist/src/ai/captain.js +442 -0
- package/dist/src/ai/captain.js.map +1 -0
- package/dist/src/ai/conversation.js +176 -0
- package/dist/src/ai/conversation.js.map +1 -0
- package/dist/src/ai/experience-compactor.js +232 -0
- package/dist/src/ai/experience-compactor.js.map +1 -0
- package/dist/src/ai/fisherman-tools.js +154 -0
- package/dist/src/ai/fisherman-tools.js.map +1 -0
- package/dist/src/ai/fisherman.js +184 -0
- package/dist/src/ai/fisherman.js.map +1 -0
- package/dist/src/ai/historian.js +384 -0
- package/dist/src/ai/historian.js.map +1 -0
- package/dist/src/ai/navigator.js +493 -0
- package/dist/src/ai/navigator.js.map +1 -0
- package/dist/src/ai/pilot.js +684 -0
- package/dist/src/ai/pilot.js.map +1 -0
- package/dist/src/ai/planner/session-dedup.js +28 -0
- package/dist/src/ai/planner/session-dedup.js.map +1 -0
- package/dist/src/ai/planner/styles.js +15 -0
- package/dist/src/ai/planner/styles.js.map +1 -0
- package/dist/src/ai/planner/subpages.js +118 -0
- package/dist/src/ai/planner/subpages.js.map +1 -0
- package/dist/src/ai/planner.js +486 -0
- package/dist/src/ai/planner.js.map +1 -0
- package/dist/src/ai/provider.js +540 -0
- package/dist/src/ai/provider.js.map +1 -0
- package/dist/src/ai/quartermaster.js +210 -0
- package/dist/src/ai/quartermaster.js.map +1 -0
- package/dist/src/ai/researcher/cache.js +95 -0
- package/dist/src/ai/researcher/cache.js.map +1 -0
- package/dist/src/ai/researcher/coordinates.js +210 -0
- package/dist/src/ai/researcher/coordinates.js.map +1 -0
- package/dist/src/ai/researcher/deep-analysis.js +364 -0
- package/dist/src/ai/researcher/deep-analysis.js.map +1 -0
- package/dist/src/ai/researcher/fingerprint-worker.js +46 -0
- package/dist/src/ai/researcher/fingerprint-worker.js.map +1 -0
- package/dist/src/ai/researcher/focus.js +37 -0
- package/dist/src/ai/researcher/focus.js.map +1 -0
- package/dist/src/ai/researcher/locators.js +242 -0
- package/dist/src/ai/researcher/locators.js.map +1 -0
- package/dist/src/ai/researcher/mixin.js +3 -0
- package/dist/src/ai/researcher/mixin.js.map +1 -0
- package/dist/src/ai/researcher/parser.js +160 -0
- package/dist/src/ai/researcher/parser.js.map +1 -0
- package/dist/src/ai/researcher/research-result.js +110 -0
- package/dist/src/ai/researcher/research-result.js.map +1 -0
- package/dist/src/ai/researcher.js +776 -0
- package/dist/src/ai/researcher.js.map +1 -0
- package/dist/src/ai/rules.js +368 -0
- package/dist/src/ai/rules.js.map +1 -0
- package/dist/src/ai/task-agent.js +110 -0
- package/dist/src/ai/task-agent.js.map +1 -0
- package/dist/src/ai/tester.js +840 -0
- package/dist/src/ai/tester.js.map +1 -0
- package/dist/src/ai/tools.js +980 -0
- package/dist/src/ai/tools.js.map +1 -0
- package/dist/src/api/api-client.js +91 -0
- package/dist/src/api/api-client.js.map +1 -0
- package/dist/src/api/request-result.js +177 -0
- package/dist/src/api/request-result.js.map +1 -0
- package/dist/src/api/request-store.js +109 -0
- package/dist/src/api/request-store.js.map +1 -0
- package/dist/src/api/spec-reader.js +148 -0
- package/dist/src/api/spec-reader.js.map +1 -0
- package/dist/src/api/xhr-capture.js +91 -0
- package/dist/src/api/xhr-capture.js.map +1 -0
- package/dist/src/browser-server.js +67 -0
- package/dist/src/browser-server.js.map +1 -0
- package/dist/src/command-handler.js +363 -0
- package/dist/src/command-handler.js.map +1 -0
- package/dist/src/commands/add-rule-command.js +52 -0
- package/dist/src/commands/add-rule-command.js.map +1 -0
- package/dist/src/commands/base-command.js +14 -0
- package/dist/src/commands/base-command.js.map +1 -0
- package/dist/src/commands/clean-command.js +67 -0
- package/dist/src/commands/clean-command.js.map +1 -0
- package/dist/src/commands/context-aria-command.js +18 -0
- package/dist/src/commands/context-aria-command.js.map +1 -0
- package/dist/src/commands/context-command.js +57 -0
- package/dist/src/commands/context-command.js.map +1 -0
- package/dist/src/commands/context-data-command.js +25 -0
- package/dist/src/commands/context-data-command.js.map +1 -0
- package/dist/src/commands/context-experience-command.js +41 -0
- package/dist/src/commands/context-experience-command.js.map +1 -0
- package/dist/src/commands/context-html-command.js +26 -0
- package/dist/src/commands/context-html-command.js.map +1 -0
- package/dist/src/commands/context-knowledge-command.js +36 -0
- package/dist/src/commands/context-knowledge-command.js.map +1 -0
- package/dist/src/commands/debug-command.js +12 -0
- package/dist/src/commands/debug-command.js.map +1 -0
- package/dist/src/commands/drill-command.js +29 -0
- package/dist/src/commands/drill-command.js.map +1 -0
- package/dist/src/commands/exit-command.js +26 -0
- package/dist/src/commands/exit-command.js.map +1 -0
- package/dist/src/commands/explore-command.js +124 -0
- package/dist/src/commands/explore-command.js.map +1 -0
- package/dist/src/commands/freesail-command.js +84 -0
- package/dist/src/commands/freesail-command.js.map +1 -0
- package/dist/src/commands/help-command.js +7 -0
- package/dist/src/commands/help-command.js.map +1 -0
- package/dist/src/commands/index.js +63 -0
- package/dist/src/commands/index.js.map +1 -0
- package/dist/src/commands/knows-command.js +54 -0
- package/dist/src/commands/knows-command.js.map +1 -0
- package/dist/src/commands/learn-command.js +35 -0
- package/dist/src/commands/learn-command.js.map +1 -0
- package/dist/src/commands/navigate-command.js +16 -0
- package/dist/src/commands/navigate-command.js.map +1 -0
- package/dist/src/commands/path-command.js +70 -0
- package/dist/src/commands/path-command.js.map +1 -0
- package/dist/src/commands/plan-clear-command.js +13 -0
- package/dist/src/commands/plan-clear-command.js.map +1 -0
- package/dist/src/commands/plan-command.js +36 -0
- package/dist/src/commands/plan-command.js.map +1 -0
- package/dist/src/commands/plan-edit-command.js +8 -0
- package/dist/src/commands/plan-edit-command.js.map +1 -0
- package/dist/src/commands/plan-load-command.js +16 -0
- package/dist/src/commands/plan-load-command.js.map +1 -0
- package/dist/src/commands/plan-reload-command.js +23 -0
- package/dist/src/commands/plan-reload-command.js.map +1 -0
- package/dist/src/commands/plan-save-command.js +22 -0
- package/dist/src/commands/plan-save-command.js.map +1 -0
- package/dist/src/commands/research-command.js +38 -0
- package/dist/src/commands/research-command.js.map +1 -0
- package/dist/src/commands/start-command.js +12 -0
- package/dist/src/commands/start-command.js.map +1 -0
- package/dist/src/commands/status-command.js +19 -0
- package/dist/src/commands/status-command.js.map +1 -0
- package/dist/src/commands/test-command.js +85 -0
- package/dist/src/commands/test-command.js.map +1 -0
- package/dist/src/components/ActivityPane.js +55 -0
- package/dist/src/components/ActivityPane.js.map +1 -0
- package/dist/src/components/AddKnowledge.js +122 -0
- package/dist/src/components/AddKnowledge.js.map +1 -0
- package/dist/src/components/AddRule.js +117 -0
- package/dist/src/components/AddRule.js.map +1 -0
- package/dist/src/components/App.js +313 -0
- package/dist/src/components/App.js.map +1 -0
- package/dist/src/components/Autocomplete.js +43 -0
- package/dist/src/components/Autocomplete.js.map +1 -0
- package/dist/src/components/InputPane.js +207 -0
- package/dist/src/components/InputPane.js.map +1 -0
- package/dist/src/components/InputReadline.js +598 -0
- package/dist/src/components/InputReadline.js.map +1 -0
- package/dist/src/components/LogPane.js +123 -0
- package/dist/src/components/LogPane.js.map +1 -0
- package/dist/src/components/PlanEditor.js +126 -0
- package/dist/src/components/PlanEditor.js.map +1 -0
- package/dist/src/components/PlanPane.js +51 -0
- package/dist/src/components/PlanPane.js.map +1 -0
- package/dist/src/components/SessionTimer.js +26 -0
- package/dist/src/components/SessionTimer.js.map +1 -0
- package/dist/src/components/StateTransitionPane.js +107 -0
- package/dist/src/components/StateTransitionPane.js.map +1 -0
- package/dist/src/components/StatusPane.js +37 -0
- package/dist/src/components/StatusPane.js.map +1 -0
- package/dist/src/components/TaskPane.js +96 -0
- package/dist/src/components/TaskPane.js.map +1 -0
- package/dist/src/components/Welcome.js +52 -0
- package/dist/src/components/Welcome.js.map +1 -0
- package/dist/src/components/WelcomeChecklist.js +96 -0
- package/dist/src/components/WelcomeChecklist.js.map +1 -0
- package/dist/src/components/WelcomeCommands.js +61 -0
- package/dist/src/components/WelcomeCommands.js.map +1 -0
- package/dist/src/components/autocomplete-store.js +22 -0
- package/dist/src/components/autocomplete-store.js.map +1 -0
- package/dist/src/components/parse-keypress.js +174 -0
- package/dist/src/components/parse-keypress.js.map +1 -0
- package/dist/src/config.js +249 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/execution-controller.js +92 -0
- package/dist/src/execution-controller.js.map +1 -0
- package/dist/src/experience-tracker.js +294 -0
- package/dist/src/experience-tracker.js.map +1 -0
- package/dist/src/explorbot.js +348 -0
- package/dist/src/explorbot.js.map +1 -0
- package/dist/src/explorer.js +611 -0
- package/dist/src/explorer.js.map +1 -0
- package/dist/src/index.js +56 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/knowledge-tracker.js +184 -0
- package/dist/src/knowledge-tracker.js.map +1 -0
- package/dist/src/observability.js +126 -0
- package/dist/src/observability.js.map +1 -0
- package/dist/src/reporter.js +185 -0
- package/dist/src/reporter.js.map +1 -0
- package/dist/src/state-manager.js +427 -0
- package/dist/src/state-manager.js.map +1 -0
- package/dist/src/stats.js +44 -0
- package/dist/src/stats.js.map +1 -0
- package/dist/src/test-plan.js +343 -0
- package/dist/src/test-plan.js.map +1 -0
- package/dist/src/utils/aria.js +588 -0
- package/dist/src/utils/aria.js.map +1 -0
- package/dist/src/utils/code-extractor.js +21 -0
- package/dist/src/utils/code-extractor.js.map +1 -0
- package/dist/src/utils/context-formatter.js +205 -0
- package/dist/src/utils/context-formatter.js.map +1 -0
- package/dist/src/utils/error-page.js +19 -0
- package/dist/src/utils/error-page.js.map +1 -0
- package/dist/src/utils/expandable.js +35 -0
- package/dist/src/utils/expandable.js.map +1 -0
- package/dist/src/utils/hooks-runner.js +77 -0
- package/dist/src/utils/hooks-runner.js.map +1 -0
- package/dist/src/utils/html-diff.js +734 -0
- package/dist/src/utils/html-diff.js.map +1 -0
- package/dist/src/utils/html.js +1163 -0
- package/dist/src/utils/html.js.map +1 -0
- package/dist/src/utils/logger.js +465 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/loop.js +126 -0
- package/dist/src/utils/loop.js.map +1 -0
- package/dist/src/utils/markdown-parser.js +117 -0
- package/dist/src/utils/markdown-parser.js.map +1 -0
- package/dist/src/utils/markdown-query.js +393 -0
- package/dist/src/utils/markdown-query.js.map +1 -0
- package/dist/src/utils/markdown-terminal.js +40 -0
- package/dist/src/utils/markdown-terminal.js.map +1 -0
- package/dist/src/utils/research-parser.js +2 -0
- package/dist/src/utils/research-parser.js.map +1 -0
- package/dist/src/utils/retry.js +55 -0
- package/dist/src/utils/retry.js.map +1 -0
- package/dist/src/utils/rules-loader.js +104 -0
- package/dist/src/utils/rules-loader.js.map +1 -0
- package/dist/src/utils/strings.js +14 -0
- package/dist/src/utils/strings.js.map +1 -0
- package/dist/src/utils/test-plan-markdown.js +301 -0
- package/dist/src/utils/test-plan-markdown.js.map +1 -0
- package/dist/src/utils/throttle.js +16 -0
- package/dist/src/utils/throttle.js.map +1 -0
- package/dist/src/utils/unique-names.js +13 -0
- package/dist/src/utils/unique-names.js.map +1 -0
- package/dist/src/utils/url-matcher.js +48 -0
- package/dist/src/utils/url-matcher.js.map +1 -0
- package/dist/src/utils/web-element.js +131 -0
- package/dist/src/utils/web-element.js.map +1 -0
- package/dist/src/utils/xpath.js +110 -0
- package/dist/src/utils/xpath.js.map +1 -0
- package/package.json +119 -0
- package/prompts/audit-rules.md +124 -0
- package/rules/chief/general.md +11 -0
- package/rules/chief/styles/curious.md +12 -0
- package/rules/chief/styles/hacker.md +19 -0
- package/rules/chief/styles/normal.md +11 -0
- package/rules/chief/styles/psycho.md +17 -0
- package/rules/navigator/multiple-locator.md +47 -0
- package/rules/navigator/output.md +69 -0
- package/rules/navigator/verification-actions.md +122 -0
- package/rules/navigator/verification-output.md +53 -0
- package/rules/planner/styles/curious.md +39 -0
- package/rules/planner/styles/normal.md +21 -0
- package/rules/planner/styles/psycho.md +14 -0
- package/rules/researcher/list-element.md +11 -0
- package/rules/researcher/screenshot-ui-map.md +30 -0
- package/rules/researcher/section-ui-map.md +18 -0
- package/rules/researcher/ui-map-table.md +18 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import micromatch from 'micromatch';
|
|
2
|
+
export function matchesUrl(pattern, path) {
|
|
3
|
+
if (pattern === '*')
|
|
4
|
+
return true;
|
|
5
|
+
const norm = (s) => s?.replace(/\/+$/, '').toLowerCase();
|
|
6
|
+
if (norm(pattern) === norm(path))
|
|
7
|
+
return true;
|
|
8
|
+
if (pattern.endsWith('/*')) {
|
|
9
|
+
const base = pattern.slice(0, -2).replace(/\/+$/, '');
|
|
10
|
+
const normPath = path.replace(/\/+$/, '');
|
|
11
|
+
if (normPath === base || path.startsWith(`${base}/`))
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
if (pattern.startsWith('^')) {
|
|
15
|
+
try {
|
|
16
|
+
return new RegExp(pattern.slice(1)).test(path);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (pattern.startsWith('~') && pattern.endsWith('~') && pattern.length > 2) {
|
|
23
|
+
try {
|
|
24
|
+
return new RegExp(pattern.slice(1, -1)).test(path);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
return micromatch.isMatch(path, pattern);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function extractStatePath(url) {
|
|
38
|
+
if (url.startsWith('/'))
|
|
39
|
+
return url;
|
|
40
|
+
try {
|
|
41
|
+
const urlObj = new URL(url);
|
|
42
|
+
return urlObj.pathname + urlObj.hash;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return url;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=url-matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-matcher.js","sourceRoot":"","sources":["../../../src/utils/url-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,IAAY;IACtD,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACjE,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9C,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACpE,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC;YACH,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { buildClickableXPath, evaluateXPath, isDynamicId, isGenericClass } from "./xpath.js";
|
|
2
|
+
const KEY_DISPLAY_ATTRS = ['role', 'id', 'class', 'aria-label'];
|
|
3
|
+
const KEY_ATTRS = ['role', 'aria-label', 'id', 'name', 'type', 'href'];
|
|
4
|
+
export class WebElement {
|
|
5
|
+
tag;
|
|
6
|
+
xpath;
|
|
7
|
+
clickXPath;
|
|
8
|
+
attrs;
|
|
9
|
+
text;
|
|
10
|
+
outerHTML;
|
|
11
|
+
x;
|
|
12
|
+
y;
|
|
13
|
+
constructor(data) {
|
|
14
|
+
this.tag = data.tag;
|
|
15
|
+
this.xpath = data.xpath;
|
|
16
|
+
this.clickXPath = data.clickXPath;
|
|
17
|
+
this.attrs = data.attrs;
|
|
18
|
+
this.text = data.text;
|
|
19
|
+
this.outerHTML = data.outerHTML || '';
|
|
20
|
+
this.x = data.x;
|
|
21
|
+
this.y = data.y;
|
|
22
|
+
}
|
|
23
|
+
get description() {
|
|
24
|
+
const attrParts = KEY_DISPLAY_ATTRS.map((k) => (this.attrs[k] ? `${k}="${this.attrs[k].slice(0, 40)}"` : '')).filter(Boolean);
|
|
25
|
+
return `<${this.tag} ${attrParts.join(' ')}> text="${this.text.slice(0, 40)}"`;
|
|
26
|
+
}
|
|
27
|
+
get keyAttrs() {
|
|
28
|
+
return KEY_ATTRS.map((k) => (this.attrs[k] ? `${k}="${this.attrs[k]}"` : ''))
|
|
29
|
+
.filter(Boolean)
|
|
30
|
+
.join(' ');
|
|
31
|
+
}
|
|
32
|
+
get coordinates() {
|
|
33
|
+
return `(${this.x}, ${this.y})`;
|
|
34
|
+
}
|
|
35
|
+
get eidx() {
|
|
36
|
+
const val = this.attrs['data-explorbot-eidx'] || this.attrs.eidx;
|
|
37
|
+
return val ? Number.parseInt(val, 10) : null;
|
|
38
|
+
}
|
|
39
|
+
get isNavigationLink() {
|
|
40
|
+
if (this.tag !== 'a')
|
|
41
|
+
return false;
|
|
42
|
+
const href = this.attrs.href || '';
|
|
43
|
+
return !!href && href !== '#' && !href.startsWith('javascript:');
|
|
44
|
+
}
|
|
45
|
+
get filteredClasses() {
|
|
46
|
+
const cls = this.attrs.class || '';
|
|
47
|
+
return cls.split(/\s+/).filter((c) => c.length > 2 && !isDynamicId(c) && !isGenericClass(c));
|
|
48
|
+
}
|
|
49
|
+
static fromRawData(d) {
|
|
50
|
+
return new WebElement({
|
|
51
|
+
tag: d.tag,
|
|
52
|
+
xpath: '',
|
|
53
|
+
clickXPath: buildClickableXPath({ tag: d.tag, allAttrs: d.allAttrs, text: d.text }),
|
|
54
|
+
attrs: d.allAttrs,
|
|
55
|
+
text: d.text,
|
|
56
|
+
x: d.x,
|
|
57
|
+
y: d.y,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
static fromXPathMatch(m) {
|
|
61
|
+
return new WebElement({
|
|
62
|
+
tag: m.tag,
|
|
63
|
+
xpath: m.absoluteXPath,
|
|
64
|
+
clickXPath: buildClickableXPath(m),
|
|
65
|
+
attrs: m.allAttrs,
|
|
66
|
+
text: m.text,
|
|
67
|
+
outerHTML: m.outerHTML,
|
|
68
|
+
x: 0,
|
|
69
|
+
y: 0,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
static async fromPlaywrightLocator(locator) {
|
|
73
|
+
try {
|
|
74
|
+
const count = await locator.count();
|
|
75
|
+
if (count === 0)
|
|
76
|
+
return null;
|
|
77
|
+
const data = await locator.first().evaluate(extractElementData);
|
|
78
|
+
if (!data)
|
|
79
|
+
return null;
|
|
80
|
+
return WebElement.fromRawData(data);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
static async fromEidx(page, eidx) {
|
|
87
|
+
return WebElement.fromPlaywrightLocator(page.locator(`[data-explorbot-eidx="${eidx}"]`));
|
|
88
|
+
}
|
|
89
|
+
static async fromEidxList(page, eidxList) {
|
|
90
|
+
if (eidxList.length === 0)
|
|
91
|
+
return [];
|
|
92
|
+
const rawList = await page.evaluate(([list, extractFnStr]) => {
|
|
93
|
+
const extract = new Function(`return ${extractFnStr}`)();
|
|
94
|
+
const results = [];
|
|
95
|
+
for (const eidx of list) {
|
|
96
|
+
const el = document.querySelector(`[data-explorbot-eidx="${eidx}"]`);
|
|
97
|
+
if (!el)
|
|
98
|
+
continue;
|
|
99
|
+
const data = extract(el);
|
|
100
|
+
if (data)
|
|
101
|
+
results.push(data);
|
|
102
|
+
}
|
|
103
|
+
return results;
|
|
104
|
+
}, [eidxList, extractElementData.toString()]);
|
|
105
|
+
return rawList.map((d) => WebElement.fromRawData(d));
|
|
106
|
+
}
|
|
107
|
+
static async findByXPath(html, xpath) {
|
|
108
|
+
const result = await evaluateXPath(html, xpath);
|
|
109
|
+
if (result.error)
|
|
110
|
+
return { totalFound: 0, elements: [], error: result.error };
|
|
111
|
+
return { totalFound: result.totalFound, elements: result.matches.map((m) => WebElement.fromXPathMatch(m)) };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function extractElementData(el) {
|
|
115
|
+
const rect = el.getBoundingClientRect();
|
|
116
|
+
if (rect.width === 0 && rect.height === 0)
|
|
117
|
+
return null;
|
|
118
|
+
const allAttrs = {};
|
|
119
|
+
for (let i = 0; i < el.attributes.length; i++) {
|
|
120
|
+
const attr = el.attributes[i];
|
|
121
|
+
allAttrs[attr.name] = attr.value;
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
tag: el.tagName.toLowerCase(),
|
|
125
|
+
text: (el.textContent || '').trim().slice(0, 80),
|
|
126
|
+
allAttrs,
|
|
127
|
+
x: Math.round(rect.x + rect.width / 2),
|
|
128
|
+
y: Math.round(rect.y + rect.height / 2),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=web-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-element.js","sourceRoot":"","sources":["../../../src/utils/web-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9G,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;AAChE,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAIvE,MAAM,OAAO,UAAU;IACrB,GAAG,CAAS;IACZ,KAAK,CAAS;IACd,UAAU,CAAS;IACnB,KAAK,CAAyB;IAC9B,IAAI,CAAS;IACb,SAAS,CAAS;IAClB,CAAC,CAAS;IACV,CAAC,CAAS;IACV,YAAY,IAA+I;QACzJ,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACpB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QAChB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,WAAW;QACb,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9H,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;IACjF,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aAC1E,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;IAClC,CAAC;IAED,IAAI,IAAI;QACN,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QACjE,OAAO,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;IAED,IAAI,gBAAgB;QAClB,IAAI,IAAI,CAAC,GAAG,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QACnC,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,eAAe;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QACnC,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,CAAiB;QAC1C,OAAO,IAAI,UAAU,CAAC;YACpB,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,KAAK,EAAE,EAAE;YACT,UAAU,EAAE,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAgB,CAAC;YACjG,KAAK,EAAE,CAAC,CAAC,QAAQ;YACjB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,CAAC,EAAE,CAAC,CAAC,CAAC;YACN,CAAC,EAAE,CAAC,CAAC,CAAC;SACP,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,CAAa;QACjC,OAAO,IAAI,UAAU,CAAC;YACpB,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,KAAK,EAAE,CAAC,CAAC,aAAa;YACtB,UAAU,EAAE,mBAAmB,CAAC,CAAC,CAAC;YAClC,KAAK,EAAE,CAAC,CAAC,QAAQ;YACjB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,CAAC,EAAE,CAAC;YACJ,CAAC,EAAE,CAAC;SACL,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,OAAY;QAC7C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,KAAK,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC7B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;YAChE,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YACvB,OAAO,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAS,EAAE,IAAY;QAC3C,OAAO,UAAU,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,IAAI,IAAI,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAS,EAAE,QAAkB;QACrD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAErC,MAAM,OAAO,GAAqB,MAAM,IAAI,CAAC,QAAQ,CACnD,CAAC,CAAC,IAAI,EAAE,YAAY,CAAqB,EAAE,EAAE;YAC3C,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAC,UAAU,YAAY,EAAE,CAAC,EAA0B,CAAC;YACjF,MAAM,OAAO,GAAU,EAAE,CAAC;YAC1B,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;gBACxB,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,yBAAyB,IAAI,IAAI,CAAC,CAAC;gBACrE,IAAI,CAAC,EAAE;oBAAE,SAAS;gBAClB,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;gBACzB,IAAI,IAAI;oBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,EACD,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,CAAuB,CAChE,CAAC;QAEF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,IAAY,EAAE,KAAa;QAClD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9G,CAAC;CACF;AAED,SAAS,kBAAkB,CAAC,EAAW;IACrC,MAAM,IAAI,GAAG,EAAE,CAAC,qBAAqB,EAAE,CAAC;IACxC,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvD,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACnC,CAAC;IAED,OAAO;QACL,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE;QAC7B,IAAI,EAAE,CAAC,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QAChD,QAAQ;QACR,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACtC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const MAX_MATCHES = 30;
|
|
2
|
+
const MAX_OUTER_HTML = 200;
|
|
3
|
+
const MAX_TEXT = 80;
|
|
4
|
+
function truncate(str, max) {
|
|
5
|
+
if (str.length <= max)
|
|
6
|
+
return str;
|
|
7
|
+
return `${str.slice(0, max)}...`;
|
|
8
|
+
}
|
|
9
|
+
function getAbsoluteXPath(el) {
|
|
10
|
+
const parts = [];
|
|
11
|
+
let current = el;
|
|
12
|
+
while (current && current.nodeType === 1) {
|
|
13
|
+
const tag = current.tagName.toLowerCase();
|
|
14
|
+
if (tag === 'html') {
|
|
15
|
+
current = current.parentElement;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (tag === 'body') {
|
|
19
|
+
parts.unshift('body');
|
|
20
|
+
current = current.parentElement;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
let index = 1;
|
|
24
|
+
let sibling = current.previousElementSibling;
|
|
25
|
+
while (sibling) {
|
|
26
|
+
if (sibling.tagName === current.tagName)
|
|
27
|
+
index++;
|
|
28
|
+
sibling = sibling.previousElementSibling;
|
|
29
|
+
}
|
|
30
|
+
parts.unshift(`${tag}[${index}]`);
|
|
31
|
+
current = current.parentElement;
|
|
32
|
+
}
|
|
33
|
+
return `//${parts.join('/')}`;
|
|
34
|
+
}
|
|
35
|
+
export const isDynamicId = (id) => /^(ember|react|__next)\d|^\d+$/.test(id);
|
|
36
|
+
export const isGenericClass = (cls) => /^ember-view$|^ember\d|^react-|^__next/.test(cls);
|
|
37
|
+
export function buildClickableXPath(el) {
|
|
38
|
+
const a = el.allAttrs;
|
|
39
|
+
if (a.id && !isDynamicId(a.id))
|
|
40
|
+
return `//*[@id="${a.id}"]`;
|
|
41
|
+
const conditions = [`self::${el.tag}`];
|
|
42
|
+
if (a.role)
|
|
43
|
+
conditions.push(`@role="${a.role}"`);
|
|
44
|
+
if (a['aria-label'])
|
|
45
|
+
conditions.push(`@aria-label="${a['aria-label']}"`);
|
|
46
|
+
if (a.class) {
|
|
47
|
+
const classes = a.class.split(/\s+/).filter((c) => !isGenericClass(c) && c.length > 2);
|
|
48
|
+
for (const cls of classes.slice(0, 3)) {
|
|
49
|
+
conditions.push(`contains(@class,"${cls}")`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (el.text && el.text.length > 0 && el.text.length < 40) {
|
|
53
|
+
conditions.push(`contains(.,"${el.text.replace(/"/g, "'")}")`);
|
|
54
|
+
}
|
|
55
|
+
return `//*[${conditions.join(' and ')}]`;
|
|
56
|
+
}
|
|
57
|
+
export function cssToAncestorXPath(css) {
|
|
58
|
+
const trimmed = css.trim();
|
|
59
|
+
if (!trimmed)
|
|
60
|
+
return null;
|
|
61
|
+
const idMatch = trimmed.match(/^#([\w-]+)$/);
|
|
62
|
+
if (idMatch)
|
|
63
|
+
return `@id="${idMatch[1]}"`;
|
|
64
|
+
const tagClassMatch = trimmed.match(/^(\w+)\.([\w-]+)$/);
|
|
65
|
+
if (tagClassMatch)
|
|
66
|
+
return `self::${tagClassMatch[1]} and contains(@class,"${tagClassMatch[2]}")`;
|
|
67
|
+
const classMatch = trimmed.match(/^\.([\w-]+)$/);
|
|
68
|
+
if (classMatch)
|
|
69
|
+
return `contains(@class,"${classMatch[1]}")`;
|
|
70
|
+
const attrMatch = trimmed.match(/^\[([^\]]+)\]$/);
|
|
71
|
+
if (attrMatch)
|
|
72
|
+
return `@${attrMatch[1]}`;
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
export async function evaluateXPath(html, xpath) {
|
|
76
|
+
const { JSDOM } = await import('jsdom');
|
|
77
|
+
const dom = new JSDOM(html);
|
|
78
|
+
try {
|
|
79
|
+
const doc = dom.window.document;
|
|
80
|
+
const result = doc.evaluate(xpath, doc, null, 7, null);
|
|
81
|
+
const matches = [];
|
|
82
|
+
const totalFound = result.snapshotLength;
|
|
83
|
+
for (let i = 0; i < Math.min(totalFound, MAX_MATCHES); i++) {
|
|
84
|
+
const node = result.snapshotItem(i);
|
|
85
|
+
if (!node || node.nodeType !== 1)
|
|
86
|
+
continue;
|
|
87
|
+
const el = node;
|
|
88
|
+
const allAttrs = {};
|
|
89
|
+
for (let a = 0; a < el.attributes.length; a++) {
|
|
90
|
+
const attr = el.attributes[a];
|
|
91
|
+
allAttrs[attr.name] = attr.value;
|
|
92
|
+
}
|
|
93
|
+
matches.push({
|
|
94
|
+
tag: el.tagName.toLowerCase(),
|
|
95
|
+
outerHTML: truncate(el.outerHTML, MAX_OUTER_HTML),
|
|
96
|
+
text: truncate(el.textContent?.trim() || '', MAX_TEXT),
|
|
97
|
+
absoluteXPath: getAbsoluteXPath(el),
|
|
98
|
+
allAttrs,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return { totalFound, matches };
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
return { totalFound: 0, matches: [], error: err?.message || 'XPath evaluation failed' };
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
dom.window.close();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=xpath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xpath.js","sourceRoot":"","sources":["../../../src/utils/xpath.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "explorbot",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "CLI app built with React Ink, CodeceptJS, and Playwright",
|
|
5
|
+
"license": "Elastic-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/src/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"explorbot": "./dist/bin/explorbot-cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": ["dist/", "rules/", "assets/sample-files/", "prompts/"],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "bun run src/index.tsx build && bun run build:bin",
|
|
14
|
+
"build:bin": "bun build bin/explorbot-cli.ts --outdir bin --target node --external commander --format esm",
|
|
15
|
+
"build:npm": "bash scripts/build-npm.sh",
|
|
16
|
+
"prepublishOnly": "npm run build:npm",
|
|
17
|
+
"dev": "bun run src/index.tsx",
|
|
18
|
+
"start": "node dist/index.js",
|
|
19
|
+
"init": "bun run src/index.tsx init",
|
|
20
|
+
"test": "codeceptjs run",
|
|
21
|
+
"test:headless": "codeceptjs run --headless",
|
|
22
|
+
"test:ui": "bun test tests/ui",
|
|
23
|
+
"test:unit": "bun test tests/unit",
|
|
24
|
+
"test:node": "node --test tests/node/*.mjs",
|
|
25
|
+
"test:unit:coverage": "bun test tests/unit --coverage && find . -name '.lcov.info*.tmp' -type f -delete 2>/dev/null || true",
|
|
26
|
+
"test:coverage": "bun test tests/unit --coverage --coverage-reporter=text && find . -name '.lcov.info*.tmp' -type f -delete 2>/dev/null || true",
|
|
27
|
+
"test:coverage:html": "echo 'Run: bun test tests/unit --coverage for detailed coverage report'",
|
|
28
|
+
"test:coverage:summary": "bun test tests/unit --coverage --coverage-reporter=text | tail -n 20 && find . -name '.lcov.info*.tmp' -type f -delete 2>/dev/null || true",
|
|
29
|
+
"test:coverage:clean": "find . -name '.lcov.info*.tmp' -type f -delete 2>/dev/null || true",
|
|
30
|
+
"format": "biome format --write .",
|
|
31
|
+
"format:check": "biome format .",
|
|
32
|
+
"lint": "biome lint .",
|
|
33
|
+
"lint:fix": "biome lint --write .",
|
|
34
|
+
"check": "biome check .",
|
|
35
|
+
"check:fix": "biome check --write .",
|
|
36
|
+
"langfuse:export": "bun run .claude/skills/explorbot-debug/langfuse-export.ts"
|
|
37
|
+
},
|
|
38
|
+
"keywords": ["cli", "react", "ink", "codeceptjs", "playwright"],
|
|
39
|
+
"author": "",
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@ai-sdk/anthropic": "^3.0",
|
|
42
|
+
"@ai-sdk/groq": "^3.0",
|
|
43
|
+
"@ai-sdk/openai": "^3.0",
|
|
44
|
+
"@axe-core/playwright": "^4.11.0",
|
|
45
|
+
"@inkjs/ui": "^2.0.0",
|
|
46
|
+
"@langfuse/otel": "^4.5.1",
|
|
47
|
+
"@openrouter/ai-sdk-provider": "^2.3.3",
|
|
48
|
+
"@opentelemetry/api": "^1.9.0",
|
|
49
|
+
"@opentelemetry/auto-instrumentations-node": "^0.67.3",
|
|
50
|
+
"@opentelemetry/instrumentation": "^0.208.0",
|
|
51
|
+
"@opentelemetry/resources": "^2.2.0",
|
|
52
|
+
"@opentelemetry/sdk-node": "^0.208.0",
|
|
53
|
+
"@opentelemetry/sdk-trace-base": "^2.2.0",
|
|
54
|
+
"@opentelemetry/semantic-conventions": "^1.38.0",
|
|
55
|
+
"@scalar/openapi-parser": "^0.25.6",
|
|
56
|
+
"@testomatio/reporter": "2.7.3",
|
|
57
|
+
"ai": "^6.0.6",
|
|
58
|
+
"axe-core": "^4.11.1",
|
|
59
|
+
"bash-tool": "^1.3.15",
|
|
60
|
+
"cli-highlight": "^2.1.11",
|
|
61
|
+
"codeceptjs": "4.0.0-rc.11",
|
|
62
|
+
"commander": "^14.0.1",
|
|
63
|
+
"debug": "^4.4.3",
|
|
64
|
+
"dedent": "^1.6.0",
|
|
65
|
+
"expect": "^30.3.0",
|
|
66
|
+
"figures": "^6.1.0",
|
|
67
|
+
"gray-matter": "^4.0.3",
|
|
68
|
+
"html-minifier-next": "^2.1.5",
|
|
69
|
+
"ink": "^6.3.1",
|
|
70
|
+
"ink-big-text": "^2.0.0",
|
|
71
|
+
"ink-select-input": "^6.2.0",
|
|
72
|
+
"ink-text-input": "^6.0.0",
|
|
73
|
+
"jsdom": "^28.0.0",
|
|
74
|
+
"jsonpath-plus": "^10.4.0",
|
|
75
|
+
"just-bash": "^2.14.0",
|
|
76
|
+
"langfuse": "^3.5.0",
|
|
77
|
+
"marked": "^16.2.0",
|
|
78
|
+
"marked-terminal": "^7.3.0",
|
|
79
|
+
"micromatch": "^4.0.8",
|
|
80
|
+
"ora-classic": "^5.4.2",
|
|
81
|
+
"parse5": "^8.0.0",
|
|
82
|
+
"playwright": "^1.40.0",
|
|
83
|
+
"react": "^19.1.1",
|
|
84
|
+
"strip-ansi": "^7.1.2",
|
|
85
|
+
"turndown": "^7.2.1",
|
|
86
|
+
"unique-names-generator": "^4.7.1",
|
|
87
|
+
"yargs": "^17.7.2",
|
|
88
|
+
"zod": "^4.1.8"
|
|
89
|
+
},
|
|
90
|
+
"devDependencies": {
|
|
91
|
+
"@biomejs/biome": "^1.5.3",
|
|
92
|
+
"@testing-library/react": "^16.3.0",
|
|
93
|
+
"@types/debug": "^4.1.12",
|
|
94
|
+
"@types/jsdom": "^27.0.0",
|
|
95
|
+
"@types/micromatch": "^4.0.9",
|
|
96
|
+
"@types/react": "^18.2.0",
|
|
97
|
+
"@types/yargs": "^17.0.24",
|
|
98
|
+
"bunosh": "^0.4.0",
|
|
99
|
+
"ink-testing-library": "^4.0.0",
|
|
100
|
+
"langwatch": "^0.10.0",
|
|
101
|
+
"msw": "^2.11.3",
|
|
102
|
+
"typescript": "^5.0.0",
|
|
103
|
+
"vitest": "^3.2.4"
|
|
104
|
+
},
|
|
105
|
+
"engines": {
|
|
106
|
+
"node": ">=24.0.0"
|
|
107
|
+
},
|
|
108
|
+
"overrides": {
|
|
109
|
+
"has-flag": "4.0.0",
|
|
110
|
+
"supports-color": "7.2.0"
|
|
111
|
+
},
|
|
112
|
+
"resolutions": {
|
|
113
|
+
"marked-terminal": {
|
|
114
|
+
"supports-hyperlinks": "2.3.0"
|
|
115
|
+
},
|
|
116
|
+
"has-flag": "4.0.0",
|
|
117
|
+
"supports-color": "7.2.0"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Prompt Audit System for Web Navigation/Testing Rules
|
|
2
|
+
|
|
3
|
+
You are an expert prompt engineer specializing in AI-driven web testing automation. Your task is to audit the prompts and rules used for web navigation and testing in this codebase.
|
|
4
|
+
|
|
5
|
+
## Files to Analyze
|
|
6
|
+
|
|
7
|
+
1. **`@src/ai/rules.ts`** - Core rules and guidelines for locators, actions, and verification
|
|
8
|
+
2. **`@src/ai/navigator.ts`** - Uses rules in prompts for navigation and verification
|
|
9
|
+
3. **`@src/ai/tools.ts`** - Tool definitions that include locator rules and guidance
|
|
10
|
+
|
|
11
|
+
## Audit Checklist
|
|
12
|
+
|
|
13
|
+
### 1. Rules Analysis (`rules.ts`)
|
|
14
|
+
|
|
15
|
+
Look for:
|
|
16
|
+
- **Contradictions**: Rules that conflict with each other (e.g., "prefer ARIA" vs "use text first")
|
|
17
|
+
- **Ambiguity**: Vague guidance that could be interpreted multiple ways
|
|
18
|
+
- **Incomplete guidance**: Missing priority order, missing edge cases
|
|
19
|
+
- **Locator priority**: Is ARIA → Text → CSS → XPath clearly defined?
|
|
20
|
+
- **Disambiguation**: How to choose between multiple matching elements?
|
|
21
|
+
- **Context parameter**: When and how to use it?
|
|
22
|
+
- **Short vs Long locators**: Clear definitions?
|
|
23
|
+
- **Unused rules**: Exported but never imported anywhere
|
|
24
|
+
|
|
25
|
+
### 2. Rule Usage Analysis (`navigator.ts`)
|
|
26
|
+
|
|
27
|
+
Check:
|
|
28
|
+
- **Imported but unused**: Rules imported but not used in prompts
|
|
29
|
+
- **Missing rules**: Prompts that should include locatorRule or actionRule but don't
|
|
30
|
+
- **Duplication**: Inline rules that duplicate what's in rules.ts
|
|
31
|
+
- **Consistency**: Do prompts follow the same structure?
|
|
32
|
+
- **HTML tags**: Is HTML content wrapped in `<page_html>` tags?
|
|
33
|
+
|
|
34
|
+
### 3. Tools Analysis (`tools.ts`)
|
|
35
|
+
|
|
36
|
+
Verify:
|
|
37
|
+
- **locatorRule usage**: Do tools that accept locators include locatorRule?
|
|
38
|
+
- **Input schema descriptions**: Do they mention "ARIA, CSS or XPath"?
|
|
39
|
+
- **Suggestions on failure**: Do failed results provide helpful suggestions?
|
|
40
|
+
- **Unreachable code paths**: Logic that can never execute (like type with undefined locator)
|
|
41
|
+
- **Consistent error handling**: Same pattern across all tools
|
|
42
|
+
- **Tool differentiation**: Clear when to use click vs clickByText, type with/without locator
|
|
43
|
+
|
|
44
|
+
## Severity Levels
|
|
45
|
+
|
|
46
|
+
| Severity | Description | Examples |
|
|
47
|
+
|----------|-------------|----------|
|
|
48
|
+
| **🔴 Critical** | Breaks functionality or causes wrong behavior | Contradictory rules, unreachable code, missing required rules |
|
|
49
|
+
| **🟠High** | Significant confusion or incorrect guidance | Ambiguous priority, misleading examples, wrong format |
|
|
50
|
+
| **🟡 Medium** | Suboptimal but functional | Redundant rules, verbose descriptions, missing suggestions |
|
|
51
|
+
| **🟢 Minor** | Cosmetic or style issues | Typos, formatting, inconsistent spacing |
|
|
52
|
+
|
|
53
|
+
## Output Format
|
|
54
|
+
|
|
55
|
+
Structure your findings as follows:
|
|
56
|
+
|
|
57
|
+
```markdown
|
|
58
|
+
## Audit Results
|
|
59
|
+
|
|
60
|
+
### Critical Issues 🔴
|
|
61
|
+
1. **[File:Line]** Issue description
|
|
62
|
+
- Impact: What goes wrong
|
|
63
|
+
- Fix: Suggested resolution
|
|
64
|
+
|
|
65
|
+
### High Priority Issues ðŸŸ
|
|
66
|
+
1. **[File:Line]** Issue description
|
|
67
|
+
- Impact: What confusion this causes
|
|
68
|
+
- Fix: Suggested resolution
|
|
69
|
+
|
|
70
|
+
### Medium Priority Issues 🟡
|
|
71
|
+
1. **[File:Line]** Issue description
|
|
72
|
+
- Impact: Why this matters
|
|
73
|
+
- Fix: Suggested resolution
|
|
74
|
+
|
|
75
|
+
### Minor Issues 🟢
|
|
76
|
+
1. **[File:Line]** Issue description
|
|
77
|
+
- Fix: Suggested resolution
|
|
78
|
+
|
|
79
|
+
### Observations
|
|
80
|
+
- General patterns noticed
|
|
81
|
+
- Recommendations for improvement
|
|
82
|
+
- Questions for clarification
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Specific Things to Check
|
|
86
|
+
|
|
87
|
+
### Locator Rules
|
|
88
|
+
- [ ] Priority order clearly defined (ARIA → Text → CSS → XPath)
|
|
89
|
+
- [ ] Context parameter explained (when to use, which tools support it)
|
|
90
|
+
- [ ] Disambiguation strategy documented (form flow, ARIA state, proximity)
|
|
91
|
+
- [ ] Short vs Long locators defined
|
|
92
|
+
- [ ] Examples consistent with rules (single quotes vs double quotes in JSON)
|
|
93
|
+
|
|
94
|
+
### Action Rules
|
|
95
|
+
- [ ] Function signatures included (I.click, I.fillField, I.see, etc.)
|
|
96
|
+
- [ ] Required parameters explained (context for I.see)
|
|
97
|
+
- [ ] Prohibited actions listed (no wait functions, no amOnPage)
|
|
98
|
+
- [ ] Examples match documented format
|
|
99
|
+
|
|
100
|
+
### Verification Rules
|
|
101
|
+
- [ ] I.see requires context parameter
|
|
102
|
+
- [ ] I.seeElement prefers ARIA locators
|
|
103
|
+
- [ ] Strictness rules to avoid false positives
|
|
104
|
+
- [ ] Examples show correct usage
|
|
105
|
+
|
|
106
|
+
### Tool Definitions
|
|
107
|
+
- [ ] Each tool includes relevant rules (locatorRule where needed)
|
|
108
|
+
- [ ] Input schemas describe all locator types
|
|
109
|
+
- [ ] Failed results include actionable suggestions
|
|
110
|
+
- [ ] Description explains when to use this tool vs alternatives
|
|
111
|
+
|
|
112
|
+
## Run This Audit
|
|
113
|
+
|
|
114
|
+
To run this audit, execute:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
Please analyze the following files for prompt/rule issues:
|
|
118
|
+
@src/ai/rules.ts
|
|
119
|
+
@src/ai/navigator.ts
|
|
120
|
+
@src/ai/tools.ts
|
|
121
|
+
|
|
122
|
+
Follow the audit checklist and output format defined in @prompts/audit-rules.md
|
|
123
|
+
```
|
|
124
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
- Each scenario must be a complete, independent test
|
|
2
|
+
- Steps should specify exact HTTP methods, paths, and key payload details
|
|
3
|
+
- Expected outcomes should be specific and verifiable (status codes, response fields, error messages)
|
|
4
|
+
- For CRUD operations, each test should handle its own setup and teardown
|
|
5
|
+
- Expect standard REST conventions: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 404 Not Found, 422 Unprocessable Entity
|
|
6
|
+
- NEVER propose scenarios that test the same thing. "Create a basic suite" and "Successful creation of a simple suite" are DUPLICATES. Each scenario must test a DISTINCT behavior or aspect.
|
|
7
|
+
- Before finalizing, review all scenarios and remove any that overlap in what they actually verify.
|
|
8
|
+
|
|
9
|
+
API Usage Notes:
|
|
10
|
+
|
|
11
|
+
- String is usually compatible with other data formats such as numbers or datetime, so do not check if number type strictly matches to number as it can be string too
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Maximize coverage by using every field and endpoint the API offers.
|
|
2
|
+
|
|
3
|
+
Focus on:
|
|
4
|
+
- Full payload create: POST with ALL optional and required fields populated, verify every field was saved
|
|
5
|
+
- Field-by-field update: PATCH/PUT each field individually, verify the change persists via GET
|
|
6
|
+
- Mixed combinations: create with some optional fields set and others omitted, then update the missing ones
|
|
7
|
+
- Array fields: send multiple items in arrays, not just one — verify all items are stored
|
|
8
|
+
- Enum fields: try every valid enum value, verify each is accepted and returned correctly
|
|
9
|
+
- Related fields: if spec shows related IDs or nested objects, populate them all
|
|
10
|
+
- All endpoints: exercise every available endpoint for the resource, not just the main CRUD
|
|
11
|
+
- Multiple resources: create several items, list them, verify count and content
|
|
12
|
+
- Default values: omit optional fields on create, then GET to see what defaults the API assigns
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Analyze the request log and API spec to discover hidden endpoints, undocumented properties, and unprotected actions — then try to exploit them.
|
|
2
|
+
|
|
3
|
+
Study previous responses carefully:
|
|
4
|
+
- Look at response field names and values — guess related endpoints and properties not in the spec
|
|
5
|
+
- If a response contains fields like "user_id", "org_id", "role" — try sending them on create/update to see if it is possible to self-promote
|
|
6
|
+
- If responses include URLs or paths — follow them, they may reveal internal routes
|
|
7
|
+
- Guess hidden endpoints by looking at response fields
|
|
8
|
+
- If IDs are sequential — try adjacent IDs to access other users' resources
|
|
9
|
+
- Try to create tests with custom ID values to see if they are accepted
|
|
10
|
+
- If a response shows more fields than the spec defines — those extra fields are attack surface
|
|
11
|
+
|
|
12
|
+
Use schemaFor to discover related endpoints, then try HTTP methods the spec doesn't list for them.
|
|
13
|
+
Derive endpoint patterns from what you've seen — if /items exists, try /items/export, /items/bulk, /items/search.
|
|
14
|
+
Send fields from GET responses back in POST/PUT — check which ones the server silently accepts.
|
|
15
|
+
Try overriding read-only or server-computed fields you observed in responses.
|
|
16
|
+
Strip or corrupt auth headers on sensitive operations to test enforcement.
|
|
17
|
+
|
|
18
|
+
Every unexpected finding must be recorded immediately.
|
|
19
|
+
Unclosed hidden exploits must be recorded as a failure.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Focus on standard CRUD operations and happy-path flows.
|
|
2
|
+
|
|
3
|
+
Test each HTTP method the endpoint supports:
|
|
4
|
+
- POST: Create a new resource with valid data, verify 201 and response body
|
|
5
|
+
- PUT/PATCH: Update the resource, verify changes persist
|
|
6
|
+
- DELETE: Remove the resource, verify 204/200 and subsequent GET returns 404
|
|
7
|
+
- GET: obtain data, list by filters, by search
|
|
8
|
+
|
|
9
|
+
Validate response schemas match expected structure.
|
|
10
|
+
Check that required fields are present in responses.
|
|
11
|
+
Verify correct HTTP status codes for each operation.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Stress-test the endpoint with invalid, malformed, and extreme inputs.
|
|
2
|
+
|
|
3
|
+
Focus on:
|
|
4
|
+
|
|
5
|
+
- Missing required fields: send partial payloads, empty objects, empty body
|
|
6
|
+
- Malformed JSON: trailing commas, unquoted keys, broken UTF-8
|
|
7
|
+
- SQL injection
|
|
8
|
+
- XSS payloads
|
|
9
|
+
- Exposed secrets: passwords, tokens, etc
|
|
10
|
+
- Wrong Content-Type: send form data as JSON, JSON as XML
|
|
11
|
+
- Invalid HTTP methods: PATCH on POST-only endpoints
|
|
12
|
+
- Boundary values: negative numbers, zero, MAX_INT, empty arrays, null values
|
|
13
|
+
- Date fields: set creation date in future, and expiring date to past
|
|
14
|
+
|
|
15
|
+
Expect proper responses with meaningful error messages if related.
|
|
16
|
+
If server strips broken data it is ok
|
|
17
|
+
Responses must be carefully validated to contain correct and secure data
|