playwright-mimic 0.1.0 → 0.1.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.
Files changed (110) hide show
  1. package/README.md +633 -446
  2. package/dist/agentic/agent.d.ts +106 -0
  3. package/dist/agentic/agent.d.ts.map +1 -0
  4. package/dist/agentic/agent.js +528 -0
  5. package/dist/agentic/agent.js.map +1 -0
  6. package/dist/agentic/index.d.ts +13 -0
  7. package/dist/agentic/index.d.ts.map +1 -0
  8. package/dist/agentic/index.js +12 -0
  9. package/dist/agentic/index.js.map +1 -0
  10. package/dist/agentic/planner.d.ts +41 -0
  11. package/dist/agentic/planner.d.ts.map +1 -0
  12. package/dist/agentic/planner.js +136 -0
  13. package/dist/agentic/planner.js.map +1 -0
  14. package/dist/agentic/react.d.ts +35 -0
  15. package/dist/agentic/react.d.ts.map +1 -0
  16. package/dist/agentic/react.js +170 -0
  17. package/dist/agentic/react.js.map +1 -0
  18. package/dist/agentic/recovery.d.ts +55 -0
  19. package/dist/agentic/recovery.d.ts.map +1 -0
  20. package/dist/agentic/recovery.js +200 -0
  21. package/dist/agentic/recovery.js.map +1 -0
  22. package/dist/agentic/reflection.d.ts +40 -0
  23. package/dist/agentic/reflection.d.ts.map +1 -0
  24. package/dist/agentic/reflection.js +142 -0
  25. package/dist/agentic/reflection.js.map +1 -0
  26. package/dist/agentic/types.d.ts +177 -0
  27. package/dist/agentic/types.d.ts.map +1 -0
  28. package/dist/agentic/types.js +8 -0
  29. package/dist/agentic/types.js.map +1 -0
  30. package/dist/agentic/wait.d.ts +50 -0
  31. package/dist/agentic/wait.d.ts.map +1 -0
  32. package/dist/agentic/wait.js +140 -0
  33. package/dist/agentic/wait.js.map +1 -0
  34. package/dist/agentic-mimic.d.ts +56 -0
  35. package/dist/agentic-mimic.d.ts.map +1 -0
  36. package/dist/agentic-mimic.js +98 -0
  37. package/dist/agentic-mimic.js.map +1 -0
  38. package/dist/index.d.ts +11 -8
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +12 -9
  41. package/dist/index.js.map +1 -1
  42. package/dist/mimic/actionType.d.ts +7 -0
  43. package/dist/mimic/actionType.d.ts.map +1 -0
  44. package/dist/mimic/actionType.js +44 -0
  45. package/dist/mimic/actionType.js.map +1 -0
  46. package/dist/mimic/annotations.d.ts +20 -0
  47. package/dist/mimic/annotations.d.ts.map +1 -0
  48. package/dist/mimic/annotations.js +30 -0
  49. package/dist/mimic/annotations.js.map +1 -0
  50. package/dist/mimic/cli.d.ts +15 -0
  51. package/dist/mimic/cli.d.ts.map +1 -0
  52. package/dist/mimic/cli.js +17 -0
  53. package/dist/mimic/cli.js.map +1 -0
  54. package/dist/mimic/click.d.ts +39 -0
  55. package/dist/mimic/click.d.ts.map +1 -0
  56. package/dist/mimic/click.js +233 -0
  57. package/dist/mimic/click.js.map +1 -0
  58. package/dist/mimic/forms.d.ts +47 -0
  59. package/dist/mimic/forms.d.ts.map +1 -0
  60. package/dist/mimic/forms.js +264 -0
  61. package/dist/mimic/forms.js.map +1 -0
  62. package/dist/mimic/navigation.d.ts +19 -0
  63. package/dist/mimic/navigation.d.ts.map +1 -0
  64. package/dist/mimic/navigation.js +117 -0
  65. package/dist/mimic/navigation.js.map +1 -0
  66. package/dist/mimic/replay.d.ts +21 -0
  67. package/dist/mimic/replay.d.ts.map +1 -0
  68. package/dist/mimic/replay.js +133 -0
  69. package/dist/mimic/replay.js.map +1 -0
  70. package/dist/mimic/schema/action.d.ts +315 -0
  71. package/dist/mimic/schema/action.d.ts.map +1 -0
  72. package/dist/mimic/schema/action.js +204 -0
  73. package/dist/mimic/schema/action.js.map +1 -0
  74. package/dist/mimic/selector.d.ts +139 -0
  75. package/dist/mimic/selector.d.ts.map +1 -0
  76. package/dist/mimic/selector.js +1103 -0
  77. package/dist/mimic/selector.js.map +1 -0
  78. package/dist/mimic/selectorDescriptor.d.ts +13 -0
  79. package/dist/mimic/selectorDescriptor.d.ts.map +1 -0
  80. package/dist/mimic/selectorDescriptor.js +9 -0
  81. package/dist/mimic/selectorDescriptor.js.map +1 -0
  82. package/dist/mimic/selectorSerialization.d.ts +30 -0
  83. package/dist/mimic/selectorSerialization.d.ts.map +1 -0
  84. package/dist/mimic/selectorSerialization.js +170 -0
  85. package/dist/mimic/selectorSerialization.js.map +1 -0
  86. package/dist/mimic/selectorTypes.d.ts +200 -0
  87. package/dist/mimic/selectorTypes.d.ts.map +1 -0
  88. package/dist/mimic/selectorTypes.js +2 -0
  89. package/dist/mimic/selectorTypes.js.map +1 -0
  90. package/dist/mimic/selectorUtils.d.ts +26 -0
  91. package/dist/mimic/selectorUtils.d.ts.map +1 -0
  92. package/dist/mimic/selectorUtils.js +144 -0
  93. package/dist/mimic/selectorUtils.js.map +1 -0
  94. package/dist/mimic/storage.d.ts +75 -0
  95. package/dist/mimic/storage.d.ts.map +1 -0
  96. package/dist/mimic/storage.js +197 -0
  97. package/dist/mimic/storage.js.map +1 -0
  98. package/dist/mimic/types.d.ts +63 -0
  99. package/dist/mimic/types.d.ts.map +1 -0
  100. package/dist/mimic/types.js +7 -0
  101. package/dist/mimic/types.js.map +1 -0
  102. package/dist/mimic.d.ts +28 -4
  103. package/dist/mimic.d.ts.map +1 -1
  104. package/dist/mimic.js +374 -32
  105. package/dist/mimic.js.map +1 -1
  106. package/dist/mimicry.d.ts +4 -4
  107. package/dist/mimicry.d.ts.map +1 -1
  108. package/dist/mimicry.js +22 -13
  109. package/dist/mimicry.js.map +1 -1
  110. package/package.json +5 -2
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Reconstruct a Playwright Locator from a stored SelectorDescriptor
3
+ *
4
+ * This function recursively builds a locator from a selector descriptor,
5
+ * handling nested selectors by chaining locator method calls.
6
+ *
7
+ * @param page - Playwright Page object (or parent Locator for nested selectors)
8
+ * @param descriptor - SelectorDescriptor (can be from JSON)
9
+ * @returns Playwright Locator reconstructed from the descriptor
10
+ */
11
+ export function getFromSelector(page, descriptor) {
12
+ let baseLocator;
13
+ // Build base locator based on selector type
14
+ // Both Page and Locator have the same locator methods, so we can call them directly
15
+ switch (descriptor.type) {
16
+ case 'testid':
17
+ baseLocator = page.getByTestId(descriptor.value);
18
+ break;
19
+ case 'role':
20
+ if (descriptor.name !== undefined) {
21
+ // Handle regex patterns
22
+ const nameValue = descriptor.name instanceof RegExp
23
+ ? descriptor.name
24
+ : descriptor.name;
25
+ const roleOptions = descriptor.name instanceof RegExp
26
+ ? { name: nameValue }
27
+ : { name: nameValue, exact: descriptor.exact ?? false };
28
+ baseLocator = page.getByRole(descriptor.role, roleOptions);
29
+ }
30
+ else {
31
+ baseLocator = page.getByRole(descriptor.role);
32
+ }
33
+ break;
34
+ case 'label':
35
+ {
36
+ const labelOptions = descriptor.value instanceof RegExp
37
+ ? {}
38
+ : { exact: descriptor.exact ?? false };
39
+ baseLocator = page.getByLabel(descriptor.value, labelOptions);
40
+ }
41
+ break;
42
+ case 'placeholder':
43
+ {
44
+ const placeholderOptions = descriptor.value instanceof RegExp
45
+ ? {}
46
+ : { exact: descriptor.exact ?? false };
47
+ baseLocator = page.getByPlaceholder(descriptor.value, placeholderOptions);
48
+ }
49
+ break;
50
+ case 'alt':
51
+ {
52
+ const altOptions = descriptor.value instanceof RegExp
53
+ ? {}
54
+ : { exact: descriptor.exact ?? false };
55
+ baseLocator = page.getByAltText(descriptor.value, altOptions);
56
+ }
57
+ break;
58
+ case 'title':
59
+ {
60
+ const titleOptions = descriptor.value instanceof RegExp
61
+ ? {}
62
+ : { exact: descriptor.exact ?? false };
63
+ baseLocator = page.getByTitle(descriptor.value, titleOptions);
64
+ }
65
+ break;
66
+ case 'text':
67
+ {
68
+ const textOptions = descriptor.value instanceof RegExp
69
+ ? {}
70
+ : { exact: descriptor.exact ?? false };
71
+ baseLocator = page.getByText(descriptor.value, textOptions);
72
+ }
73
+ break;
74
+ case 'css':
75
+ baseLocator = page.locator(descriptor.selector);
76
+ break;
77
+ default:
78
+ // TypeScript exhaustiveness check - if we reach here, a case is missing
79
+ const _exhaustive = descriptor;
80
+ void _exhaustive; // Suppress unused variable warning
81
+ throw new Error(`Unknown selector type: ${descriptor.type}`);
82
+ }
83
+ // If there's a nested child selector, recursively build it from the base locator
84
+ if (descriptor.child) {
85
+ return getFromSelector(baseLocator, descriptor.child);
86
+ }
87
+ return baseLocator;
88
+ }
89
+ /**
90
+ * Verify that a selector uniquely identifies the target element
91
+ *
92
+ * This function checks if a locator built from a SelectorDescriptor matches
93
+ * exactly one element, and optionally verifies it matches the original target element.
94
+ *
95
+ * @param page - Playwright Page object
96
+ * @param descriptor - SelectorDescriptor to verify
97
+ * @param targetElementHandle - Optional element handle to verify the match is correct
98
+ * @returns Promise resolving to true if selector is unique (and matches target if provided)
99
+ */
100
+ export async function verifySelectorUniqueness(page, descriptor, targetElementHandle) {
101
+ try {
102
+ const locator = getFromSelector(page, descriptor);
103
+ const count = await locator.count();
104
+ // Must match exactly one element
105
+ if (count !== 1) {
106
+ return false;
107
+ }
108
+ // If target element provided, verify it's the same element
109
+ if (targetElementHandle) {
110
+ const matchedElement = await locator.elementHandle();
111
+ if (!matchedElement) {
112
+ return false;
113
+ }
114
+ // Compare elements by checking if they have the same properties
115
+ // We'll compare by getting a unique identifier from both elements
116
+ const targetId = await page.evaluate((el) => {
117
+ // Create a unique identifier: tag + id + text + position
118
+ const rect = el.getBoundingClientRect();
119
+ return JSON.stringify({
120
+ tag: el.tagName,
121
+ id: el.id,
122
+ text: (el.textContent || '').substring(0, 50),
123
+ position: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
124
+ });
125
+ }, targetElementHandle);
126
+ const matchedId = await page.evaluate((el) => {
127
+ const rect = el.getBoundingClientRect();
128
+ return JSON.stringify({
129
+ tag: el.tagName,
130
+ id: el.id,
131
+ text: (el.textContent || '').substring(0, 50),
132
+ position: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
133
+ });
134
+ }, matchedElement);
135
+ return targetId === matchedId;
136
+ }
137
+ return true;
138
+ }
139
+ catch (error) {
140
+ // If selector is invalid or throws, it's not unique
141
+ return false;
142
+ }
143
+ }
144
+ //# sourceMappingURL=selectorUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectorUtils.js","sourceRoot":"","sources":["../../src/mimic/selectorUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Snapshot Storage Module
3
+ *
4
+ * Handles reading, writing, and managing test execution snapshots.
5
+ * Snapshots store successful test executions as JSON files for fast replay.
6
+ */
7
+ import type { Snapshot } from './types.js';
8
+ /**
9
+ * Generate a hash from test text to create a unique identifier
10
+ *
11
+ * @param testText - The test text (mimic template string)
12
+ * @returns SHA-256 hash of the test text (first 16 characters for readability)
13
+ */
14
+ export declare function hashTestText(testText: string): string;
15
+ /**
16
+ * Get the snapshot directory path for a test file
17
+ *
18
+ * @param testFilePath - Directory path of the test file
19
+ * @returns Path to the .mimic-snapshots directory
20
+ */
21
+ export declare function getSnapshotDir(testFilePath: string): string;
22
+ /**
23
+ * Get the snapshot file path for a specific test
24
+ *
25
+ * @param testFilePath - Directory path of the test file
26
+ * @param testHash - Hash identifier for the test
27
+ * @returns Full path to the snapshot JSON file
28
+ */
29
+ export declare function getSnapshotPath(testFilePath: string, testHash: string): string;
30
+ /**
31
+ * Read a snapshot from disk
32
+ *
33
+ * @param testFilePath - Directory path of the test file
34
+ * @param testHash - Hash identifier for the test
35
+ * @returns Snapshot object if found, null otherwise
36
+ */
37
+ export declare function getSnapshot(testFilePath: string, testHash: string): Promise<Snapshot | null>;
38
+ /**
39
+ * Save a snapshot to disk
40
+ *
41
+ * @param testFilePath - Directory path of the test file
42
+ * @param snapshot - Snapshot object to save
43
+ * @returns Promise that resolves when snapshot is saved
44
+ */
45
+ export declare function saveSnapshot(testFilePath: string, snapshot: Snapshot): Promise<void>;
46
+ /**
47
+ * Record a test failure timestamp
48
+ *
49
+ * Updates the snapshot's lastFailedAt timestamp if the snapshot exists.
50
+ *
51
+ * @param testFilePath - Directory path of the test file
52
+ * @param testHash - Hash identifier for the test
53
+ * @param failedStepIndex - Index of the step that failed (optional)
54
+ * @param failedStepText - Text of the step that failed (optional)
55
+ * @param error - Error message (optional)
56
+ * @returns Promise that resolves when failure is recorded
57
+ */
58
+ export declare function recordFailure(testFilePath: string, testHash: string, failedStepIndex?: number, failedStepText?: string, error?: string): Promise<void>;
59
+ /**
60
+ * Determine if a snapshot should be used for replay
61
+ *
62
+ * A snapshot should be used if:
63
+ * - It exists
64
+ * - lastPassedAt is more recent than lastFailedAt (or lastFailedAt is null)
65
+ *
66
+ * Note: Even in troubleshoot mode, we use snapshots if they've passed.
67
+ * Regeneration only happens if replay fails.
68
+ *
69
+ * @param testFilePath - Directory path of the test file
70
+ * @param testHash - Hash identifier for the test
71
+ * @param troubleshootMode - Whether troubleshoot mode is enabled (unused, kept for compatibility)
72
+ * @returns true if snapshot should be used, false otherwise
73
+ */
74
+ export declare function shouldUseSnapshot(testFilePath: string, testHash: string, _troubleshootMode?: boolean, expectedStepCount?: number): Promise<boolean>;
75
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/mimic/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIrD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG9E;AAoBD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAoB1B;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,MAAM,EACxB,cAAc,CAAC,EAAE,MAAM,EACvB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe,EAClC,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,OAAO,CAAC,CAwClB"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Snapshot Storage Module
3
+ *
4
+ * Handles reading, writing, and managing test execution snapshots.
5
+ * Snapshots store successful test executions as JSON files for fast replay.
6
+ */
7
+ import { createHash } from 'crypto';
8
+ import fs from 'node:fs/promises';
9
+ import { join } from 'node:path';
10
+ /**
11
+ * Generate a hash from test text to create a unique identifier
12
+ *
13
+ * @param testText - The test text (mimic template string)
14
+ * @returns SHA-256 hash of the test text (first 16 characters for readability)
15
+ */
16
+ export function hashTestText(testText) {
17
+ const hash = createHash('sha256');
18
+ hash.update(testText.trim());
19
+ return hash.digest('hex').substring(0, 16);
20
+ }
21
+ /**
22
+ * Get the snapshot directory path for a test file
23
+ *
24
+ * @param testFilePath - Directory path of the test file
25
+ * @returns Path to the .mimic-snapshots directory
26
+ */
27
+ export function getSnapshotDir(testFilePath) {
28
+ return join(testFilePath, '.mimic-snapshots');
29
+ }
30
+ /**
31
+ * Get the snapshot file path for a specific test
32
+ *
33
+ * @param testFilePath - Directory path of the test file
34
+ * @param testHash - Hash identifier for the test
35
+ * @returns Full path to the snapshot JSON file
36
+ */
37
+ export function getSnapshotPath(testFilePath, testHash) {
38
+ const snapshotDir = getSnapshotDir(testFilePath);
39
+ return join(snapshotDir, `${testHash}.json`);
40
+ }
41
+ /**
42
+ * Ensure the snapshot directory exists
43
+ *
44
+ * @param testFilePath - Directory path of the test file
45
+ * @returns Promise that resolves when directory is created or already exists
46
+ */
47
+ async function ensureSnapshotDir(testFilePath) {
48
+ const snapshotDir = getSnapshotDir(testFilePath);
49
+ try {
50
+ await fs.mkdir(snapshotDir, { recursive: true });
51
+ }
52
+ catch (error) {
53
+ // Directory might already exist, which is fine
54
+ if (error instanceof Error && !error.message.includes('EEXIST')) {
55
+ throw error;
56
+ }
57
+ }
58
+ }
59
+ /**
60
+ * Read a snapshot from disk
61
+ *
62
+ * @param testFilePath - Directory path of the test file
63
+ * @param testHash - Hash identifier for the test
64
+ * @returns Snapshot object if found, null otherwise
65
+ */
66
+ export async function getSnapshot(testFilePath, testHash) {
67
+ if (!testFilePath) {
68
+ return null;
69
+ }
70
+ const snapshotPath = getSnapshotPath(testFilePath, testHash);
71
+ try {
72
+ const content = await fs.readFile(snapshotPath, 'utf-8');
73
+ const snapshot = JSON.parse(content);
74
+ return snapshot;
75
+ }
76
+ catch (error) {
77
+ // File doesn't exist or is invalid - return null
78
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
79
+ return null;
80
+ }
81
+ // For other errors (parse errors, etc.), log and return null
82
+ console.warn(`Failed to read snapshot at ${snapshotPath}:`, error);
83
+ return null;
84
+ }
85
+ }
86
+ /**
87
+ * Save a snapshot to disk
88
+ *
89
+ * @param testFilePath - Directory path of the test file
90
+ * @param snapshot - Snapshot object to save
91
+ * @returns Promise that resolves when snapshot is saved
92
+ */
93
+ export async function saveSnapshot(testFilePath, snapshot) {
94
+ if (!testFilePath) {
95
+ return;
96
+ }
97
+ await ensureSnapshotDir(testFilePath);
98
+ const snapshotPath = getSnapshotPath(testFilePath, snapshot.testHash);
99
+ // Update timestamps
100
+ const now = new Date().toISOString();
101
+ snapshot.lastPassedAt = now;
102
+ if (!snapshot.createdAt) {
103
+ snapshot.createdAt = now;
104
+ }
105
+ await fs.writeFile(snapshotPath, JSON.stringify(snapshot, null, 2), 'utf-8');
106
+ }
107
+ /**
108
+ * Record a test failure timestamp
109
+ *
110
+ * Updates the snapshot's lastFailedAt timestamp if the snapshot exists.
111
+ *
112
+ * @param testFilePath - Directory path of the test file
113
+ * @param testHash - Hash identifier for the test
114
+ * @param failedStepIndex - Index of the step that failed (optional)
115
+ * @param failedStepText - Text of the step that failed (optional)
116
+ * @param error - Error message (optional)
117
+ * @returns Promise that resolves when failure is recorded
118
+ */
119
+ export async function recordFailure(testFilePath, testHash, failedStepIndex, failedStepText, error) {
120
+ if (!testFilePath) {
121
+ return;
122
+ }
123
+ const snapshot = await getSnapshot(testFilePath, testHash);
124
+ if (!snapshot) {
125
+ // Create a minimal snapshot just for failure tracking
126
+ const failureSnapshot = {
127
+ testHash,
128
+ testText: '',
129
+ createdAt: new Date().toISOString(),
130
+ lastPassedAt: null,
131
+ lastFailedAt: new Date().toISOString(),
132
+ steps: [],
133
+ };
134
+ await saveSnapshot(testFilePath, failureSnapshot);
135
+ return;
136
+ }
137
+ // Update existing snapshot with failure info
138
+ snapshot.lastFailedAt = new Date().toISOString();
139
+ // Store failure details if provided
140
+ if (failedStepIndex !== undefined || failedStepText || error) {
141
+ snapshot.failureDetails = {
142
+ failedStepIndex,
143
+ failedStepText,
144
+ error,
145
+ };
146
+ }
147
+ await saveSnapshot(testFilePath, snapshot);
148
+ }
149
+ /**
150
+ * Determine if a snapshot should be used for replay
151
+ *
152
+ * A snapshot should be used if:
153
+ * - It exists
154
+ * - lastPassedAt is more recent than lastFailedAt (or lastFailedAt is null)
155
+ *
156
+ * Note: Even in troubleshoot mode, we use snapshots if they've passed.
157
+ * Regeneration only happens if replay fails.
158
+ *
159
+ * @param testFilePath - Directory path of the test file
160
+ * @param testHash - Hash identifier for the test
161
+ * @param troubleshootMode - Whether troubleshoot mode is enabled (unused, kept for compatibility)
162
+ * @returns true if snapshot should be used, false otherwise
163
+ */
164
+ export async function shouldUseSnapshot(testFilePath, testHash, _troubleshootMode = false, expectedStepCount) {
165
+ // Use snapshots even in troubleshoot mode if they've passed
166
+ // Regeneration will happen only if replay fails
167
+ if (!testFilePath) {
168
+ return false;
169
+ }
170
+ const snapshot = await getSnapshot(testFilePath, testHash);
171
+ if (!snapshot) {
172
+ return false;
173
+ }
174
+ // Validate that snapshot has at least as many steps as expected input lines
175
+ if (expectedStepCount !== undefined) {
176
+ // Count unique steps in snapshot (by stepIndex)
177
+ const uniqueStepIndices = new Set(snapshot.steps.map((step) => step.stepIndex));
178
+ const snapshotStepCount = uniqueStepIndices.size;
179
+ if (snapshotStepCount < expectedStepCount) {
180
+ // Snapshot is incomplete - don't use it
181
+ return false;
182
+ }
183
+ }
184
+ // If never passed, don't use snapshot
185
+ if (!snapshot.lastPassedAt) {
186
+ return false;
187
+ }
188
+ // If never failed, use snapshot
189
+ if (!snapshot.lastFailedAt) {
190
+ return true;
191
+ }
192
+ // Compare timestamps: use snapshot if pass is more recent than failure
193
+ const passTime = new Date(snapshot.lastPassedAt).getTime();
194
+ const failTime = new Date(snapshot.lastFailedAt).getTime();
195
+ return passTime > failTime;
196
+ }
197
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/mimic/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Snapshot-related Type Definitions
3
+ *
4
+ * Types for storing and replaying test execution snapshots.
5
+ */
6
+ import type { NavigationAction } from './schema/action.js';
7
+ import type { ClickActionResult } from './schema/action.js';
8
+ import type { FormActionResult } from './forms.js';
9
+ import type { TargetInfo } from './selector.js';
10
+ /**
11
+ * A single step in a test execution snapshot
12
+ */
13
+ export interface SnapshotStep {
14
+ /** Index of the step in the test (0-based) */
15
+ stepIndex: number;
16
+ /** Original step text (Gherkin step) */
17
+ stepText: string;
18
+ /** Type of action (navigation, click, form update) */
19
+ actionKind: 'navigation' | 'click' | 'form update';
20
+ /** Full action details (varies by actionKind) */
21
+ actionDetails: NavigationAction | ClickActionResult | FormActionResult;
22
+ /** Target element information (for click and form actions) */
23
+ targetElement?: TargetInfo & {
24
+ selector?: string;
25
+ };
26
+ /** Timestamp when this step was executed */
27
+ executedAt: string;
28
+ }
29
+ /**
30
+ * Complete snapshot of a test execution
31
+ */
32
+ export interface Snapshot {
33
+ /** Hash identifier for this test */
34
+ testHash: string;
35
+ /** Original test text (mimic template string) */
36
+ testText: string;
37
+ /** When this snapshot was first created */
38
+ createdAt: string;
39
+ /** When the test last passed (ISO timestamp) */
40
+ lastPassedAt: string | null;
41
+ /** When the test last failed (ISO timestamp, null if never failed) */
42
+ lastFailedAt: string | null;
43
+ /** Array of executed steps */
44
+ steps: SnapshotStep[];
45
+ }
46
+ /**
47
+ * Result of executing a single step (for snapshot creation)
48
+ */
49
+ export interface StepExecutionResult {
50
+ /** Index of the step in the test (0-based) */
51
+ stepIndex: number;
52
+ /** Original step text (Gherkin step) */
53
+ stepText: string;
54
+ /** Type of action (navigation, click, form update) */
55
+ actionKind: 'navigation' | 'click' | 'form update';
56
+ /** Full action details (varies by actionKind) */
57
+ actionDetails: NavigationAction | ClickActionResult | FormActionResult;
58
+ /** Target element information (for click and form actions) */
59
+ targetElement?: TargetInfo & {
60
+ selector?: string;
61
+ };
62
+ }
63
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mimic/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,UAAU,EAAE,YAAY,GAAG,OAAO,GAAG,aAAa,CAAC;IACnD,iDAAiD;IACjD,aAAa,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IACvE,8DAA8D;IAC9D,aAAa,CAAC,EAAE,UAAU,GAAG;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,sEAAsE;IACtE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,8BAA8B;IAC9B,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,UAAU,EAAE,YAAY,GAAG,OAAO,GAAG,aAAa,CAAC;IACnD,iDAAiD;IACjD,aAAa,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IACvE,8DAA8D;IAC9D,aAAa,CAAC,EAAE,UAAU,GAAG;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Snapshot-related Type Definitions
3
+ *
4
+ * Types for storing and replaying test execution snapshots.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/mimic/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
package/dist/mimic.d.ts CHANGED
@@ -4,23 +4,47 @@
4
4
  import { Page, TestInfo } from '@playwright/test';
