cbrowser 7.2.0 → 7.4.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.
- package/dist/analysis/bug-hunter.d.ts +32 -0
- package/dist/analysis/bug-hunter.d.ts.map +1 -0
- package/dist/analysis/bug-hunter.js +106 -0
- package/dist/analysis/bug-hunter.js.map +1 -0
- package/dist/analysis/chaos-testing.d.ts +41 -0
- package/dist/analysis/chaos-testing.d.ts.map +1 -0
- package/dist/analysis/chaos-testing.js +87 -0
- package/dist/analysis/chaos-testing.js.map +1 -0
- package/dist/analysis/index.d.ts +10 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +26 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/natural-language.d.ts +43 -0
- package/dist/analysis/natural-language.d.ts.map +1 -0
- package/dist/analysis/natural-language.js +205 -0
- package/dist/analysis/natural-language.js.map +1 -0
- package/dist/analysis/persona-comparison.d.ts +31 -0
- package/dist/analysis/persona-comparison.d.ts.map +1 -0
- package/dist/analysis/persona-comparison.js +217 -0
- package/dist/analysis/persona-comparison.js.map +1 -0
- package/dist/browser.d.ts +1 -395
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +0 -4388
- package/dist/browser.js.map +1 -1
- package/dist/cli.js +198 -55
- package/dist/cli.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +2 -1
- package/dist/daemon.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/performance/index.d.ts +7 -0
- package/dist/performance/index.d.ts.map +1 -0
- package/dist/performance/index.js +23 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/performance/metrics.d.ts +49 -0
- package/dist/performance/metrics.d.ts.map +1 -0
- package/dist/performance/metrics.js +386 -0
- package/dist/performance/metrics.js.map +1 -0
- package/dist/testing/coverage.d.ts +39 -0
- package/dist/testing/coverage.d.ts.map +1 -0
- package/dist/testing/coverage.js +713 -0
- package/dist/testing/coverage.js.map +1 -0
- package/dist/testing/flaky-detection.d.ts +28 -0
- package/dist/testing/flaky-detection.d.ts.map +1 -0
- package/dist/testing/flaky-detection.js +332 -0
- package/dist/testing/flaky-detection.js.map +1 -0
- package/dist/testing/index.d.ts +10 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +26 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/nl-test-suite.d.ts +70 -0
- package/dist/testing/nl-test-suite.d.ts.map +1 -0
- package/dist/testing/nl-test-suite.js +427 -0
- package/dist/testing/nl-test-suite.js.map +1 -0
- package/dist/testing/test-repair.d.ts +36 -0
- package/dist/testing/test-repair.d.ts.map +1 -0
- package/dist/testing/test-repair.js +528 -0
- package/dist/testing/test-repair.js.map +1 -0
- package/dist/types.d.ts +125 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/visual/ab-comparison.d.ts +23 -0
- package/dist/visual/ab-comparison.d.ts.map +1 -0
- package/dist/visual/ab-comparison.js +366 -0
- package/dist/visual/ab-comparison.js.map +1 -0
- package/dist/visual/cross-browser.d.ts +41 -0
- package/dist/visual/cross-browser.d.ts.map +1 -0
- package/dist/visual/cross-browser.js +442 -0
- package/dist/visual/cross-browser.js.map +1 -0
- package/dist/visual/index.d.ts +10 -0
- package/dist/visual/index.d.ts.map +1 -0
- package/dist/visual/index.js +26 -0
- package/dist/visual/index.js.map +1 -0
- package/dist/visual/regression.d.ts +55 -0
- package/dist/visual/regression.d.ts.map +1 -0
- package/dist/visual/regression.js +616 -0
- package/dist/visual/regression.js.map +1 -0
- package/dist/visual/responsive.d.ts +27 -0
- package/dist/visual/responsive.d.ts.map +1 -0
- package/dist/visual/responsive.js +450 -0
- package/dist/visual/responsive.js.map +1 -0
- package/package.json +32 -3
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autonomous Bug Hunter
|
|
3
|
+
*
|
|
4
|
+
* Tier 4: Automatically explores pages and finds common bugs including:
|
|
5
|
+
* - Broken links and images
|
|
6
|
+
* - Console errors
|
|
7
|
+
* - Accessibility violations
|
|
8
|
+
* - Slow resources
|
|
9
|
+
* - Form errors
|
|
10
|
+
*/
|
|
11
|
+
import type { CBrowser } from "../browser.js";
|
|
12
|
+
export interface BugReport {
|
|
13
|
+
type: "broken-link" | "console-error" | "a11y-violation" | "slow-resource" | "missing-image" | "form-error";
|
|
14
|
+
severity: "critical" | "high" | "medium" | "low";
|
|
15
|
+
description: string;
|
|
16
|
+
url: string;
|
|
17
|
+
selector?: string;
|
|
18
|
+
screenshot?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Autonomously explore a page and find bugs.
|
|
22
|
+
*/
|
|
23
|
+
export declare function huntBugs(browser: CBrowser, url: string, options?: {
|
|
24
|
+
maxDepth?: number;
|
|
25
|
+
maxPages?: number;
|
|
26
|
+
timeout?: number;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
bugs: BugReport[];
|
|
29
|
+
pagesVisited: number;
|
|
30
|
+
duration: number;
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=bug-hunter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bug-hunter.d.ts","sourceRoot":"","sources":["../../src/analysis/bug-hunter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,aAAa,GAAG,eAAe,GAAG,gBAAgB,GAAG,eAAe,GAAG,eAAe,GAAG,YAAY,CAAC;IAC5G,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,QAAQ,EACjB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACvE,OAAO,CAAC;IACT,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAoGD"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Autonomous Bug Hunter
|
|
4
|
+
*
|
|
5
|
+
* Tier 4: Automatically explores pages and finds common bugs including:
|
|
6
|
+
* - Broken links and images
|
|
7
|
+
* - Console errors
|
|
8
|
+
* - Accessibility violations
|
|
9
|
+
* - Slow resources
|
|
10
|
+
* - Form errors
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.huntBugs = huntBugs;
|
|
14
|
+
/**
|
|
15
|
+
* Autonomously explore a page and find bugs.
|
|
16
|
+
*/
|
|
17
|
+
async function huntBugs(browser, url, options = {}) {
|
|
18
|
+
const startTime = Date.now();
|
|
19
|
+
const bugs = [];
|
|
20
|
+
const visited = new Set();
|
|
21
|
+
const maxPages = options.maxPages || 10;
|
|
22
|
+
const timeout = options.timeout || 60000;
|
|
23
|
+
const page = await browser.getPage();
|
|
24
|
+
const consoleErrors = [];
|
|
25
|
+
// Capture console errors
|
|
26
|
+
page.on("console", (msg) => {
|
|
27
|
+
if (msg.type() === "error") {
|
|
28
|
+
consoleErrors.push(msg.text());
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
// Start with initial URL
|
|
32
|
+
await browser.navigate(url);
|
|
33
|
+
visited.add(url);
|
|
34
|
+
// Check for issues on current page
|
|
35
|
+
const pageIssues = await page.evaluate(() => {
|
|
36
|
+
const issues = [];
|
|
37
|
+
// Check for broken images
|
|
38
|
+
document.querySelectorAll("img").forEach((img, i) => {
|
|
39
|
+
if (!img.complete || img.naturalWidth === 0) {
|
|
40
|
+
issues.push({
|
|
41
|
+
type: "missing-image",
|
|
42
|
+
description: `Broken image: ${img.src || img.alt || "unknown"}`,
|
|
43
|
+
selector: `img:nth-of-type(${i + 1})`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
// Check for empty links
|
|
48
|
+
document.querySelectorAll("a").forEach((a, i) => {
|
|
49
|
+
if (!a.href || a.href === "#" || a.href === "javascript:void(0)") {
|
|
50
|
+
issues.push({
|
|
51
|
+
type: "broken-link",
|
|
52
|
+
description: `Empty/invalid link: ${a.textContent?.slice(0, 50) || "no text"}`,
|
|
53
|
+
selector: `a:nth-of-type(${i + 1})`,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
// Check for empty buttons
|
|
58
|
+
document.querySelectorAll("button").forEach((btn, i) => {
|
|
59
|
+
if (!btn.textContent?.trim() && !btn.getAttribute("aria-label")) {
|
|
60
|
+
issues.push({
|
|
61
|
+
type: "a11y-violation",
|
|
62
|
+
description: "Button with no accessible text",
|
|
63
|
+
selector: `button:nth-of-type(${i + 1})`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// Check for missing form labels
|
|
68
|
+
document.querySelectorAll("input:not([type='hidden'])").forEach((input, i) => {
|
|
69
|
+
const id = input.id;
|
|
70
|
+
const hasLabel = id && document.querySelector(`label[for="${id}"]`);
|
|
71
|
+
if (!hasLabel && !input.getAttribute("aria-label") && !input.getAttribute("placeholder")) {
|
|
72
|
+
issues.push({
|
|
73
|
+
type: "form-error",
|
|
74
|
+
description: "Input without label or placeholder",
|
|
75
|
+
selector: `input:nth-of-type(${i + 1})`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return issues;
|
|
80
|
+
});
|
|
81
|
+
// Add page issues to bugs
|
|
82
|
+
for (const issue of pageIssues) {
|
|
83
|
+
bugs.push({
|
|
84
|
+
type: issue.type,
|
|
85
|
+
severity: issue.type === "a11y-violation" ? "high" : "medium",
|
|
86
|
+
description: issue.description,
|
|
87
|
+
url,
|
|
88
|
+
selector: issue.selector,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Add console errors
|
|
92
|
+
for (const error of consoleErrors) {
|
|
93
|
+
bugs.push({
|
|
94
|
+
type: "console-error",
|
|
95
|
+
severity: "high",
|
|
96
|
+
description: error.slice(0, 200),
|
|
97
|
+
url,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
bugs,
|
|
102
|
+
pagesVisited: visited.size,
|
|
103
|
+
duration: Date.now() - startTime,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=bug-hunter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bug-hunter.js","sourceRoot":"","sources":["../../src/analysis/bug-hunter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chaos Engineering for Browser Testing
|
|
3
|
+
*
|
|
4
|
+
* Tier 4: Apply adverse conditions to test application resilience:
|
|
5
|
+
* - Network latency and offline simulation
|
|
6
|
+
* - URL blocking and API failure injection
|
|
7
|
+
* - Random delays and CPU throttling
|
|
8
|
+
*/
|
|
9
|
+
import type { CBrowser } from "../browser.js";
|
|
10
|
+
export interface ChaosConfig {
|
|
11
|
+
/** Simulate slow network (ms latency) */
|
|
12
|
+
networkLatency?: number;
|
|
13
|
+
/** Simulate offline mode */
|
|
14
|
+
offline?: boolean;
|
|
15
|
+
/** Block specific URL patterns */
|
|
16
|
+
blockUrls?: string[];
|
|
17
|
+
/** Inject random delays (0-1 probability) */
|
|
18
|
+
randomDelays?: number;
|
|
19
|
+
/** Fail specific API calls */
|
|
20
|
+
failApis?: Array<{
|
|
21
|
+
pattern: string;
|
|
22
|
+
status: number;
|
|
23
|
+
body?: string;
|
|
24
|
+
}>;
|
|
25
|
+
/** CPU throttling (1-20x slowdown) */
|
|
26
|
+
cpuThrottle?: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Apply chaos engineering conditions to browser.
|
|
30
|
+
*/
|
|
31
|
+
export declare function applyChaos(browser: CBrowser, config: ChaosConfig): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Run chaos test - apply conditions and verify app resilience.
|
|
34
|
+
*/
|
|
35
|
+
export declare function runChaosTest(browser: CBrowser, url: string, chaos: ChaosConfig, actions?: string[]): Promise<{
|
|
36
|
+
passed: boolean;
|
|
37
|
+
errors: string[];
|
|
38
|
+
duration: number;
|
|
39
|
+
screenshot: string;
|
|
40
|
+
}>;
|
|
41
|
+
//# sourceMappingURL=chaos-testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chaos-testing.d.ts","sourceRoot":"","sources":["../../src/analysis/chaos-testing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CtF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,QAAQ,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,MAAM,EAAO,GACrB,OAAO,CAAC;IACT,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAgCD"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Chaos Engineering for Browser Testing
|
|
4
|
+
*
|
|
5
|
+
* Tier 4: Apply adverse conditions to test application resilience:
|
|
6
|
+
* - Network latency and offline simulation
|
|
7
|
+
* - URL blocking and API failure injection
|
|
8
|
+
* - Random delays and CPU throttling
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.applyChaos = applyChaos;
|
|
12
|
+
exports.runChaosTest = runChaosTest;
|
|
13
|
+
const natural_language_js_1 = require("./natural-language.js");
|
|
14
|
+
/**
|
|
15
|
+
* Apply chaos engineering conditions to browser.
|
|
16
|
+
*/
|
|
17
|
+
async function applyChaos(browser, config) {
|
|
18
|
+
const context = await browser.context;
|
|
19
|
+
const page = await browser.getPage();
|
|
20
|
+
// Network conditions
|
|
21
|
+
if (config.offline) {
|
|
22
|
+
await context.setOffline(true);
|
|
23
|
+
}
|
|
24
|
+
// Route interception for latency/failures
|
|
25
|
+
if (config.networkLatency || config.blockUrls || config.failApis) {
|
|
26
|
+
await page.route("**/*", async (route) => {
|
|
27
|
+
const url = route.request().url();
|
|
28
|
+
// Block URLs
|
|
29
|
+
if (config.blockUrls?.some(pattern => url.includes(pattern))) {
|
|
30
|
+
await route.abort();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// Fail specific APIs
|
|
34
|
+
const failConfig = config.failApis?.find(f => url.includes(f.pattern));
|
|
35
|
+
if (failConfig) {
|
|
36
|
+
await route.fulfill({
|
|
37
|
+
status: failConfig.status,
|
|
38
|
+
body: failConfig.body || "Chaos: Simulated failure",
|
|
39
|
+
});
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Add latency
|
|
43
|
+
if (config.networkLatency) {
|
|
44
|
+
await new Promise(r => setTimeout(r, config.networkLatency));
|
|
45
|
+
}
|
|
46
|
+
// Random delays
|
|
47
|
+
if (config.randomDelays && Math.random() < config.randomDelays) {
|
|
48
|
+
await new Promise(r => setTimeout(r, Math.random() * 3000));
|
|
49
|
+
}
|
|
50
|
+
await route.continue();
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Run chaos test - apply conditions and verify app resilience.
|
|
56
|
+
*/
|
|
57
|
+
async function runChaosTest(browser, url, chaos, actions = []) {
|
|
58
|
+
const startTime = Date.now();
|
|
59
|
+
const errors = [];
|
|
60
|
+
try {
|
|
61
|
+
await applyChaos(browser, chaos);
|
|
62
|
+
await browser.navigate(url);
|
|
63
|
+
// Execute actions
|
|
64
|
+
for (const action of actions) {
|
|
65
|
+
const result = await (0, natural_language_js_1.executeNaturalLanguage)(browser, action);
|
|
66
|
+
if (!result.success) {
|
|
67
|
+
errors.push(`Action failed: ${action} - ${result.error}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const screenshot = await browser.screenshot();
|
|
71
|
+
return {
|
|
72
|
+
passed: errors.length === 0,
|
|
73
|
+
errors,
|
|
74
|
+
duration: Date.now() - startTime,
|
|
75
|
+
screenshot,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
return {
|
|
80
|
+
passed: false,
|
|
81
|
+
errors: [...errors, e.message],
|
|
82
|
+
duration: Date.now() - startTime,
|
|
83
|
+
screenshot: "",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=chaos-testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chaos-testing.js","sourceRoot":"","sources":["../../src/analysis/chaos-testing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Module
|
|
3
|
+
*
|
|
4
|
+
* Natural language commands, autonomous bug hunting, chaos testing, and persona comparison.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./natural-language.js";
|
|
7
|
+
export * from "./bug-hunter.js";
|
|
8
|
+
export * from "./chaos-testing.js";
|
|
9
|
+
export * from "./persona-comparison.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analysis/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Analysis Module
|
|
4
|
+
*
|
|
5
|
+
* Natural language commands, autonomous bug hunting, chaos testing, and persona comparison.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
__exportStar(require("./natural-language.js"), exports);
|
|
23
|
+
__exportStar(require("./bug-hunter.js"), exports);
|
|
24
|
+
__exportStar(require("./chaos-testing.js"), exports);
|
|
25
|
+
__exportStar(require("./persona-comparison.js"), exports);
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analysis/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;AAEH,wDAAsC;AACtC,kDAAgC;AAChC,qDAAmC;AACnC,0DAAwC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Natural Language API for Browser Automation
|
|
3
|
+
*
|
|
4
|
+
* Tier 3: Provides natural language command parsing and execution for browser automation.
|
|
5
|
+
* Allows commands like "click on the login button" or "fill 'hello' in the search box".
|
|
6
|
+
*/
|
|
7
|
+
import type { CBrowser } from "../browser.js";
|
|
8
|
+
/**
|
|
9
|
+
* Parse natural language into browser action.
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseNaturalLanguage(command: string): {
|
|
12
|
+
action: string;
|
|
13
|
+
params: Record<string, string>;
|
|
14
|
+
} | null;
|
|
15
|
+
/**
|
|
16
|
+
* Execute a natural language command.
|
|
17
|
+
*/
|
|
18
|
+
export declare function executeNaturalLanguage(browser: CBrowser, command: string): Promise<{
|
|
19
|
+
success: boolean;
|
|
20
|
+
action: string;
|
|
21
|
+
result?: unknown;
|
|
22
|
+
error?: string;
|
|
23
|
+
}>;
|
|
24
|
+
/**
|
|
25
|
+
* Execute multiple natural language commands in sequence.
|
|
26
|
+
*/
|
|
27
|
+
export declare function executeNaturalLanguageScript(browser: CBrowser, commands: string[]): Promise<Array<{
|
|
28
|
+
command: string;
|
|
29
|
+
success: boolean;
|
|
30
|
+
action: string;
|
|
31
|
+
result?: unknown;
|
|
32
|
+
error?: string;
|
|
33
|
+
}>>;
|
|
34
|
+
/**
|
|
35
|
+
* AI-powered semantic element finding.
|
|
36
|
+
* Examples: "the cheapest product", "login form", "main navigation"
|
|
37
|
+
*/
|
|
38
|
+
export declare function findElementByIntent(browser: CBrowser, intent: string): Promise<{
|
|
39
|
+
selector: string;
|
|
40
|
+
confidence: number;
|
|
41
|
+
description: string;
|
|
42
|
+
} | null>;
|
|
43
|
+
//# sourceMappingURL=natural-language.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"natural-language.d.ts","sourceRoot":"","sources":["../../src/analysis/natural-language.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AA8C9C;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAW/G;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACxF,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CA4CD;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAWzG;AAMD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAyH/E"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Natural Language API for Browser Automation
|
|
4
|
+
*
|
|
5
|
+
* Tier 3: Provides natural language command parsing and execution for browser automation.
|
|
6
|
+
* Allows commands like "click on the login button" or "fill 'hello' in the search box".
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.parseNaturalLanguage = parseNaturalLanguage;
|
|
10
|
+
exports.executeNaturalLanguage = executeNaturalLanguage;
|
|
11
|
+
exports.executeNaturalLanguageScript = executeNaturalLanguageScript;
|
|
12
|
+
exports.findElementByIntent = findElementByIntent;
|
|
13
|
+
/**
|
|
14
|
+
* Natural language command patterns.
|
|
15
|
+
*/
|
|
16
|
+
const NL_PATTERNS = [
|
|
17
|
+
// Navigation
|
|
18
|
+
{ pattern: /^(?:go to|navigate to|open|visit)\s+(.+)$/i, action: "navigate", extract: (m) => ({ url: m[1] }) },
|
|
19
|
+
{ pattern: /^(?:go\s+)?back$/i, action: "back", extract: () => ({}) },
|
|
20
|
+
{ pattern: /^(?:go\s+)?forward$/i, action: "forward", extract: () => ({}) },
|
|
21
|
+
{ pattern: /^refresh|reload$/i, action: "reload", extract: () => ({}) },
|
|
22
|
+
// Clicking
|
|
23
|
+
{ pattern: /^click(?:\s+on)?\s+(?:the\s+)?["']?(.+?)["']?$/i, action: "click", extract: (m) => ({ selector: m[1] }) },
|
|
24
|
+
{ pattern: /^press(?:\s+the)?\s+["']?(.+?)["']?(?:\s+button)?$/i, action: "click", extract: (m) => ({ selector: m[1] }) },
|
|
25
|
+
{ pattern: /^tap(?:\s+on)?\s+["']?(.+?)["']?$/i, action: "click", extract: (m) => ({ selector: m[1] }) },
|
|
26
|
+
// Form filling
|
|
27
|
+
{ pattern: /^(?:type|enter|input|fill(?:\s+in)?)\s+["'](.+?)["']\s+(?:in(?:to)?|on)\s+(?:the\s+)?["']?(.+?)["']?$/i, action: "fill", extract: (m) => ({ value: m[1], selector: m[2] }) },
|
|
28
|
+
{ pattern: /^(?:fill(?:\s+in)?|set)\s+(?:the\s+)?["']?(.+?)["']?\s+(?:to|with|as)\s+["'](.+?)["']$/i, action: "fill", extract: (m) => ({ selector: m[1], value: m[2] }) },
|
|
29
|
+
// Selecting
|
|
30
|
+
{ pattern: /^select\s+["'](.+?)["']\s+(?:from|in)\s+(?:the\s+)?["']?(.+?)["']?$/i, action: "select", extract: (m) => ({ value: m[1], selector: m[2] }) },
|
|
31
|
+
{ pattern: /^choose\s+["'](.+?)["']$/i, action: "click", extract: (m) => ({ selector: m[1] }) },
|
|
32
|
+
// Screenshots
|
|
33
|
+
{ pattern: /^(?:take\s+a?\s*)?screenshot(?:\s+as\s+["']?(.+?)["']?)?$/i, action: "screenshot", extract: (m) => ({ path: m[1] || "" }) },
|
|
34
|
+
{ pattern: /^capture(?:\s+the)?\s+(?:page|screen)$/i, action: "screenshot", extract: () => ({}) },
|
|
35
|
+
// Waiting
|
|
36
|
+
{ pattern: /^wait(?:\s+for)?\s+(\d+)\s*(?:ms|milliseconds?)?$/i, action: "wait", extract: (m) => ({ ms: m[1] }) },
|
|
37
|
+
{ pattern: /^wait(?:\s+for)?\s+(\d+)\s*(?:s|seconds?)$/i, action: "waitSeconds", extract: (m) => ({ seconds: m[1] }) },
|
|
38
|
+
{ pattern: /^wait(?:\s+for)?\s+["']?(.+?)["']?(?:\s+to\s+appear)?$/i, action: "waitFor", extract: (m) => ({ selector: m[1] }) },
|
|
39
|
+
// Scrolling
|
|
40
|
+
{ pattern: /^scroll\s+(?:to\s+)?(?:the\s+)?(top|bottom)$/i, action: "scroll", extract: (m) => ({ direction: m[1] }) },
|
|
41
|
+
{ pattern: /^scroll\s+(up|down)(?:\s+(\d+))?$/i, action: "scrollBy", extract: (m) => ({ direction: m[1], amount: m[2] || "300" }) },
|
|
42
|
+
// Extraction
|
|
43
|
+
{ pattern: /^(?:get|extract|find)\s+(?:all\s+)?(?:the\s+)?(.+)$/i, action: "extract", extract: (m) => ({ what: m[1] }) },
|
|
44
|
+
];
|
|
45
|
+
/**
|
|
46
|
+
* Parse natural language into browser action.
|
|
47
|
+
*/
|
|
48
|
+
function parseNaturalLanguage(command) {
|
|
49
|
+
const trimmed = command.trim();
|
|
50
|
+
for (const { pattern, action, extract } of NL_PATTERNS) {
|
|
51
|
+
const match = trimmed.match(pattern);
|
|
52
|
+
if (match) {
|
|
53
|
+
return { action, params: extract(match) };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Execute a natural language command.
|
|
60
|
+
*/
|
|
61
|
+
async function executeNaturalLanguage(browser, command) {
|
|
62
|
+
const parsed = parseNaturalLanguage(command);
|
|
63
|
+
if (!parsed) {
|
|
64
|
+
return { success: false, action: "unknown", error: `Could not parse command: "${command}"` };
|
|
65
|
+
}
|
|
66
|
+
const { action, params } = parsed;
|
|
67
|
+
try {
|
|
68
|
+
let result;
|
|
69
|
+
switch (action) {
|
|
70
|
+
case "navigate":
|
|
71
|
+
result = await browser.navigate(params.url);
|
|
72
|
+
break;
|
|
73
|
+
case "click":
|
|
74
|
+
result = await browser.click(params.selector);
|
|
75
|
+
break;
|
|
76
|
+
case "fill":
|
|
77
|
+
result = await browser.fill(params.selector, params.value);
|
|
78
|
+
break;
|
|
79
|
+
case "screenshot":
|
|
80
|
+
result = await browser.screenshot(params.path || undefined);
|
|
81
|
+
break;
|
|
82
|
+
case "wait":
|
|
83
|
+
await new Promise(r => setTimeout(r, parseInt(params.ms)));
|
|
84
|
+
result = { waited: parseInt(params.ms) };
|
|
85
|
+
break;
|
|
86
|
+
case "waitSeconds":
|
|
87
|
+
await new Promise(r => setTimeout(r, parseInt(params.seconds) * 1000));
|
|
88
|
+
result = { waited: parseInt(params.seconds) * 1000 };
|
|
89
|
+
break;
|
|
90
|
+
case "extract":
|
|
91
|
+
result = await browser.extract(params.what);
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
return { success: false, action, error: `Unsupported action: ${action}` };
|
|
95
|
+
}
|
|
96
|
+
return { success: true, action, result };
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
return { success: false, action, error: e.message };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Execute multiple natural language commands in sequence.
|
|
104
|
+
*/
|
|
105
|
+
async function executeNaturalLanguageScript(browser, commands) {
|
|
106
|
+
const results = [];
|
|
107
|
+
for (const command of commands) {
|
|
108
|
+
if (!command.trim() || command.startsWith("#"))
|
|
109
|
+
continue; // Skip empty lines and comments
|
|
110
|
+
const result = await executeNaturalLanguage(browser, command);
|
|
111
|
+
results.push({ command, ...result });
|
|
112
|
+
if (!result.success)
|
|
113
|
+
break; // Stop on first error
|
|
114
|
+
}
|
|
115
|
+
return results;
|
|
116
|
+
}
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// Tier 4: Visual AI Understanding (v4.0.0)
|
|
119
|
+
// ============================================================================
|
|
120
|
+
/**
|
|
121
|
+
* AI-powered semantic element finding.
|
|
122
|
+
* Examples: "the cheapest product", "login form", "main navigation"
|
|
123
|
+
*/
|
|
124
|
+
async function findElementByIntent(browser, intent) {
|
|
125
|
+
const page = await browser.getPage();
|
|
126
|
+
// Extract page structure for AI analysis
|
|
127
|
+
const pageData = await page.evaluate(() => {
|
|
128
|
+
const elements = [];
|
|
129
|
+
// Find interactive elements
|
|
130
|
+
const interactives = document.querySelectorAll("button, a, input, select, [role='button'], [onclick], .btn, .card, .product, [data-price], .price");
|
|
131
|
+
interactives.forEach((el, i) => {
|
|
132
|
+
const text = el.innerText?.trim().slice(0, 100) || "";
|
|
133
|
+
const priceMatch = text.match(/\$[\d,.]+|\d+\.\d{2}/);
|
|
134
|
+
elements.push({
|
|
135
|
+
tag: el.tagName.toLowerCase(),
|
|
136
|
+
text,
|
|
137
|
+
classes: el.className.toString().slice(0, 100),
|
|
138
|
+
id: el.id,
|
|
139
|
+
role: el.getAttribute("role") || "",
|
|
140
|
+
type: el.type || "",
|
|
141
|
+
price: priceMatch ? priceMatch[0] : undefined,
|
|
142
|
+
selector: el.id ? `#${el.id}` : `${el.tagName.toLowerCase()}:nth-of-type(${i + 1})`,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
return elements;
|
|
146
|
+
});
|
|
147
|
+
// Intent matching logic
|
|
148
|
+
const intentLower = intent.toLowerCase();
|
|
149
|
+
// Price-based intents
|
|
150
|
+
if (intentLower.includes("cheapest") || intentLower.includes("lowest price")) {
|
|
151
|
+
const withPrices = pageData.filter(el => el.price);
|
|
152
|
+
if (withPrices.length > 0) {
|
|
153
|
+
const sorted = withPrices.sort((a, b) => {
|
|
154
|
+
const priceA = parseFloat(a.price.replace(/[$,]/g, ""));
|
|
155
|
+
const priceB = parseFloat(b.price.replace(/[$,]/g, ""));
|
|
156
|
+
return priceA - priceB;
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
selector: sorted[0].selector,
|
|
160
|
+
confidence: 0.8,
|
|
161
|
+
description: `Cheapest item: ${sorted[0].text.slice(0, 50)} (${sorted[0].price})`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (intentLower.includes("most expensive") || intentLower.includes("highest price")) {
|
|
166
|
+
const withPrices = pageData.filter(el => el.price);
|
|
167
|
+
if (withPrices.length > 0) {
|
|
168
|
+
const sorted = withPrices.sort((a, b) => {
|
|
169
|
+
const priceA = parseFloat(a.price.replace(/[$,]/g, ""));
|
|
170
|
+
const priceB = parseFloat(b.price.replace(/[$,]/g, ""));
|
|
171
|
+
return priceB - priceA;
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
selector: sorted[0].selector,
|
|
175
|
+
confidence: 0.8,
|
|
176
|
+
description: `Most expensive: ${sorted[0].text.slice(0, 50)} (${sorted[0].price})`,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Form-based intents
|
|
181
|
+
if (intentLower.includes("login") || intentLower.includes("sign in")) {
|
|
182
|
+
const loginBtn = pageData.find(el => el.text.toLowerCase().includes("login") ||
|
|
183
|
+
el.text.toLowerCase().includes("sign in") ||
|
|
184
|
+
el.classes.includes("login"));
|
|
185
|
+
if (loginBtn) {
|
|
186
|
+
return { selector: loginBtn.selector, confidence: 0.9, description: "Login button/form" };
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (intentLower.includes("search")) {
|
|
190
|
+
const searchInput = pageData.find(el => el.type === "search" ||
|
|
191
|
+
el.classes.includes("search") ||
|
|
192
|
+
el.id.includes("search"));
|
|
193
|
+
if (searchInput) {
|
|
194
|
+
return { selector: searchInput.selector, confidence: 0.9, description: "Search input" };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Text-based matching
|
|
198
|
+
const textMatch = pageData.find(el => el.text.toLowerCase().includes(intentLower) ||
|
|
199
|
+
el.classes.toLowerCase().includes(intentLower));
|
|
200
|
+
if (textMatch) {
|
|
201
|
+
return { selector: textMatch.selector, confidence: 0.7, description: `Matched: ${textMatch.text.slice(0, 50)}` };
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=natural-language.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"natural-language.js","sourceRoot":"","sources":["../../src/analysis/natural-language.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Persona Comparison Testing
|
|
3
|
+
*
|
|
4
|
+
* Tier 6: Run the same user journey with multiple personas in parallel
|
|
5
|
+
* to compare how different user types experience your application.
|
|
6
|
+
*/
|
|
7
|
+
import type { PersonaComparisonResult } from "../types.js";
|
|
8
|
+
export interface ComparePersonasOptions {
|
|
9
|
+
/** Starting URL for the journey */
|
|
10
|
+
startUrl: string;
|
|
11
|
+
/** Goal to accomplish */
|
|
12
|
+
goal: string;
|
|
13
|
+
/** Personas to compare (names) */
|
|
14
|
+
personas: string[];
|
|
15
|
+
/** Maximum steps per journey */
|
|
16
|
+
maxSteps?: number;
|
|
17
|
+
/** Maximum concurrent browsers */
|
|
18
|
+
maxConcurrency?: number;
|
|
19
|
+
/** Headless mode */
|
|
20
|
+
headless?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Run the same journey with multiple personas and compare results.
|
|
24
|
+
* This runs personas in parallel (up to maxConcurrency) for efficiency.
|
|
25
|
+
*/
|
|
26
|
+
export declare function comparePersonas(options: ComparePersonasOptions): Promise<PersonaComparisonResult>;
|
|
27
|
+
/**
|
|
28
|
+
* Generate a formatted comparison report.
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatComparisonReport(comparison: PersonaComparisonResult): string;
|
|
31
|
+
//# sourceMappingURL=persona-comparison.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona-comparison.d.ts","sourceRoot":"","sources":["../../src/analysis/persona-comparison.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAwB,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEjF,MAAM,WAAW,sBAAsB;IACrC,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CAoMlC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,uBAAuB,GAAG,MAAM,CAsDlF"}
|