@continuum8032/playwright-ai-tools 0.2.0-oidc-bootstrap.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.
@@ -0,0 +1,22 @@
1
+ import { Reporter, FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
2
+ import { j as AnalysisStore } from './types-B55GjfW7.cjs';
3
+
4
+ interface PlaywrightAiReporterOptions {
5
+ outputDir?: string;
6
+ databasePath?: string;
7
+ store?: AnalysisStore;
8
+ outputLanguage?: string;
9
+ }
10
+ declare class PlaywrightAiReporter implements Reporter {
11
+ private readonly outputDir;
12
+ private readonly store;
13
+ private readonly outputLanguage?;
14
+ private run;
15
+ private failures;
16
+ constructor(options?: PlaywrightAiReporterOptions);
17
+ onBegin(_config: FullConfig, suite: Suite): Promise<void>;
18
+ onTestEnd(test: TestCase, result: TestResult): Promise<void>;
19
+ onEnd(_result: FullResult): Promise<void>;
20
+ }
21
+
22
+ export { PlaywrightAiReporter, type PlaywrightAiReporterOptions, PlaywrightAiReporter as default };
@@ -0,0 +1,22 @@
1
+ import { Reporter, FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
2
+ import { j as AnalysisStore } from './types-B55GjfW7.js';
3
+
4
+ interface PlaywrightAiReporterOptions {
5
+ outputDir?: string;
6
+ databasePath?: string;
7
+ store?: AnalysisStore;
8
+ outputLanguage?: string;
9
+ }
10
+ declare class PlaywrightAiReporter implements Reporter {
11
+ private readonly outputDir;
12
+ private readonly store;
13
+ private readonly outputLanguage?;
14
+ private run;
15
+ private failures;
16
+ constructor(options?: PlaywrightAiReporterOptions);
17
+ onBegin(_config: FullConfig, suite: Suite): Promise<void>;
18
+ onTestEnd(test: TestCase, result: TestResult): Promise<void>;
19
+ onEnd(_result: FullResult): Promise<void>;
20
+ }
21
+
22
+ export { PlaywrightAiReporter, type PlaywrightAiReporterOptions, PlaywrightAiReporter as default };
@@ -0,0 +1,133 @@
1
+ import {
2
+ enrichFailureWithArtifacts
3
+ } from "./chunk-QL3XW2UN.js";
4
+ import {
5
+ SQLiteStore,
6
+ analyzeFailures,
7
+ writePortableReport
8
+ } from "./chunk-3VDDPPGG.js";
9
+
10
+ // src/reporter.ts
11
+ function isFailure(status) {
12
+ return ["failed", "timedOut", "interrupted"].includes(status);
13
+ }
14
+ function extractError(result) {
15
+ return result.error?.message || result.error?.stack || result.errors?.[0]?.message || "Unknown error";
16
+ }
17
+ function extractSteps(result) {
18
+ const steps = result.steps || [];
19
+ return steps.filter((step) => step.category === "test.step" || step.category === "expect").map((step) => String(step.title)).filter(Boolean);
20
+ }
21
+ function extractArtifacts(result) {
22
+ return (result.attachments || []).filter((attachment) => attachment.path).map((attachment) => ({
23
+ type: attachment.contentType?.startsWith("image/") ? "screenshot" : attachment.name,
24
+ path: String(attachment.path),
25
+ contentType: attachment.contentType
26
+ }));
27
+ }
28
+ function ciMetadata() {
29
+ if (process.env.GITHUB_RUN_ID && process.env.GITHUB_REPOSITORY) {
30
+ const server = process.env.GITHUB_SERVER_URL || "https://github.com";
31
+ return {
32
+ provider: "github",
33
+ runId: process.env.GITHUB_RUN_ID,
34
+ repository: process.env.GITHUB_REPOSITORY,
35
+ commit: process.env.GITHUB_SHA,
36
+ branch: process.env.GITHUB_REF_NAME,
37
+ url: `${server}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`
38
+ };
39
+ }
40
+ if (process.env.CI) {
41
+ return {
42
+ provider: "generic",
43
+ commit: process.env.GIT_COMMIT || process.env.CI_COMMIT_SHA,
44
+ branch: process.env.GIT_BRANCH || process.env.CI_COMMIT_REF_NAME,
45
+ url: process.env.BUILD_URL || process.env.CI_JOB_URL
46
+ };
47
+ }
48
+ return void 0;
49
+ }
50
+ function projectMetadata(config) {
51
+ return {
52
+ rootDir: config.rootDir,
53
+ projects: (config.projects || []).map((project) => ({
54
+ name: project.name,
55
+ browserName: project.use?.browserName,
56
+ viewport: project.use?.viewport,
57
+ locale: project.use?.locale
58
+ }))
59
+ };
60
+ }
61
+ var PlaywrightAiReporter = class {
62
+ constructor(options = {}) {
63
+ this.run = { id: `local-${Date.now()}`, startedAt: (/* @__PURE__ */ new Date()).toISOString() };
64
+ this.failures = [];
65
+ this.outputDir = options.outputDir || "playwright-ai-report";
66
+ this.store = options.store || new SQLiteStore({ path: options.databasePath });
67
+ this.outputLanguage = options.outputLanguage;
68
+ }
69
+ async onBegin(_config, suite) {
70
+ this.failures = [];
71
+ this.run = {
72
+ id: process.env.PW_AI_RUN_ID || `local-${Date.now()}`,
73
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
74
+ total: suite.allTests().length,
75
+ metadata: {
76
+ ...projectMetadata(_config),
77
+ ci: ciMetadata()
78
+ }
79
+ };
80
+ await this.store.migrate();
81
+ await this.store.saveRun(this.run);
82
+ }
83
+ async onTestEnd(test, result) {
84
+ if (!isFailure(result.status)) {
85
+ return;
86
+ }
87
+ const failure = {
88
+ title: String(test.title),
89
+ file: test.location.file,
90
+ line: test.location.line,
91
+ project: test.parent?.project()?.name,
92
+ workerIndex: result.workerIndex,
93
+ status: result.status,
94
+ retry: result.retry,
95
+ durationMs: result.duration,
96
+ error: extractError(result),
97
+ steps: extractSteps(result),
98
+ artifacts: extractArtifacts(result),
99
+ annotations: test.annotations.map((annotation) => ({
100
+ type: annotation.type,
101
+ description: annotation.description
102
+ })),
103
+ run: { id: this.run.id, ci: ciMetadata() },
104
+ metadata: {
105
+ testId: test.id,
106
+ parallelIndex: result.parallelIndex
107
+ }
108
+ };
109
+ const enriched = await enrichFailureWithArtifacts(failure);
110
+ this.failures.push(enriched);
111
+ await this.store.saveFailure(enriched);
112
+ }
113
+ async onEnd(_result) {
114
+ this.run.finishedAt = (/* @__PURE__ */ new Date()).toISOString();
115
+ this.run.failed = this.failures.length;
116
+ const analyses = await analyzeFailures(this.failures, {
117
+ store: this.store,
118
+ outputLanguage: this.outputLanguage
119
+ });
120
+ await writePortableReport(this.outputDir, {
121
+ run: this.run,
122
+ failures: this.failures,
123
+ analyses
124
+ });
125
+ await this.store.saveRun(this.run);
126
+ await this.store.close();
127
+ }
128
+ };
129
+ var reporter_default = PlaywrightAiReporter;
130
+ export {
131
+ PlaywrightAiReporter,
132
+ reporter_default as default
133
+ };
@@ -0,0 +1,355 @@
1
+ type FailureStatus = 'failed' | 'timedOut' | 'interrupted' | 'skipped' | 'passed' | string;
2
+ interface ArtifactRecord {
3
+ type: string;
4
+ path: string;
5
+ contentType?: string;
6
+ metadata?: Record<string, unknown>;
7
+ }
8
+ interface ManualTestArtifact {
9
+ type: string;
10
+ path?: string;
11
+ url?: string;
12
+ contentType?: string;
13
+ metadata?: Record<string, unknown>;
14
+ }
15
+ interface ManualTestStep {
16
+ index?: number;
17
+ action: string;
18
+ expected?: string;
19
+ data?: Record<string, unknown>;
20
+ artifacts?: ManualTestArtifact[];
21
+ }
22
+ interface ManualTestCase {
23
+ id: string;
24
+ key?: string;
25
+ title: string;
26
+ description?: string;
27
+ preconditions?: string;
28
+ steps: ManualTestStep[];
29
+ artifacts?: ManualTestArtifact[];
30
+ labels?: string[];
31
+ source?: {
32
+ provider?: string;
33
+ project?: string;
34
+ url?: string;
35
+ };
36
+ metadata?: Record<string, unknown>;
37
+ }
38
+ interface ManualTestCaseQuery {
39
+ project: string;
40
+ query?: string;
41
+ limit?: number;
42
+ }
43
+ interface ManualTestProvider {
44
+ listCases(input: ManualTestCaseQuery): Promise<ManualTestCase[]>;
45
+ }
46
+ type FailureCategory = 'selector' | 'timing' | 'runtime' | 'test_data' | 'visual' | 'interaction' | 'environment' | 'unknown';
47
+ type RiskLevel = 'low' | 'medium' | 'high';
48
+ interface ConsoleEvent {
49
+ level: string;
50
+ text: string;
51
+ url?: string;
52
+ lineNumber?: number;
53
+ columnNumber?: number;
54
+ timestamp?: number;
55
+ }
56
+ interface NetworkEvent {
57
+ url: string;
58
+ method?: string;
59
+ status?: number;
60
+ statusText?: string;
61
+ errorText?: string;
62
+ timestamp?: number;
63
+ }
64
+ interface ActionEvent {
65
+ name: string;
66
+ selector?: string;
67
+ url?: string;
68
+ timestamp?: number;
69
+ pageId?: string;
70
+ }
71
+ interface TraceSummary {
72
+ browserContext?: Record<string, unknown>;
73
+ page?: {
74
+ url?: string;
75
+ title?: string;
76
+ snapshot?: string;
77
+ };
78
+ pageSnapshot?: string;
79
+ consoleErrors: ConsoleEvent[];
80
+ networkFailures: NetworkEvent[];
81
+ lastActions: ActionEvent[];
82
+ artifactRefs: ArtifactRecord[];
83
+ }
84
+ interface FailureRecord {
85
+ title: string;
86
+ file: string;
87
+ line?: number;
88
+ project?: string;
89
+ workerIndex?: number;
90
+ status: FailureStatus;
91
+ retry?: number;
92
+ durationMs?: number;
93
+ error: string;
94
+ steps?: string[];
95
+ artifacts?: ArtifactRecord[];
96
+ artifactRefs?: ArtifactRecord[];
97
+ annotations?: Array<{
98
+ type: string;
99
+ description?: string;
100
+ }>;
101
+ browserContext?: Record<string, unknown>;
102
+ page?: {
103
+ url?: string;
104
+ title?: string;
105
+ snapshot?: string;
106
+ };
107
+ pageSnapshot?: string;
108
+ consoleErrors?: ConsoleEvent[];
109
+ networkFailures?: NetworkEvent[];
110
+ lastActions?: ActionEvent[];
111
+ trace?: TraceSummary;
112
+ run?: Record<string, unknown>;
113
+ metadata?: Record<string, unknown>;
114
+ }
115
+ interface AnalysisResult {
116
+ side: 'app_bug' | 'test_bug' | 'flaky_test' | 'env_issue' | 'unknown';
117
+ rootCause: string;
118
+ evidence: string[];
119
+ reproductionSteps: string[];
120
+ suspects: {
121
+ selectors: string[];
122
+ pages: string[];
123
+ endpoints: string[];
124
+ };
125
+ fixSuggestions: string[];
126
+ confidence: number;
127
+ category: FailureCategory;
128
+ risk: RiskLevel;
129
+ evidenceRefs: string[];
130
+ confidenceReasons: string[];
131
+ needsHumanReview: boolean;
132
+ suggestedFixes?: PatchSuggestion[];
133
+ source: 'deterministic' | 'ai' | 'cache' | 'unknown';
134
+ tokenUsage?: {
135
+ inputTokens: number;
136
+ outputTokens: number;
137
+ totalTokens: number;
138
+ };
139
+ }
140
+ type PatchPolicyDecision = 'review' | 'blocked';
141
+ interface PatchSuggestion {
142
+ filePath: string;
143
+ line?: number;
144
+ oldSnippet: string;
145
+ newSnippet: string;
146
+ explanation: string;
147
+ evidence: string[];
148
+ risk: RiskLevel;
149
+ policyDecision: PatchPolicyDecision;
150
+ reviewReason: string;
151
+ }
152
+ interface FailureGroup {
153
+ signature: string;
154
+ pattern: string;
155
+ failures: FailureRecord[];
156
+ }
157
+ interface RunRecord {
158
+ id: string;
159
+ startedAt?: string;
160
+ finishedAt?: string;
161
+ total?: number;
162
+ passed?: number;
163
+ failed?: number;
164
+ skipped?: number;
165
+ metadata?: Record<string, unknown>;
166
+ }
167
+ interface MemoryRecordInput {
168
+ namespace: string;
169
+ kind: string;
170
+ key: string;
171
+ value: Record<string, unknown>;
172
+ tags?: string[];
173
+ confidence?: number;
174
+ source: string;
175
+ }
176
+ interface MemoryRecord extends Required<MemoryRecordInput> {
177
+ supersededBy: string | null;
178
+ createdAt: string;
179
+ updatedAt: string;
180
+ }
181
+ interface SearchMemoryInput {
182
+ namespace?: string;
183
+ kind?: string;
184
+ query?: string;
185
+ tags?: string[];
186
+ limit?: number;
187
+ }
188
+ type FeedbackDecision = 'approved' | 'rejected' | 'needs_work' | 'mark_flaky';
189
+ interface FeedbackRecordInput {
190
+ signature: string;
191
+ decision: FeedbackDecision;
192
+ reason?: string;
193
+ metadata?: Record<string, unknown>;
194
+ }
195
+ interface FeedbackRecord extends Required<FeedbackRecordInput> {
196
+ createdAt: string;
197
+ }
198
+ interface FailureHistoryQuery {
199
+ signature?: string;
200
+ query?: string;
201
+ file?: string;
202
+ limit?: number;
203
+ }
204
+ interface ProjectContext {
205
+ namespace?: string;
206
+ repository?: string;
207
+ commit?: string;
208
+ branch?: string;
209
+ ci?: Record<string, unknown>;
210
+ }
211
+ interface PrivacyPolicy {
212
+ redactSecrets?: boolean;
213
+ }
214
+ interface AnalysisStore {
215
+ migrate(): Promise<void>;
216
+ saveRun(run: RunRecord): Promise<void>;
217
+ saveFailure(failure: FailureRecord): Promise<void>;
218
+ saveAnalysis(signature: string, analysis: AnalysisResult): Promise<void>;
219
+ getCachedAnalysis(signature: string): Promise<AnalysisResult | null>;
220
+ upsertMemory(record: MemoryRecordInput): Promise<void>;
221
+ searchMemory(input: SearchMemoryInput): Promise<MemoryRecord[]>;
222
+ recordFeedback(input: FeedbackRecordInput): Promise<void>;
223
+ searchFeedback(input: {
224
+ signature?: string;
225
+ decision?: FeedbackDecision;
226
+ query?: string;
227
+ limit?: number;
228
+ }): Promise<FeedbackRecord[]>;
229
+ findFailures(input: FailureHistoryQuery): Promise<FailureRecord[]>;
230
+ getRun?(id: string): Promise<RunRecord | null>;
231
+ stats?(): Promise<Record<string, number>>;
232
+ close(): Promise<void>;
233
+ }
234
+ interface AiProviderRequest {
235
+ failure: FailureRecord;
236
+ outputLanguage: string;
237
+ similarAnalyses?: AnalysisResult[];
238
+ }
239
+ interface AiProvider {
240
+ analyzeFailure(request: AiProviderRequest): Promise<AnalysisResult>;
241
+ }
242
+ interface IssueReporter {
243
+ publishAnalysis(report: {
244
+ failure: FailureRecord;
245
+ analysis: AnalysisResult;
246
+ markdown: string;
247
+ }): Promise<{
248
+ url?: string;
249
+ id?: string;
250
+ } | void>;
251
+ }
252
+ interface ArtifactProvider {
253
+ resolveArtifacts(failure: FailureRecord): Promise<ArtifactRecord[]>;
254
+ }
255
+ interface TestManagementProvider {
256
+ resolveCase(failure: FailureRecord): Promise<Record<string, unknown> | null>;
257
+ }
258
+ interface BrowserEvidence {
259
+ requestedUrl: string;
260
+ currentUrl: string;
261
+ title: string;
262
+ domSummary: string;
263
+ htmlSnippet: string;
264
+ screenshotBase64: string;
265
+ }
266
+ interface GeneratedLocator {
267
+ stepIndex?: number;
268
+ selector: string;
269
+ reason: string;
270
+ }
271
+ interface GeneratedStepCoverage {
272
+ stepIndex?: number;
273
+ status: 'covered' | 'partial' | 'missing';
274
+ notes: string;
275
+ }
276
+ interface TestGenerationProviderRequest {
277
+ manualCase: ManualTestCase;
278
+ url: string;
279
+ browser: BrowserEvidence;
280
+ outputLanguage?: string;
281
+ }
282
+ interface TestGenerationProviderResult {
283
+ code: string;
284
+ locators: GeneratedLocator[];
285
+ coverage: GeneratedStepCoverage[];
286
+ warnings: string[];
287
+ }
288
+ interface TestGenerationProvider {
289
+ generateTest(request: TestGenerationProviderRequest): Promise<TestGenerationProviderResult>;
290
+ }
291
+ interface TestGenerationRequest {
292
+ manualCase: ManualTestCase;
293
+ url: string;
294
+ outputDir?: string;
295
+ provider: TestGenerationProvider;
296
+ confirmBrowserRun?: boolean;
297
+ allowDestructiveActions?: boolean;
298
+ storageState?: string;
299
+ sourceName?: string;
300
+ outputLanguage?: string;
301
+ }
302
+ interface GeneratedTestDraft extends TestGenerationProviderResult {
303
+ manualCase: ManualTestCase;
304
+ filePath: string;
305
+ reportPath: string;
306
+ screenshotPath: string;
307
+ browser: Omit<BrowserEvidence, 'screenshotBase64'>;
308
+ needsHumanReview: boolean;
309
+ }
310
+ interface ReportPublisher {
311
+ publishReport(report: {
312
+ run: RunRecord;
313
+ failures: FailureRecord[];
314
+ analyses: AnalysisResult[];
315
+ markdown: string;
316
+ html?: string;
317
+ }): Promise<{
318
+ url?: string;
319
+ id?: string;
320
+ } | void>;
321
+ }
322
+ interface PatchSuggestionPublisher {
323
+ publishSuggestions(report: {
324
+ failure: FailureRecord;
325
+ analysis: AnalysisResult;
326
+ suggestions: PatchSuggestion[];
327
+ markdown: string;
328
+ }): Promise<{
329
+ url?: string;
330
+ id?: string;
331
+ } | void>;
332
+ }
333
+ interface ArtifactResolver {
334
+ resolveArtifact(artifact: ArtifactRecord): Promise<string | Buffer | null>;
335
+ }
336
+ interface FeedbackStore {
337
+ recordFeedback(input: {
338
+ signature: string;
339
+ decision: FeedbackDecision;
340
+ reason?: string;
341
+ metadata?: Record<string, unknown>;
342
+ }): Promise<void>;
343
+ }
344
+ interface AnalyzeFailuresOptions {
345
+ store?: AnalysisStore;
346
+ provider?: AiProvider;
347
+ outputLanguage?: string;
348
+ projectContext?: ProjectContext;
349
+ knowledgeSources?: string[];
350
+ ciMetadata?: Record<string, unknown>;
351
+ privacyPolicy?: PrivacyPolicy;
352
+ similarityLimit?: number;
353
+ }
354
+
355
+ export type { AiProvider as A, BrowserEvidence as B, ConsoleEvent as C, PatchPolicyDecision as D, PatchSuggestionPublisher as E, FailureRecord as F, GeneratedTestDraft as G, PrivacyPolicy as H, IssueReporter as I, ProjectContext as J, ReportPublisher as K, RiskLevel as L, ManualTestCase as M, NetworkEvent as N, TestManagementProvider as O, PatchSuggestion as P, RunRecord as R, SearchMemoryInput as S, TestGenerationProvider as T, AnalysisResult as a, AnalyzeFailuresOptions as b, FailureCategory as c, FailureGroup as d, TestGenerationProviderResult as e, TestGenerationRequest as f, AiProviderRequest as g, TestGenerationProviderRequest as h, TraceSummary as i, AnalysisStore as j, MemoryRecord as k, FeedbackRecord as l, MemoryRecordInput as m, FeedbackRecordInput as n, FeedbackDecision as o, FailureHistoryQuery as p, ArtifactProvider as q, ArtifactRecord as r, ArtifactResolver as s, FeedbackStore as t, GeneratedLocator as u, GeneratedStepCoverage as v, ManualTestArtifact as w, ManualTestCaseQuery as x, ManualTestProvider as y, ManualTestStep as z };