@fasttest-ai/qa-agent 0.3.0 → 0.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/bin/install.js +3 -0
- package/bin/qa-agent.js +7 -2
- package/dist/cloud.d.ts +43 -30
- package/dist/cloud.js +8 -25
- package/dist/cloud.js.map +1 -1
- package/dist/healer.d.ts +5 -1
- package/dist/healer.js +85 -16
- package/dist/healer.js.map +1 -1
- package/dist/index.js +298 -30
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +11 -0
- package/dist/install.js +225 -0
- package/dist/install.js.map +1 -0
- package/dist/runner.js +1 -1
- package/dist/runner.js.map +1 -1
- package/package.json +3 -2
package/bin/install.js
ADDED
package/bin/qa-agent.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// CLI entry point —
|
|
3
|
-
|
|
2
|
+
// CLI entry point — routes to MCP server or subcommands
|
|
3
|
+
const sub = process.argv[2];
|
|
4
|
+
if (sub === "install" || sub === "uninstall") {
|
|
5
|
+
await import("../dist/install.js");
|
|
6
|
+
} else {
|
|
7
|
+
await import("../dist/index.js");
|
|
8
|
+
}
|
package/dist/cloud.d.ts
CHANGED
|
@@ -22,6 +22,33 @@ export interface RunResponse {
|
|
|
22
22
|
status: string;
|
|
23
23
|
base_url: string | null;
|
|
24
24
|
test_cases: TestCasePayload[];
|
|
25
|
+
previous_execution_id: string | null;
|
|
26
|
+
}
|
|
27
|
+
export interface RegressionItem {
|
|
28
|
+
test_case_id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
previous_status: string;
|
|
31
|
+
current_status: string;
|
|
32
|
+
error?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface ExecutionDiff {
|
|
35
|
+
previous_execution_id: string | null;
|
|
36
|
+
regressions: RegressionItem[];
|
|
37
|
+
fixes: RegressionItem[];
|
|
38
|
+
new_tests: Array<{
|
|
39
|
+
test_case_id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
status: string;
|
|
42
|
+
}>;
|
|
43
|
+
removed_tests: Array<{
|
|
44
|
+
test_case_id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
}>;
|
|
47
|
+
unchanged: {
|
|
48
|
+
passed: number;
|
|
49
|
+
failed: number;
|
|
50
|
+
};
|
|
51
|
+
healed_count: number;
|
|
25
52
|
}
|
|
26
53
|
export interface TestCasePayload {
|
|
27
54
|
id: string;
|
|
@@ -83,7 +110,6 @@ export declare class CloudClient {
|
|
|
83
110
|
health(): Promise<{
|
|
84
111
|
status: string;
|
|
85
112
|
}>;
|
|
86
|
-
getOrg(): Promise<Record<string, unknown>>;
|
|
87
113
|
listProjects(): Promise<Record<string, unknown>>;
|
|
88
114
|
/** Get-or-create a project by name. Returns project with id. */
|
|
89
115
|
resolveProject(name: string, baseUrl?: string): Promise<{
|
|
@@ -108,15 +134,6 @@ export declare class CloudClient {
|
|
|
108
134
|
id: string;
|
|
109
135
|
name: string;
|
|
110
136
|
}>;
|
|
111
|
-
/** Update an existing test suite. */
|
|
112
|
-
updateSuite(projectId: string, suiteId: string, body: {
|
|
113
|
-
name?: string;
|
|
114
|
-
description?: string;
|
|
115
|
-
tags?: string[];
|
|
116
|
-
}): Promise<{
|
|
117
|
-
id: string;
|
|
118
|
-
name: string;
|
|
119
|
-
}>;
|
|
120
137
|
/** Create a test case and link it to suite(s). */
|
|
121
138
|
createTestCase(body: {
|
|
122
139
|
name: string;
|
|
@@ -145,25 +162,12 @@ export declare class CloudClient {
|
|
|
145
162
|
id: string;
|
|
146
163
|
name: string;
|
|
147
164
|
}>;
|
|
148
|
-
/**
|
|
149
|
-
|
|
165
|
+
/** Resolve an environment by name within a suite's project. */
|
|
166
|
+
resolveEnvironment(suiteId: string, name: string): Promise<{
|
|
150
167
|
id: string;
|
|
151
168
|
name: string;
|
|
152
|
-
|
|
153
|
-
test_cases: Array<{
|
|
154
|
-
id: string;
|
|
155
|
-
name: string;
|
|
156
|
-
steps: Array<Record<string, unknown>>;
|
|
157
|
-
assertions: Array<Record<string, unknown>>;
|
|
158
|
-
}>;
|
|
169
|
+
base_url: string;
|
|
159
170
|
}>;
|
|
160
|
-
/** @deprecated Cloud exploration endpoints removed. Exploration runs via local skill. */
|
|
161
|
-
startExploration(body: {
|
|
162
|
-
url: string;
|
|
163
|
-
max_pages?: number;
|
|
164
|
-
focus?: string;
|
|
165
|
-
project_id?: string;
|
|
166
|
-
}): Promise<Record<string, unknown>>;
|
|
167
171
|
/** Start a test run — returns execution_id + test cases to execute locally. */
|
|
168
172
|
startRun(body: {
|
|
169
173
|
suite_id: string;
|
|
@@ -198,6 +202,8 @@ export declare class CloudClient {
|
|
|
198
202
|
cancelExecution(executionId: string): Promise<Record<string, unknown>>;
|
|
199
203
|
/** Get execution status. */
|
|
200
204
|
getExecutionStatus(executionId: string): Promise<Record<string, unknown>>;
|
|
205
|
+
/** Get regression diff comparing this execution against the previous run. */
|
|
206
|
+
getExecutionDiff(executionId: string): Promise<ExecutionDiff>;
|
|
201
207
|
/** Notify that a test case is about to start executing. Non-fatal. */
|
|
202
208
|
notifyTestStarted(executionId: string, testCaseId: string, testCaseName: string): Promise<void>;
|
|
203
209
|
/** Notify that selector healing is being attempted. Non-fatal. */
|
|
@@ -231,6 +237,17 @@ export declare class CloudClient {
|
|
|
231
237
|
name?: string;
|
|
232
238
|
retry_attempts?: number;
|
|
233
239
|
}>;
|
|
240
|
+
regressions?: Array<{
|
|
241
|
+
name: string;
|
|
242
|
+
previous_status: string;
|
|
243
|
+
current_status: string;
|
|
244
|
+
error?: string;
|
|
245
|
+
}>;
|
|
246
|
+
fixes?: Array<{
|
|
247
|
+
name: string;
|
|
248
|
+
previous_status: string;
|
|
249
|
+
current_status: string;
|
|
250
|
+
}>;
|
|
234
251
|
}): Promise<Record<string, unknown>>;
|
|
235
252
|
/** Save a chaos report with adversarial findings. */
|
|
236
253
|
saveChaosReport(projectId: string | undefined, body: {
|
|
@@ -243,8 +260,4 @@ export declare class CloudClient {
|
|
|
243
260
|
console_errors?: string[];
|
|
244
261
|
}>;
|
|
245
262
|
}): Promise<Record<string, unknown>>;
|
|
246
|
-
/** List chaos reports for the org. */
|
|
247
|
-
listChaosReports(projectId?: string): Promise<Record<string, unknown>>;
|
|
248
|
-
/** Get a single chaos report. */
|
|
249
|
-
getChaosReport(reportId: string): Promise<Record<string, unknown>>;
|
|
250
263
|
}
|
package/dist/cloud.js
CHANGED
|
@@ -87,10 +87,6 @@ export class CloudClient {
|
|
|
87
87
|
const resp = await fetch(url);
|
|
88
88
|
return (await resp.json());
|
|
89
89
|
}
|
|
90
|
-
// --- Organization ---
|
|
91
|
-
async getOrg() {
|
|
92
|
-
return this.get("/orgs/me");
|
|
93
|
-
}
|
|
94
90
|
// --- Projects ---
|
|
95
91
|
async listProjects() {
|
|
96
92
|
return this.get("/qa/projects/");
|
|
@@ -123,10 +119,6 @@ export class CloudClient {
|
|
|
123
119
|
project_id: projectId,
|
|
124
120
|
});
|
|
125
121
|
}
|
|
126
|
-
/** Update an existing test suite. */
|
|
127
|
-
async updateSuite(projectId, suiteId, body) {
|
|
128
|
-
return this.request("PUT", `/qa/projects/${projectId}/test-suites/${suiteId}`, body);
|
|
129
|
-
}
|
|
130
122
|
/** Create a test case and link it to suite(s). */
|
|
131
123
|
async createTestCase(body) {
|
|
132
124
|
return this.post("/qa/test-cases/", body);
|
|
@@ -135,14 +127,10 @@ export class CloudClient {
|
|
|
135
127
|
async updateTestCase(testCaseId, body) {
|
|
136
128
|
return this.request("PUT", `/qa/test-cases/${testCaseId}`, body);
|
|
137
129
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
// --- Exploration (DEPRECATED — cloud exploration endpoints no longer served) ---
|
|
143
|
-
/** @deprecated Cloud exploration endpoints removed. Exploration runs via local skill. */
|
|
144
|
-
async startExploration(body) {
|
|
145
|
-
return this.post("/explore/", body);
|
|
130
|
+
// --- Environments ---
|
|
131
|
+
/** Resolve an environment by name within a suite's project. */
|
|
132
|
+
async resolveEnvironment(suiteId, name) {
|
|
133
|
+
return this.post("/qa/environments/resolve", { suite_id: suiteId, name });
|
|
146
134
|
}
|
|
147
135
|
// --- Execution (Phase 3) ---
|
|
148
136
|
/** Start a test run — returns execution_id + test cases to execute locally. */
|
|
@@ -165,6 +153,10 @@ export class CloudClient {
|
|
|
165
153
|
async getExecutionStatus(executionId) {
|
|
166
154
|
return this.get(`/qa/execution/executions/${executionId}`);
|
|
167
155
|
}
|
|
156
|
+
/** Get regression diff comparing this execution against the previous run. */
|
|
157
|
+
async getExecutionDiff(executionId) {
|
|
158
|
+
return this.get(`/qa/execution/executions/${executionId}/diff`);
|
|
159
|
+
}
|
|
168
160
|
/** Notify that a test case is about to start executing. Non-fatal. */
|
|
169
161
|
async notifyTestStarted(executionId, testCaseId, testCaseName) {
|
|
170
162
|
try {
|
|
@@ -209,14 +201,5 @@ export class CloudClient {
|
|
|
209
201
|
const qs = projectId ? `?project_id=${projectId}` : "";
|
|
210
202
|
return this.post(`/qa/chaos/reports${qs}`, body);
|
|
211
203
|
}
|
|
212
|
-
/** List chaos reports for the org. */
|
|
213
|
-
async listChaosReports(projectId) {
|
|
214
|
-
const qs = projectId ? `?project_id=${projectId}` : "";
|
|
215
|
-
return this.get(`/qa/chaos/reports${qs}`);
|
|
216
|
-
}
|
|
217
|
-
/** Get a single chaos report. */
|
|
218
|
-
async getChaosReport(reportId) {
|
|
219
|
-
return this.get(`/qa/chaos/reports/${reportId}`);
|
|
220
|
-
}
|
|
221
204
|
}
|
|
222
205
|
//# sourceMappingURL=cloud.js.map
|
package/dist/cloud.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud.js","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"cloud.js","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"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"}
|
package/dist/healer.d.ts
CHANGED
|
@@ -20,8 +20,12 @@ export interface HealResult {
|
|
|
20
20
|
confidence?: number;
|
|
21
21
|
error?: string;
|
|
22
22
|
}
|
|
23
|
+
export interface ElementContext {
|
|
24
|
+
action: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
}
|
|
23
27
|
/**
|
|
24
28
|
* Attempt to heal a broken selector by trying 5 strategies in order.
|
|
25
29
|
* Returns the first working selector with its confidence score.
|
|
26
30
|
*/
|
|
27
|
-
export declare function healSelector(page: Page, cloud: CloudClient | null, originalSelector: string, failureType: string, errorMessage: string, pageUrl: string): Promise<HealResult>;
|
|
31
|
+
export declare function healSelector(page: Page, cloud: CloudClient | null, originalSelector: string, failureType: string, errorMessage: string, pageUrl: string, context?: ElementContext): Promise<HealResult>;
|
package/dist/healer.js
CHANGED
|
@@ -28,7 +28,7 @@ const CONFIDENCE = {
|
|
|
28
28
|
* Attempt to heal a broken selector by trying 5 strategies in order.
|
|
29
29
|
* Returns the first working selector with its confidence score.
|
|
30
30
|
*/
|
|
31
|
-
export async function healSelector(page, cloud, originalSelector, failureType, errorMessage, pageUrl) {
|
|
31
|
+
export async function healSelector(page, cloud, originalSelector, failureType, errorMessage, pageUrl, context) {
|
|
32
32
|
// 1. Check Cloud for a stored pattern first (only if cloud is available)
|
|
33
33
|
if (cloud) {
|
|
34
34
|
try {
|
|
@@ -42,9 +42,10 @@ export async function healSelector(page, cloud, originalSelector, failureType, e
|
|
|
42
42
|
return { healed: false, error: classification.reason ?? "Classified as real bug" };
|
|
43
43
|
}
|
|
44
44
|
if (classification.pattern) {
|
|
45
|
-
// Validate the stored pattern still works
|
|
45
|
+
// Validate the stored pattern still works and targets the right element
|
|
46
46
|
const found = await testSelector(page, classification.pattern.healed_value);
|
|
47
|
-
|
|
47
|
+
const valid = found && await validateCandidate(page, classification.pattern.healed_value, context);
|
|
48
|
+
if (found && valid) {
|
|
48
49
|
return {
|
|
49
50
|
healed: true,
|
|
50
51
|
newSelector: classification.pattern.healed_value,
|
|
@@ -52,6 +53,10 @@ export async function healSelector(page, cloud, originalSelector, failureType, e
|
|
|
52
53
|
confidence: classification.pattern.confidence,
|
|
53
54
|
};
|
|
54
55
|
}
|
|
56
|
+
// Pattern failed — report to cloud for deprecation tracking
|
|
57
|
+
if (classification.pattern.id) {
|
|
58
|
+
reportPatternFailedQuietly(cloud, classification.pattern.id, pageUrl);
|
|
59
|
+
}
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
62
|
catch {
|
|
@@ -68,6 +73,10 @@ export async function healSelector(page, cloud, originalSelector, failureType, e
|
|
|
68
73
|
for (const strategy of strategies) {
|
|
69
74
|
const candidate = await strategy.fn();
|
|
70
75
|
if (candidate) {
|
|
76
|
+
// Validate the candidate targets the right type of element
|
|
77
|
+
const valid = await validateCandidate(page, candidate, context);
|
|
78
|
+
if (!valid)
|
|
79
|
+
continue; // Wrong element type — try next strategy
|
|
71
80
|
// Report the pattern to Cloud for future reuse (if connected)
|
|
72
81
|
if (cloud) {
|
|
73
82
|
await storePatternQuietly(cloud, failureType, originalSelector, candidate, strategy.name, CONFIDENCE[strategy.name] ?? 0.8, pageUrl);
|
|
@@ -90,12 +99,67 @@ export async function healSelector(page, cloud, originalSelector, failureType, e
|
|
|
90
99
|
async function testSelector(page, selector) {
|
|
91
100
|
try {
|
|
92
101
|
const count = await page.locator(selector).count();
|
|
93
|
-
return count
|
|
102
|
+
return count === 1; // Reject ambiguous matches — must be exactly one element
|
|
94
103
|
}
|
|
95
104
|
catch {
|
|
96
105
|
return false;
|
|
97
106
|
}
|
|
98
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Validate that a candidate selector points to an element compatible
|
|
110
|
+
* with the step's action and description. Returns true if valid.
|
|
111
|
+
*/
|
|
112
|
+
async function validateCandidate(page, selector, context) {
|
|
113
|
+
if (!context)
|
|
114
|
+
return true;
|
|
115
|
+
try {
|
|
116
|
+
const info = await page.locator(selector).evaluate((el) => ({
|
|
117
|
+
tag: el.tagName.toLowerCase(),
|
|
118
|
+
role: el.getAttribute("role"),
|
|
119
|
+
type: el.type ?? null,
|
|
120
|
+
contentEditable: el.getAttribute("contenteditable"),
|
|
121
|
+
text: (el.textContent ?? "").trim().slice(0, 200),
|
|
122
|
+
ariaLabel: el.getAttribute("aria-label") ?? "",
|
|
123
|
+
}));
|
|
124
|
+
const action = context.action;
|
|
125
|
+
// Check action compatibility
|
|
126
|
+
if (action === "click" || action === "hover") {
|
|
127
|
+
const interactiveTags = ["button", "a", "input", "select", "summary", "details", "label", "option"];
|
|
128
|
+
const interactiveRoles = ["button", "link", "tab", "menuitem", "checkbox", "radio", "switch", "option"];
|
|
129
|
+
const isInteractive = interactiveTags.includes(info.tag) ||
|
|
130
|
+
(info.role != null && interactiveRoles.includes(info.role));
|
|
131
|
+
if (!isInteractive)
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
if (action === "fill" || action === "type") {
|
|
135
|
+
const isFillable = info.tag === "input" ||
|
|
136
|
+
info.tag === "textarea" ||
|
|
137
|
+
info.contentEditable === "true" ||
|
|
138
|
+
info.contentEditable === "";
|
|
139
|
+
if (!isFillable)
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
if (action === "select") {
|
|
143
|
+
if (info.tag !== "select" && info.role !== "listbox" && info.role !== "combobox") {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Check description text similarity (if description contains quoted text)
|
|
148
|
+
if (context.description) {
|
|
149
|
+
const quotedMatch = context.description.match(/['"]([^'"]+)['"]/);
|
|
150
|
+
if (quotedMatch) {
|
|
151
|
+
const expectedText = quotedMatch[1].toLowerCase();
|
|
152
|
+
const elementText = (info.text + " " + info.ariaLabel).toLowerCase();
|
|
153
|
+
if (!elementText.includes(expectedText))
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return true; // If evaluation fails, don't block healing
|
|
161
|
+
}
|
|
162
|
+
}
|
|
99
163
|
/**
|
|
100
164
|
* Strategy 1: Look for a data-testid attribute near the original selector.
|
|
101
165
|
*/
|
|
@@ -107,7 +171,6 @@ async function tryDataTestId(page, original) {
|
|
|
107
171
|
return null;
|
|
108
172
|
const candidates = [
|
|
109
173
|
`[data-testid="${name}"]`,
|
|
110
|
-
`[data-testid*="${name}"]`,
|
|
111
174
|
`[data-test="${name}"]`,
|
|
112
175
|
`[data-test-id="${name}"]`,
|
|
113
176
|
];
|
|
@@ -131,8 +194,6 @@ async function tryAria(page, original) {
|
|
|
131
194
|
return null;
|
|
132
195
|
const candidates = [
|
|
133
196
|
`[aria-label="${name}"]`,
|
|
134
|
-
`[aria-label*="${name}"]`,
|
|
135
|
-
`[role][aria-label*="${name}"]`,
|
|
136
197
|
];
|
|
137
198
|
for (const sel of candidates) {
|
|
138
199
|
if (await testSelector(page, sel))
|
|
@@ -152,12 +213,14 @@ async function tryTextContent(page, original) {
|
|
|
152
213
|
const name = extractName(original);
|
|
153
214
|
if (!name)
|
|
154
215
|
return null;
|
|
155
|
-
//
|
|
216
|
+
// Use CSS attribute and ARIA selectors (Playwright 1.52+ compatible)
|
|
156
217
|
const candidates = [
|
|
157
|
-
`
|
|
158
|
-
|
|
159
|
-
`
|
|
160
|
-
`
|
|
218
|
+
`[aria-label="${name}"]`,
|
|
219
|
+
`[title="${name}"]`,
|
|
220
|
+
`[alt="${name}"]`,
|
|
221
|
+
`[placeholder="${name}"]`,
|
|
222
|
+
`role=button[name="${name}"]`,
|
|
223
|
+
`role=link[name="${name}"]`,
|
|
161
224
|
];
|
|
162
225
|
for (const sel of candidates) {
|
|
163
226
|
if (await testSelector(page, sel))
|
|
@@ -185,10 +248,6 @@ async function tryStructural(page, original) {
|
|
|
185
248
|
candidates.push(`${tag}[name="${name}"]`);
|
|
186
249
|
candidates.push(`${tag}[id*="${name}"]`);
|
|
187
250
|
candidates.push(`${tag}[class*="${name}"]`);
|
|
188
|
-
candidates.push(`form ${tag}[type="submit"]`);
|
|
189
|
-
}
|
|
190
|
-
else if (tag) {
|
|
191
|
-
candidates.push(`form >> ${tag}[type="submit"]`);
|
|
192
251
|
}
|
|
193
252
|
for (const sel of candidates) {
|
|
194
253
|
if (await testSelector(page, sel))
|
|
@@ -243,4 +302,14 @@ async function storePatternQuietly(cloud, failureType, originalValue, healedValu
|
|
|
243
302
|
// Non-fatal — pattern storage failure shouldn't block test execution
|
|
244
303
|
}
|
|
245
304
|
}
|
|
305
|
+
async function reportPatternFailedQuietly(cloud, patternId, pageUrl) {
|
|
306
|
+
try {
|
|
307
|
+
await cloud.post(`/qa/healing/patterns/${patternId}/failed`, {
|
|
308
|
+
page_url: pageUrl,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// Non-fatal
|
|
313
|
+
}
|
|
314
|
+
}
|
|
246
315
|
//# sourceMappingURL=healer.js.map
|
package/dist/healer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"healer.js","sourceRoot":"","sources":["../src/healer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"healer.js","sourceRoot":"","sources":["../src/healer.ts"],"names":[],"mappings":"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"}
|