5
5
  import type { LanguageModel } from 'ai';
6
6
  export type Mimic = (steps: TemplateStringsArray, ...args: unknown[]) => Promise<void>;
7
+ /**
8
+ * Test context that tracks previous state and actions for better decision-making
9
+ */
10
+ export interface TestContext {
11
+ /** Previous steps that have been executed */
12
+ previousSteps: Array<{
13
+ stepIndex: number;
14
+ stepText: string;
15
+ actionKind: string;
16
+ url?: string;
17
+ pageTitle?: string;
18
+ }>;
19
+ /** Current page state */
20
+ currentState: {
21
+ url: string;
22
+ pageTitle: string;
23
+ };
24
+ /** Total number of steps in the test */
25
+ totalSteps: number;
26
+ /** Current step index */
27
+ currentStepIndex: number;
28
+ }
7
29
  /**
8
30
  * Minimal flow function that takes a Playwright page and input string
9
31
  *
10
32
  * @param page - Playwright Page object
11
33
  * @param input - Input string to process
34
+ * @param testFilePath - Directory path of the test file (for snapshot storage)
35
+ * @param troubleshootMode - Whether troubleshoot mode is enabled
12
36
  * @returns Flow execution result with validated context
13
37
  */
14
- export declare function mimic(input: string, { page, brains, testInfo }: {
38
+ export declare function mimic(input: string, { page, brains, testInfo, testFilePath, troubleshootMode }: {
15
39
  page: Page;
16
40
  brains: LanguageModel;
17
- eyes: LanguageModel;
18
- testInfo?: TestInfo;
41
+ testInfo: TestInfo | undefined;
42
+ testFilePath?: string;
43
+ troubleshootMode?: boolean;
19
44
  }): Promise<void>;
20
45
  export declare const createMimic: (config: {
21
46
  page: Page;
22
47
  brains: LanguageModel;
23
- eyes: LanguageModel;
24
48
  testInfo?: TestInfo;
25
49
  }) => (prompt: TemplateStringsArray, ...args: unknown[]) => Promise<void>;
26
50
  //# sourceMappingURL=mimic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mimic.d.ts","sourceRoot":"","sources":["../src/mimic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAQ,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAQxC,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAGvF;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IACrE,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,iBAwCA;AAeD,eAAO,MAAM,WAAW,GAAI,QAAQ;IAClC,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,MACe,QAAQ,oBAAoB,EAAE,GAAG,MAAM,OAAO,EAAE,kBAI/D,CAAA"}
1
+ {"version":3,"file":"mimic.d.ts","sourceRoot":"","sources":["../src/mimic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAQ,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAiBxC,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,aAAa,EAAE,KAAK,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,yBAAyB;IACzB,YAAY,EAAE;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAoHD;;;;;;;;GAQG;AACH,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,EAAE;IACrG,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,iBAsUA;AAeD,eAAO,MAAM,WAAW,GAAI,QAAQ;IAClC,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,MASe,QAAQ,oBAAoB,EAAE,GAAG,MAAM,OAAO,EAAE,kBAU/D,CAAA"}