@sudobility/testomniac_runner_service 0.1.65 → 0.1.67
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/analyzer/page-analyzer/generators/content.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/content.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/content.js +10 -8
- package/dist/analyzer/page-analyzer/generators/content.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/dialogs.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/dialogs.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/dialogs.js +6 -6
- package/dist/analyzer/page-analyzer/generators/dialogs.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/e2e.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/e2e.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/e2e.js +5 -5
- package/dist/analyzer/page-analyzer/generators/e2e.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/forms.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/forms.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/forms.js +21 -21
- package/dist/analyzer/page-analyzer/generators/forms.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/hover-follow-up.d.ts +2 -2
- package/dist/analyzer/page-analyzer/generators/hover-follow-up.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/hover-follow-up.js +21 -21
- package/dist/analyzer/page-analyzer/generators/hover-follow-up.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/keyboard-disclosure.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/keyboard-disclosure.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/keyboard-disclosure.js +5 -5
- package/dist/analyzer/page-analyzer/generators/keyboard-disclosure.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/navigation.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/navigation.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/navigation.js +4 -31
- package/dist/analyzer/page-analyzer/generators/navigation.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/render.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/render.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/render.js +6 -6
- package/dist/analyzer/page-analyzer/generators/render.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/scaffolds.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/scaffolds.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/scaffolds.js +11 -8
- package/dist/analyzer/page-analyzer/generators/scaffolds.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/semantic-journeys.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/semantic-journeys.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/semantic-journeys.js +5 -5
- package/dist/analyzer/page-analyzer/generators/semantic-journeys.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/variants.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/variants.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/variants.js +5 -5
- package/dist/analyzer/page-analyzer/generators/variants.js.map +1 -1
- package/dist/analyzer/page-analyzer/index.d.ts +28 -28
- package/dist/analyzer/page-analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/index.js +174 -98
- package/dist/analyzer/page-analyzer/index.js.map +1 -1
- package/dist/analyzer/page-analyzer/types.d.ts +1 -1
- package/dist/analyzer/page-analyzer/types.d.ts.map +1 -1
- package/dist/api/client.d.ts +11 -11
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +27 -22
- package/dist/api/client.js.map +1 -1
- package/dist/detectors/action-description.d.ts +1 -1
- package/dist/detectors/action-description.d.ts.map +1 -1
- package/dist/detectors/action-description.js +1 -1
- package/dist/detectors/action-description.js.map +1 -1
- package/dist/detectors/index.d.ts +1 -1
- package/dist/detectors/index.d.ts.map +1 -1
- package/dist/detectors/index.js +1 -1
- package/dist/detectors/index.js.map +1 -1
- package/dist/domain/types.d.ts +1 -1
- package/dist/domain/types.d.ts.map +1 -1
- package/dist/generation/e2e.d.ts +2 -2
- package/dist/generation/e2e.d.ts.map +1 -1
- package/dist/generation/e2e.js +1 -1
- package/dist/generation/e2e.js.map +1 -1
- package/dist/generation/form-negative.d.ts +2 -2
- package/dist/generation/form-negative.d.ts.map +1 -1
- package/dist/generation/form-negative.js +1 -1
- package/dist/generation/form-negative.js.map +1 -1
- package/dist/generation/form.d.ts +2 -2
- package/dist/generation/form.d.ts.map +1 -1
- package/dist/generation/form.js +1 -1
- package/dist/generation/form.js.map +1 -1
- package/dist/generation/generator.d.ts +2 -2
- package/dist/generation/generator.d.ts.map +1 -1
- package/dist/generation/generator.js +1 -1
- package/dist/generation/generator.js.map +1 -1
- package/dist/generation/interaction.d.ts +2 -2
- package/dist/generation/interaction.d.ts.map +1 -1
- package/dist/generation/interaction.js +1 -1
- package/dist/generation/interaction.js.map +1 -1
- package/dist/generation/navigation.d.ts +2 -2
- package/dist/generation/navigation.d.ts.map +1 -1
- package/dist/generation/navigation.js +1 -1
- package/dist/generation/navigation.js.map +1 -1
- package/dist/generation/password.d.ts +4 -4
- package/dist/generation/password.d.ts.map +1 -1
- package/dist/generation/password.js +1 -1
- package/dist/generation/password.js.map +1 -1
- package/dist/generation/playwright-export.d.ts +2 -2
- package/dist/generation/playwright-export.d.ts.map +1 -1
- package/dist/generation/playwright-export.js +3 -3
- package/dist/generation/playwright-export.js.map +1 -1
- package/dist/generation/render.d.ts +7 -7
- package/dist/generation/render.d.ts.map +1 -1
- package/dist/generation/render.js +1 -1
- package/dist/generation/render.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/runner.d.ts +2 -0
- package/dist/orchestrator/runner.d.ts.map +1 -1
- package/dist/orchestrator/runner.js +195 -51
- package/dist/orchestrator/runner.js.map +1 -1
- package/dist/orchestrator/{test-element-executor.d.ts → test-interaction-executor.d.ts} +3 -3
- package/dist/orchestrator/test-interaction-executor.d.ts.map +1 -0
- package/dist/orchestrator/{test-element-executor.js → test-interaction-executor.js} +162 -52
- package/dist/orchestrator/test-interaction-executor.js.map +1 -0
- package/dist/orchestrator/types.d.ts +3 -3
- package/dist/orchestrator/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/orchestrator/test-element-executor.d.ts.map +0 -1
- package/dist/orchestrator/test-element-executor.js.map +0 -1
|
@@ -4,16 +4,19 @@ import { createHash } from "node:crypto";
|
|
|
4
4
|
import { fillValuePlanner } from "../../planners/fill-value-planner";
|
|
5
5
|
import { AUTH_URL_PATTERNS, SIGNUP_URL_PATTERNS } from "../../config/constants";
|
|
6
6
|
import { generateHoverFollowUpCases } from "./generators/hover-follow-up";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
7
|
+
import { generateNavigationTestInteractions } from "./generators/navigation";
|
|
8
|
+
import { generateScaffoldTestInteractions } from "./generators/scaffolds";
|
|
9
|
+
import { generateRenderTestInteractions } from "./generators/render";
|
|
10
|
+
import { generateFormTestInteractions } from "./generators/forms";
|
|
11
|
+
import { generateE2ETestInteractions } from "./generators/e2e";
|
|
12
|
+
import { generateSemanticJourneyTestInteractions } from "./generators/semantic-journeys";
|
|
13
|
+
import { generateDialogLifecycleTestInteractions } from "./generators/dialogs";
|
|
14
|
+
import { generateKeyboardAndDisclosureTestInteractions } from "./generators/keyboard-disclosure";
|
|
15
|
+
import { generateVariantTestInteractions } from "./generators/variants";
|
|
16
|
+
import { generateContentTestInteractions } from "./generators/content";
|
|
17
|
+
function logAnalyzer(step, details) {
|
|
18
|
+
console.info("[PageAnalyzer]", step, details ?? {});
|
|
19
|
+
}
|
|
17
20
|
/**
|
|
18
21
|
* PageAnalyzer generates expectations and discovers new test elements
|
|
19
22
|
* during discovery mode.
|
|
@@ -23,8 +26,10 @@ export class PageAnalyzer {
|
|
|
23
26
|
* Generate baseline expectations for a test element.
|
|
24
27
|
* Called BEFORE expertises evaluate.
|
|
25
28
|
*/
|
|
26
|
-
generateExpectations(
|
|
27
|
-
const steps = Array.isArray(
|
|
29
|
+
generateExpectations(testInteraction) {
|
|
30
|
+
const steps = Array.isArray(testInteraction.steps)
|
|
31
|
+
? testInteraction.steps
|
|
32
|
+
: [];
|
|
28
33
|
const expectations = [
|
|
29
34
|
{
|
|
30
35
|
expectationType: ExpectationType.PageLoaded,
|
|
@@ -56,55 +61,110 @@ export class PageAnalyzer {
|
|
|
56
61
|
* Generate new test elements for scaffolds and page content.
|
|
57
62
|
* Called AFTER expertises evaluate and the target page state is established.
|
|
58
63
|
*/
|
|
59
|
-
async
|
|
64
|
+
async generateTestInteractions(testInteraction, context) {
|
|
65
|
+
logAnalyzer("generate:start", {
|
|
66
|
+
sourceTitle: testInteraction.title,
|
|
67
|
+
sourceType: testInteraction.type,
|
|
68
|
+
sourcePriority: testInteraction.priority,
|
|
69
|
+
sourceSurfaceTags: testInteraction.surface_tags,
|
|
70
|
+
currentTestInteractionId: context.currentTestInteractionId,
|
|
71
|
+
currentTestSurfaceId: context.currentTestSurfaceId,
|
|
72
|
+
currentSurfaceRunId: context.currentSurfaceRunId ?? null,
|
|
73
|
+
beginningPageStateId: context.beginningPageStateId,
|
|
74
|
+
currentPageStateId: context.currentPageStateId,
|
|
75
|
+
currentPath: context.currentPath,
|
|
76
|
+
actionableItemsCount: context.actionableItems.length,
|
|
77
|
+
formsCount: context.forms.length,
|
|
78
|
+
scaffoldsCount: context.scaffolds.length,
|
|
79
|
+
});
|
|
60
80
|
const normalizedContext = this.normalizeContext(context);
|
|
61
81
|
const currentPageStateId = await this.ensureTargetPageState(normalizedContext);
|
|
62
82
|
const resolvedContext = {
|
|
63
83
|
...normalizedContext,
|
|
64
84
|
currentPageStateId,
|
|
65
85
|
};
|
|
66
|
-
|
|
67
|
-
|
|
86
|
+
logAnalyzer("generate:resolved-context", {
|
|
87
|
+
sourceTitle: testInteraction.title,
|
|
88
|
+
sourceType: testInteraction.type,
|
|
89
|
+
currentTestInteractionId: resolvedContext.currentTestInteractionId,
|
|
90
|
+
currentTestSurfaceId: resolvedContext.currentTestSurfaceId,
|
|
91
|
+
currentSurfaceRunId: resolvedContext.currentSurfaceRunId ?? null,
|
|
92
|
+
beginningPageStateId: resolvedContext.beginningPageStateId,
|
|
93
|
+
currentPageStateId: resolvedContext.currentPageStateId,
|
|
94
|
+
currentPath: resolvedContext.currentPath,
|
|
95
|
+
});
|
|
96
|
+
if (this.isHoverOnly(testInteraction)) {
|
|
97
|
+
logAnalyzer("generate:hover-only", {
|
|
98
|
+
sourceTitle: testInteraction.title,
|
|
99
|
+
currentTestInteractionId: resolvedContext.currentTestInteractionId,
|
|
100
|
+
currentPageStateId: resolvedContext.currentPageStateId,
|
|
101
|
+
});
|
|
102
|
+
await generateHoverFollowUpCases(this, testInteraction, resolvedContext);
|
|
68
103
|
return;
|
|
69
104
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
await
|
|
76
|
-
await
|
|
77
|
-
await
|
|
78
|
-
await
|
|
79
|
-
await
|
|
105
|
+
logAnalyzer("generate:full-pass", {
|
|
106
|
+
sourceTitle: testInteraction.title,
|
|
107
|
+
currentTestInteractionId: resolvedContext.currentTestInteractionId,
|
|
108
|
+
currentPageStateId: resolvedContext.currentPageStateId,
|
|
109
|
+
});
|
|
110
|
+
await generateRenderTestInteractions(this, resolvedContext);
|
|
111
|
+
await generateFormTestInteractions(this, resolvedContext);
|
|
112
|
+
await generateSemanticJourneyTestInteractions(this, resolvedContext);
|
|
113
|
+
await generateE2ETestInteractions(this, resolvedContext);
|
|
114
|
+
await generateDialogLifecycleTestInteractions(this, resolvedContext);
|
|
115
|
+
await generateScaffoldTestInteractions(this, resolvedContext);
|
|
116
|
+
await generateContentTestInteractions(this, resolvedContext);
|
|
117
|
+
await generateKeyboardAndDisclosureTestInteractions(this, resolvedContext);
|
|
118
|
+
await generateVariantTestInteractions(this, resolvedContext);
|
|
119
|
+
await generateNavigationTestInteractions(this, resolvedContext);
|
|
80
120
|
}
|
|
81
121
|
async reconcileGeneratedSurfaceElements(context, params) {
|
|
82
122
|
const surface = params.surfaceId != null
|
|
83
123
|
? { id: params.surfaceId, title: params.surfaceTitle }
|
|
84
124
|
: await this.findExistingSurfaceByTitle(context, params.surfaceTitle);
|
|
85
|
-
if (!surface)
|
|
125
|
+
if (!surface) {
|
|
126
|
+
logAnalyzer("reconcile:surface-missing", {
|
|
127
|
+
requestedSurfaceId: params.surfaceId ?? null,
|
|
128
|
+
requestedSurfaceTitle: params.surfaceTitle,
|
|
129
|
+
dependencyTestInteractionId: params.dependencyTestInteractionId ?? null,
|
|
130
|
+
desiredKeysCount: params.desiredKeys.length,
|
|
131
|
+
});
|
|
86
132
|
return;
|
|
87
|
-
|
|
133
|
+
}
|
|
134
|
+
const existing = await context.api.getTestInteractionsByTestSurface(surface.id, true);
|
|
88
135
|
const desiredKeys = new Set(params.desiredKeys.map(key => key.trim()).filter(Boolean));
|
|
89
136
|
const obsoleteIds = existing
|
|
90
|
-
.filter(
|
|
91
|
-
const isGenerated = Boolean(
|
|
92
|
-
const isActive =
|
|
137
|
+
.filter(testInteraction => {
|
|
138
|
+
const isGenerated = Boolean(testInteraction.isGenerated);
|
|
139
|
+
const isActive = testInteraction.isActive !== false;
|
|
93
140
|
if (!isGenerated || !isActive)
|
|
94
141
|
return false;
|
|
95
|
-
if (
|
|
142
|
+
if (testInteraction.startingPageStateId !== context.currentPageStateId)
|
|
96
143
|
return false;
|
|
97
|
-
if ((
|
|
98
|
-
(params.
|
|
144
|
+
if ((testInteraction.dependencyTestInteractionId ?? null) !==
|
|
145
|
+
(params.dependencyTestInteractionId ?? null)) {
|
|
99
146
|
return false;
|
|
100
147
|
}
|
|
101
|
-
const existingKey = this.getPersistedGeneratedKey(
|
|
148
|
+
const existingKey = this.getPersistedGeneratedKey(testInteraction);
|
|
102
149
|
return !existingKey || !desiredKeys.has(existingKey);
|
|
103
150
|
})
|
|
104
|
-
.map(
|
|
151
|
+
.map(testInteraction => testInteraction.id);
|
|
152
|
+
logAnalyzer("reconcile:evaluated", {
|
|
153
|
+
surfaceId: surface.id,
|
|
154
|
+
surfaceTitle: surface.title,
|
|
155
|
+
dependencyTestInteractionId: params.dependencyTestInteractionId ?? null,
|
|
156
|
+
desiredKeysCount: desiredKeys.size,
|
|
157
|
+
existingCount: existing.length,
|
|
158
|
+
obsoleteIds,
|
|
159
|
+
});
|
|
105
160
|
if (obsoleteIds.length === 0)
|
|
106
161
|
return;
|
|
107
|
-
await context.api.
|
|
162
|
+
await context.api.retireTestInteractions(obsoleteIds);
|
|
163
|
+
logAnalyzer("reconcile:retired", {
|
|
164
|
+
surfaceId: surface.id,
|
|
165
|
+
surfaceTitle: surface.title,
|
|
166
|
+
obsoleteIds,
|
|
167
|
+
});
|
|
108
168
|
}
|
|
109
169
|
async findExistingSurfaceByTitle(context, title) {
|
|
110
170
|
const surfaces = await context.api.getTestSurfacesByRunner(context.runnerId);
|
|
@@ -123,12 +183,23 @@ export class PageAnalyzer {
|
|
|
123
183
|
const openSurfaceRuns = await api.getOpenTestSurfaceRuns(bundleRunId);
|
|
124
184
|
const existing = openSurfaceRuns.find(surfaceRun => surfaceRun.testSurfaceId === testSurfaceId);
|
|
125
185
|
if (existing) {
|
|
186
|
+
logAnalyzer("surface-run:reused", {
|
|
187
|
+
bundleRunId,
|
|
188
|
+
testSurfaceId,
|
|
189
|
+
surfaceRunId: existing.id,
|
|
190
|
+
});
|
|
126
191
|
return existing;
|
|
127
192
|
}
|
|
128
|
-
|
|
193
|
+
const created = await api.createTestSurfaceRun({
|
|
129
194
|
testSurfaceId,
|
|
130
195
|
testSurfaceBundleRunId: bundleRunId,
|
|
131
196
|
});
|
|
197
|
+
logAnalyzer("surface-run:created", {
|
|
198
|
+
bundleRunId,
|
|
199
|
+
testSurfaceId,
|
|
200
|
+
surfaceRunId: created.id,
|
|
201
|
+
});
|
|
202
|
+
return created;
|
|
132
203
|
}
|
|
133
204
|
isMouseActionable(item) {
|
|
134
205
|
return (item.visible &&
|
|
@@ -149,7 +220,7 @@ export class PageAnalyzer {
|
|
|
149
220
|
return null;
|
|
150
221
|
}
|
|
151
222
|
}
|
|
152
|
-
|
|
223
|
+
buildNavigationTestInteraction(path, sizeClass, uid, startingPageStateId) {
|
|
153
224
|
return {
|
|
154
225
|
title: `Navigate to ${path}`,
|
|
155
226
|
type: "navigation",
|
|
@@ -176,15 +247,15 @@ export class PageAnalyzer {
|
|
|
176
247
|
generatedKey: this.buildGeneratedKey("navigation", startingPageStateId, path),
|
|
177
248
|
};
|
|
178
249
|
}
|
|
179
|
-
|
|
250
|
+
buildHoverTestInteraction(item, startingPath, sizeClass, uid, startingPageStateId, dependencyTestInteractionId) {
|
|
180
251
|
const label = this.describeActionableItem(item);
|
|
181
252
|
return {
|
|
182
253
|
title: `Hover over ${label}`,
|
|
183
254
|
type: "interaction",
|
|
184
255
|
sizeClass,
|
|
185
256
|
surface_tags: ["interaction", "hover"],
|
|
186
|
-
priority:
|
|
187
|
-
|
|
257
|
+
priority: 1,
|
|
258
|
+
dependencyTestInteractionId,
|
|
188
259
|
startingPageStateId,
|
|
189
260
|
startingPath,
|
|
190
261
|
steps: [
|
|
@@ -202,10 +273,10 @@ export class PageAnalyzer {
|
|
|
202
273
|
],
|
|
203
274
|
globalExpectations: [],
|
|
204
275
|
uid,
|
|
205
|
-
generatedKey: this.buildGeneratedKey("hover", startingPageStateId,
|
|
276
|
+
generatedKey: this.buildGeneratedKey("hover", startingPageStateId, dependencyTestInteractionId, item.stableKey ?? item.selector ?? label),
|
|
206
277
|
};
|
|
207
278
|
}
|
|
208
|
-
|
|
279
|
+
buildClickTestInteraction(item, startingPath, sizeClass, uid, startingPageStateId, dependencyTestInteractionId) {
|
|
209
280
|
const label = this.describeActionableItem(item);
|
|
210
281
|
return {
|
|
211
282
|
title: `Click ${label}`,
|
|
@@ -213,7 +284,7 @@ export class PageAnalyzer {
|
|
|
213
284
|
sizeClass,
|
|
214
285
|
surface_tags: ["interaction", "click"],
|
|
215
286
|
priority: 5,
|
|
216
|
-
|
|
287
|
+
dependencyTestInteractionId,
|
|
217
288
|
startingPageStateId,
|
|
218
289
|
startingPath,
|
|
219
290
|
steps: [
|
|
@@ -231,16 +302,20 @@ export class PageAnalyzer {
|
|
|
231
302
|
],
|
|
232
303
|
globalExpectations: [],
|
|
233
304
|
uid,
|
|
234
|
-
generatedKey: this.buildGeneratedKey("click", startingPageStateId,
|
|
305
|
+
generatedKey: this.buildGeneratedKey("click", startingPageStateId, dependencyTestInteractionId, item.stableKey ?? item.selector ?? label),
|
|
235
306
|
};
|
|
236
307
|
}
|
|
237
|
-
isHoverOnly(
|
|
238
|
-
const steps = Array.isArray(
|
|
308
|
+
isHoverOnly(testInteraction) {
|
|
309
|
+
const steps = Array.isArray(testInteraction.steps)
|
|
310
|
+
? testInteraction.steps
|
|
311
|
+
: [];
|
|
239
312
|
return (steps.length === 1 &&
|
|
240
313
|
steps[0]?.action?.actionType === PlaywrightAction.Hover);
|
|
241
314
|
}
|
|
242
|
-
getPrimarySelector(
|
|
243
|
-
const steps = Array.isArray(
|
|
315
|
+
getPrimarySelector(testInteraction) {
|
|
316
|
+
const steps = Array.isArray(testInteraction.steps)
|
|
317
|
+
? testInteraction.steps
|
|
318
|
+
: [];
|
|
244
319
|
const step = steps[0];
|
|
245
320
|
return step?.action.path ?? null;
|
|
246
321
|
}
|
|
@@ -249,20 +324,20 @@ export class PageAnalyzer {
|
|
|
249
324
|
const selector = item.selector;
|
|
250
325
|
return stableKey ?? selector ?? null;
|
|
251
326
|
}
|
|
252
|
-
withGeneratedKey(
|
|
327
|
+
withGeneratedKey(testInteraction, ...parts) {
|
|
253
328
|
return {
|
|
254
|
-
...
|
|
329
|
+
...testInteraction,
|
|
255
330
|
generatedKey: this.buildGeneratedKey(...parts),
|
|
256
331
|
};
|
|
257
332
|
}
|
|
258
|
-
getGeneratedKey(
|
|
259
|
-
return (
|
|
333
|
+
getGeneratedKey(testInteraction) {
|
|
334
|
+
return (testInteraction.generatedKey?.trim() || testInteraction.title).trim();
|
|
260
335
|
}
|
|
261
|
-
getPersistedGeneratedKey(
|
|
262
|
-
const generatedKey =
|
|
336
|
+
getPersistedGeneratedKey(testInteraction) {
|
|
337
|
+
const generatedKey = testInteraction.generatedKey?.trim();
|
|
263
338
|
if (generatedKey)
|
|
264
339
|
return generatedKey;
|
|
265
|
-
const title =
|
|
340
|
+
const title = testInteraction.title?.trim();
|
|
266
341
|
return title || null;
|
|
267
342
|
}
|
|
268
343
|
buildGeneratedKey(...parts) {
|
|
@@ -396,7 +471,7 @@ export class PageAnalyzer {
|
|
|
396
471
|
normalizeForms(forms) {
|
|
397
472
|
return Array.isArray(forms) ? forms : [];
|
|
398
473
|
}
|
|
399
|
-
|
|
474
|
+
buildRenderTestInteraction(currentPath, sizeClass, uid, startingPageStateId, pageId) {
|
|
400
475
|
return {
|
|
401
476
|
title: `Render — ${currentPath}`,
|
|
402
477
|
type: "render",
|
|
@@ -452,7 +527,7 @@ export class PageAnalyzer {
|
|
|
452
527
|
generatedKey: this.buildGeneratedKey("render", startingPageStateId, pageId, currentPath),
|
|
453
528
|
};
|
|
454
529
|
}
|
|
455
|
-
|
|
530
|
+
buildFormTestInteraction(form, formLabel, formType, currentPath, sizeClass, uid, startingPageStateId, validValues) {
|
|
456
531
|
const steps = this.buildFormSteps(form, validValues, undefined);
|
|
457
532
|
return {
|
|
458
533
|
title: `Form — ${formLabel}`,
|
|
@@ -497,7 +572,7 @@ export class PageAnalyzer {
|
|
|
497
572
|
generatedKey: this.buildGeneratedKey("form-positive", startingPageStateId, form.selector, formType),
|
|
498
573
|
};
|
|
499
574
|
}
|
|
500
|
-
|
|
575
|
+
buildNegativeFormTestInteraction(form, formLabel, formType, omittedField, currentPath, sizeClass, uid, startingPageStateId, validValues) {
|
|
501
576
|
const steps = this.buildFormSteps(form, validValues, omittedField.selector, this.buildValuePreservationExpectations(form, validValues, omittedField.selector));
|
|
502
577
|
return {
|
|
503
578
|
title: `Form Negative — ${formLabel} (missing ${this.fieldLabel(omittedField)})`,
|
|
@@ -520,7 +595,7 @@ export class PageAnalyzer {
|
|
|
520
595
|
generatedKey: this.buildGeneratedKey("form-negative", startingPageStateId, form.selector, formType, omittedField.selector),
|
|
521
596
|
};
|
|
522
597
|
}
|
|
523
|
-
|
|
598
|
+
buildFormCorrectionTestInteraction(form, formLabel, formType, correctedField, currentPath, sizeClass, uid, startingPageStateId, validValues) {
|
|
524
599
|
const steps = this.buildFormSteps(form, validValues, correctedField.selector, this.buildValuePreservationExpectations(form, validValues, correctedField.selector));
|
|
525
600
|
const correctionValue = validValues[correctedField.selector];
|
|
526
601
|
if (correctionValue) {
|
|
@@ -565,7 +640,7 @@ export class PageAnalyzer {
|
|
|
565
640
|
generatedKey: this.buildGeneratedKey("form-correction", startingPageStateId, form.selector, formType, correctedField.selector),
|
|
566
641
|
};
|
|
567
642
|
}
|
|
568
|
-
|
|
643
|
+
buildPasswordTestInteractions(form, formLabel, formType, currentPath, sizeClass, uid, startingPageStateId, validValues, passwordRequirements) {
|
|
569
644
|
const passwordFields = form.fields.filter(field => field.type === "password");
|
|
570
645
|
if (passwordFields.length === 0)
|
|
571
646
|
return [];
|
|
@@ -602,7 +677,7 @@ export class PageAnalyzer {
|
|
|
602
677
|
};
|
|
603
678
|
});
|
|
604
679
|
}
|
|
605
|
-
|
|
680
|
+
buildE2ETestInteraction(currentPath, sizeClass, uid, startingPageStateId, journeySteps) {
|
|
606
681
|
return {
|
|
607
682
|
title: `E2E — Journey to ${currentPath}`,
|
|
608
683
|
type: "e2e",
|
|
@@ -864,7 +939,7 @@ export class PageAnalyzer {
|
|
|
864
939
|
.toLowerCase();
|
|
865
940
|
return field.type === "search" || /\bsearch\b/.test(text);
|
|
866
941
|
}
|
|
867
|
-
|
|
942
|
+
buildSearchTestInteractions(form, formLabel, currentPath, sizeClass, uid, startingPageStateId, validValues, actionableItems) {
|
|
868
943
|
const searchField = form.fields.find(field => this.isSearchField(field));
|
|
869
944
|
if (!searchField)
|
|
870
945
|
return [];
|
|
@@ -998,7 +1073,7 @@ export class PageAnalyzer {
|
|
|
998
1073
|
const descriptor = namedField?.label || namedField?.name || `form ${index + 1}`;
|
|
999
1074
|
return `${descriptor} @ ${form.selector}`;
|
|
1000
1075
|
}
|
|
1001
|
-
|
|
1076
|
+
buildSemanticJourneyTestInteractions(context) {
|
|
1002
1077
|
const items = this.selectRepresentativeItems(context.actionableItems.filter(item => item.visible && !item.disabled && Boolean(item.selector)));
|
|
1003
1078
|
const journeys = [];
|
|
1004
1079
|
const collectionCount = this.estimateCollectionCount(context.html);
|
|
@@ -1006,7 +1081,7 @@ export class PageAnalyzer {
|
|
|
1006
1081
|
const checkout = items.find(item => this.isCheckoutItem(item));
|
|
1007
1082
|
const createCollectionAction = items.find(item => this.isCreateCollectionAction(item));
|
|
1008
1083
|
if (addToCart && checkout) {
|
|
1009
|
-
journeys.push(this.
|
|
1084
|
+
journeys.push(this.buildJourneyTestInteraction("Commerce journey", ["commerce", "cart", "checkout"], context, [
|
|
1010
1085
|
this.buildJourneyAction(addToCart, "Add item to cart", [
|
|
1011
1086
|
this.makeExpectation("navigation_or_state_changed", "Adding an item to cart should update the page state"),
|
|
1012
1087
|
this.makeExpectation("count_changed", "Adding an item should update a visible count", {
|
|
@@ -1076,7 +1151,7 @@ export class PageAnalyzer {
|
|
|
1076
1151
|
severity: ExpectationSeverity.ShouldPass,
|
|
1077
1152
|
}));
|
|
1078
1153
|
}
|
|
1079
|
-
journeys.push(this.
|
|
1154
|
+
journeys.push(this.buildJourneyTestInteraction("Remove item from collection", ["commerce", "remove"], context, [
|
|
1080
1155
|
this.buildJourneyAction(removeItem, "Remove item", removeExpectations),
|
|
1081
1156
|
]));
|
|
1082
1157
|
}
|
|
@@ -1096,13 +1171,13 @@ export class PageAnalyzer {
|
|
|
1096
1171
|
this.makeExpectation("loading_completes", "Create/add flow should complete loading"),
|
|
1097
1172
|
this.makeExpectation("page_responsive", "Page should remain responsive after creating or adding a record"),
|
|
1098
1173
|
];
|
|
1099
|
-
journeys.push(this.
|
|
1174
|
+
journeys.push(this.buildJourneyTestInteraction("Create or add collection record", ["list", "crud", "create"], context, [
|
|
1100
1175
|
this.buildJourneyAction(createCollectionAction, "Create or add record", createExpectations),
|
|
1101
1176
|
]));
|
|
1102
1177
|
}
|
|
1103
1178
|
const authEntry = items.find(item => this.isAuthEntryItem(item));
|
|
1104
1179
|
if (authEntry) {
|
|
1105
|
-
journeys.push(this.
|
|
1180
|
+
journeys.push(this.buildJourneyTestInteraction("Authentication entry journey", ["auth"], context, [
|
|
1106
1181
|
this.buildJourneyAction(authEntry, "Open authentication entry point", [
|
|
1107
1182
|
this.makeExpectation("navigation_or_state_changed", "Authentication entry should open the next auth state"),
|
|
1108
1183
|
this.makeExpectation("loading_completes", "Authentication entry flow should settle"),
|
|
@@ -1112,7 +1187,7 @@ export class PageAnalyzer {
|
|
|
1112
1187
|
}
|
|
1113
1188
|
const protectedAction = items.find(item => item !== authEntry && this.isProtectedActionItem(item));
|
|
1114
1189
|
if (authEntry && protectedAction) {
|
|
1115
|
-
journeys.push(this.
|
|
1190
|
+
journeys.push(this.buildJourneyTestInteraction("Protected action auth gate journey", ["auth", "protected"], context, [
|
|
1116
1191
|
this.buildJourneyAction(protectedAction, "Open protected action", [
|
|
1117
1192
|
this.makeExpectation(ExpectationType.NavigationOrStateChanged, "Protected action should open a gated state, redirect, or login requirement"),
|
|
1118
1193
|
this.makeExpectation(ExpectationType.PageResponsive, "Page should remain responsive when auth gating is triggered"),
|
|
@@ -1122,7 +1197,7 @@ export class PageAnalyzer {
|
|
|
1122
1197
|
}
|
|
1123
1198
|
const logoutAction = items.find(item => this.isLogoutAction(item));
|
|
1124
1199
|
if (logoutAction) {
|
|
1125
|
-
journeys.push(this.
|
|
1200
|
+
journeys.push(this.buildJourneyTestInteraction("Logout journey", ["auth", "logout"], context, [
|
|
1126
1201
|
this.buildJourneyAction(logoutAction, "Log out", [
|
|
1127
1202
|
this.makeExpectation(ExpectationType.NavigationOrStateChanged, "Logging out should change application state"),
|
|
1128
1203
|
this.makeExpectation(ExpectationType.PageResponsive, "Page should remain responsive during logout"),
|
|
@@ -1138,7 +1213,7 @@ export class PageAnalyzer {
|
|
|
1138
1213
|
}
|
|
1139
1214
|
const retryAction = items.find(item => this.isRetryAction(item));
|
|
1140
1215
|
if (retryAction) {
|
|
1141
|
-
journeys.push(this.
|
|
1216
|
+
journeys.push(this.buildJourneyTestInteraction("Retry recovery journey", ["recovery", "retry"], context, [
|
|
1142
1217
|
this.buildJourneyAction(retryAction, "Retry failed action", [
|
|
1143
1218
|
this.makeExpectation(ExpectationType.ErrorStateCleared, "Retrying should clear any visible recoverable error state"),
|
|
1144
1219
|
this.makeExpectation(ExpectationType.NetworkRequestMade, "Retrying should trigger a follow-up request or state transition", {
|
|
@@ -1164,7 +1239,7 @@ export class PageAnalyzer {
|
|
|
1164
1239
|
if (this.isVideoLikeItem(mediaCandidate)) {
|
|
1165
1240
|
mediaExpectations.push(this.makeExpectation("video_playable", "Opened video should be playable"));
|
|
1166
1241
|
}
|
|
1167
|
-
journeys.push(this.
|
|
1242
|
+
journeys.push(this.buildJourneyTestInteraction("Media open journey", ["media"], context, [
|
|
1168
1243
|
this.buildJourneyAction(mediaCandidate, "Open media", mediaExpectations),
|
|
1169
1244
|
]));
|
|
1170
1245
|
}
|
|
@@ -1185,7 +1260,7 @@ export class PageAnalyzer {
|
|
|
1185
1260
|
this.makeExpectation("loading_completes", "Quantity adjustment should complete loading"),
|
|
1186
1261
|
this.makeExpectation("page_responsive", "Page should remain responsive during quantity adjustment"),
|
|
1187
1262
|
].filter(Boolean);
|
|
1188
|
-
journeys.push(this.
|
|
1263
|
+
journeys.push(this.buildJourneyTestInteraction(quantityDelta === -1
|
|
1189
1264
|
? "Quantity decrease journey"
|
|
1190
1265
|
: quantityDelta === 1
|
|
1191
1266
|
? "Quantity increase journey"
|
|
@@ -1199,14 +1274,14 @@ export class PageAnalyzer {
|
|
|
1199
1274
|
}
|
|
1200
1275
|
const filterAction = items.find(item => this.isFilterAction(item));
|
|
1201
1276
|
if (filterAction) {
|
|
1202
|
-
journeys.push(this.
|
|
1277
|
+
journeys.push(this.buildJourneyTestInteraction("Filter results journey", ["filter"], context, [
|
|
1203
1278
|
this.buildJourneyAction(filterAction, "Apply filter", [
|
|
1204
1279
|
this.makeExpectation("navigation_or_state_changed", "Applying a filter should change the result state"),
|
|
1205
1280
|
this.makeExpectation("results_changed", "Applying a filter should change the visible result summary"),
|
|
1206
1281
|
this.makeExpectation("loading_completes", "Filter update should complete loading"),
|
|
1207
1282
|
]),
|
|
1208
1283
|
]));
|
|
1209
|
-
journeys.push(this.
|
|
1284
|
+
journeys.push(this.buildJourneyTestInteraction("Filter persistence journey", ["filter", "reload"], context, [
|
|
1210
1285
|
this.buildJourneyAction(filterAction, "Apply filter", [
|
|
1211
1286
|
this.makeExpectation("navigation_or_state_changed", "Applying a filter should change the result state"),
|
|
1212
1287
|
]),
|
|
@@ -1220,7 +1295,7 @@ export class PageAnalyzer {
|
|
|
1220
1295
|
}
|
|
1221
1296
|
const sortAction = items.find(item => this.isSortAction(item));
|
|
1222
1297
|
if (sortAction) {
|
|
1223
|
-
journeys.push(this.
|
|
1298
|
+
journeys.push(this.buildJourneyTestInteraction("Sort results journey", ["sort"], context, [
|
|
1224
1299
|
this.buildJourneyAction(sortAction, "Change sort order", [
|
|
1225
1300
|
this.makeExpectation("navigation_or_state_changed", "Changing sort should update the result state"),
|
|
1226
1301
|
this.makeExpectation("collection_order_changed", "Changing sort should change the visible collection ordering"),
|
|
@@ -1230,7 +1305,7 @@ export class PageAnalyzer {
|
|
|
1230
1305
|
}
|
|
1231
1306
|
const paginationAction = items.find(item => this.isPaginationAction(item));
|
|
1232
1307
|
if (paginationAction) {
|
|
1233
|
-
journeys.push(this.
|
|
1308
|
+
journeys.push(this.buildJourneyTestInteraction("Pagination journey", ["list", "pagination"], context, [
|
|
1234
1309
|
this.buildJourneyAction(paginationAction, "Paginate list", [
|
|
1235
1310
|
this.makeExpectation(ExpectationType.NavigationOrStateChanged, "Pagination should change the visible list state"),
|
|
1236
1311
|
this.makeExpectation("results_changed", "Pagination should change the visible collection contents"),
|
|
@@ -1241,7 +1316,7 @@ export class PageAnalyzer {
|
|
|
1241
1316
|
]));
|
|
1242
1317
|
}
|
|
1243
1318
|
if (addToCart) {
|
|
1244
|
-
journeys.push(this.
|
|
1319
|
+
journeys.push(this.buildJourneyTestInteraction("Cart persistence journey", ["commerce", "reload"], context, [
|
|
1245
1320
|
this.buildJourneyAction(addToCart, "Add item to cart", [
|
|
1246
1321
|
this.makeExpectation("navigation_or_state_changed", "Adding an item should change page state before reload"),
|
|
1247
1322
|
]),
|
|
@@ -1260,7 +1335,7 @@ export class PageAnalyzer {
|
|
|
1260
1335
|
]));
|
|
1261
1336
|
}
|
|
1262
1337
|
if (collectionCount > 0 && removeItem && createCollectionAction) {
|
|
1263
|
-
journeys.push(this.
|
|
1338
|
+
journeys.push(this.buildJourneyTestInteraction("Collection mutation recovery journey", ["list", "crud", "recovery"], context, [
|
|
1264
1339
|
this.buildJourneyAction(removeItem, "Remove record", [
|
|
1265
1340
|
this.makeExpectation("row_count_changed", "Removing a record should change the visible collection", {
|
|
1266
1341
|
expectedCountDelta: -1,
|
|
@@ -1281,7 +1356,7 @@ export class PageAnalyzer {
|
|
|
1281
1356
|
this.isMediaOpenItem(item) ||
|
|
1282
1357
|
this.isAuthEntryItem(item));
|
|
1283
1358
|
if (backCandidate) {
|
|
1284
|
-
journeys.push(this.
|
|
1359
|
+
journeys.push(this.buildJourneyTestInteraction("Back and forward navigation journey", ["navigation", "history"], context, [
|
|
1285
1360
|
this.buildJourneyAction(backCandidate, "Navigate to next state", [
|
|
1286
1361
|
this.makeExpectation("navigation_or_state_changed", "Navigation should move to a different state"),
|
|
1287
1362
|
]),
|
|
@@ -1297,7 +1372,7 @@ export class PageAnalyzer {
|
|
|
1297
1372
|
}
|
|
1298
1373
|
return journeys;
|
|
1299
1374
|
}
|
|
1300
|
-
|
|
1375
|
+
buildJourneyTestInteraction(title, surfaceTags, context, steps) {
|
|
1301
1376
|
return {
|
|
1302
1377
|
title: `${title} — ${context.currentPath}`,
|
|
1303
1378
|
type: "e2e",
|
|
@@ -1414,18 +1489,18 @@ export class PageAnalyzer {
|
|
|
1414
1489
|
isCheckboxLike(field) {
|
|
1415
1490
|
return field.type === "checkbox" || field.type === "radio";
|
|
1416
1491
|
}
|
|
1417
|
-
|
|
1492
|
+
buildKeyboardAndDisclosureTestInteractions(context) {
|
|
1418
1493
|
const items = this.selectRepresentativeItems(context.actionableItems.filter(item => item.visible && !item.disabled && Boolean(item.selector)));
|
|
1419
1494
|
const tests = [];
|
|
1420
1495
|
for (const item of items) {
|
|
1421
1496
|
if (this.isDisclosureItem(item)) {
|
|
1422
|
-
tests.push(this.
|
|
1423
|
-
tests.push(this.
|
|
1497
|
+
tests.push(this.buildDisclosureToggleTestInteraction(item, context.currentPath, context.sizeClass, context.uid, context.currentPageStateId));
|
|
1498
|
+
tests.push(this.buildKeyboardActivateTestInteraction(item, "Enter", "Activate disclosure with Enter", [
|
|
1424
1499
|
this.makeExpectation("expanded_state_changed", "Enter should toggle the disclosure state", {
|
|
1425
1500
|
targetPath: item.selector,
|
|
1426
1501
|
}),
|
|
1427
1502
|
], context.currentPath, context.sizeClass, context.uid, context.currentPageStateId));
|
|
1428
|
-
tests.push(this.
|
|
1503
|
+
tests.push(this.buildKeyboardActivateTestInteraction(item, " ", "Activate disclosure with Space", [
|
|
1429
1504
|
this.makeExpectation("expanded_state_changed", "Space should toggle the disclosure state", {
|
|
1430
1505
|
targetPath: item.selector,
|
|
1431
1506
|
}),
|
|
@@ -1433,12 +1508,12 @@ export class PageAnalyzer {
|
|
|
1433
1508
|
continue;
|
|
1434
1509
|
}
|
|
1435
1510
|
if (this.isKeyboardPrimaryAction(item)) {
|
|
1436
|
-
tests.push(this.
|
|
1511
|
+
tests.push(this.buildKeyboardActivateTestInteraction(item, "Enter", "Activate with Enter", [
|
|
1437
1512
|
this.makeExpectation("navigation_or_state_changed", "Enter key activation should change the page or control state"),
|
|
1438
1513
|
], context.currentPath, context.sizeClass, context.uid, context.currentPageStateId));
|
|
1439
1514
|
}
|
|
1440
1515
|
if (this.isKeyboardToggleAction(item)) {
|
|
1441
|
-
tests.push(this.
|
|
1516
|
+
tests.push(this.buildKeyboardActivateTestInteraction(item, " ", "Toggle with Space", [
|
|
1442
1517
|
this.makeExpectation(ExpectationType.ElementChecked, "Space key activation should toggle the control state", {
|
|
1443
1518
|
targetPath: item.selector,
|
|
1444
1519
|
}),
|
|
@@ -1447,13 +1522,13 @@ export class PageAnalyzer {
|
|
|
1447
1522
|
}
|
|
1448
1523
|
return tests;
|
|
1449
1524
|
}
|
|
1450
|
-
|
|
1525
|
+
buildVariantTestInteractions(context) {
|
|
1451
1526
|
const items = this.selectRepresentativeItems(context.actionableItems.filter(item => item.visible &&
|
|
1452
1527
|
!item.disabled &&
|
|
1453
1528
|
Boolean(item.selector) &&
|
|
1454
1529
|
this.isVariantSelector(item)));
|
|
1455
1530
|
const tests = items
|
|
1456
|
-
.map(item => this.
|
|
1531
|
+
.map(item => this.buildVariantTestInteraction(item, context))
|
|
1457
1532
|
.filter((item) => Boolean(item));
|
|
1458
1533
|
const purchaseAction = context.actionableItems.find(item => item.visible &&
|
|
1459
1534
|
!item.disabled &&
|
|
@@ -1465,12 +1540,12 @@ export class PageAnalyzer {
|
|
|
1465
1540
|
tests.push(purchaseJourney);
|
|
1466
1541
|
const requiredField = this.findRequiredVariantField(item, context.forms);
|
|
1467
1542
|
if (requiredField && purchaseAction) {
|
|
1468
|
-
tests.push(this.
|
|
1543
|
+
tests.push(this.buildRequiredVariantGuardTestInteraction(item, requiredField, purchaseAction, context));
|
|
1469
1544
|
}
|
|
1470
1545
|
}
|
|
1471
1546
|
return tests;
|
|
1472
1547
|
}
|
|
1473
|
-
|
|
1548
|
+
buildVariantTestInteraction(item, context) {
|
|
1474
1549
|
const plannedValue = this.extractSelectableValue(item);
|
|
1475
1550
|
if (!plannedValue || !item.selector)
|
|
1476
1551
|
return null;
|
|
@@ -1583,7 +1658,7 @@ export class PageAnalyzer {
|
|
|
1583
1658
|
generatedKey: this.buildGeneratedKey("variant-purchase", context.currentPageStateId, item.selector, plannedValue, purchaseAction.selector),
|
|
1584
1659
|
};
|
|
1585
1660
|
}
|
|
1586
|
-
|
|
1661
|
+
buildRequiredVariantGuardTestInteraction(item, requiredField, purchaseAction, context) {
|
|
1587
1662
|
const label = this.describeActionableItem(item);
|
|
1588
1663
|
const purchaseLabel = this.describeActionableItem(purchaseAction);
|
|
1589
1664
|
return {
|
|
@@ -1617,7 +1692,7 @@ export class PageAnalyzer {
|
|
|
1617
1692
|
}
|
|
1618
1693
|
return undefined;
|
|
1619
1694
|
}
|
|
1620
|
-
|
|
1695
|
+
buildDisclosureToggleTestInteraction(item, startingPath, sizeClass, uid, startingPageStateId) {
|
|
1621
1696
|
const label = this.describeActionableItem(item);
|
|
1622
1697
|
return {
|
|
1623
1698
|
title: `Toggle disclosure ${label}`,
|
|
@@ -1649,7 +1724,7 @@ export class PageAnalyzer {
|
|
|
1649
1724
|
generatedKey: this.buildGeneratedKey("disclosure-click", startingPageStateId, item.stableKey ?? item.selector ?? label),
|
|
1650
1725
|
};
|
|
1651
1726
|
}
|
|
1652
|
-
|
|
1727
|
+
buildKeyboardActivateTestInteraction(item, key, titlePrefix, expectations, startingPath, sizeClass, uid, startingPageStateId) {
|
|
1653
1728
|
const label = this.describeActionableItem(item);
|
|
1654
1729
|
return {
|
|
1655
1730
|
title: `${titlePrefix} ${label}`,
|
|
@@ -1695,7 +1770,7 @@ export class PageAnalyzer {
|
|
|
1695
1770
|
generatedKey: this.buildGeneratedKey("keyboard", startingPageStateId, key === " " ? "space" : key, item.stableKey ?? item.selector ?? label),
|
|
1696
1771
|
};
|
|
1697
1772
|
}
|
|
1698
|
-
|
|
1773
|
+
buildDialogCloseTestInteraction(item, startingPath, sizeClass, uid, startingPageStateId) {
|
|
1699
1774
|
const label = this.describeActionableItem(item);
|
|
1700
1775
|
return {
|
|
1701
1776
|
title: `Close dialog via ${label}`,
|
|
@@ -1726,7 +1801,7 @@ export class PageAnalyzer {
|
|
|
1726
1801
|
generatedKey: this.buildGeneratedKey("dialog-close", startingPageStateId, item.stableKey ?? item.selector ?? label),
|
|
1727
1802
|
};
|
|
1728
1803
|
}
|
|
1729
|
-
|
|
1804
|
+
buildEscapeDialogTestInteraction(startingPath, sizeClass, uid, startingPageStateId) {
|
|
1730
1805
|
return {
|
|
1731
1806
|
title: "Close dialog with Escape",
|
|
1732
1807
|
type: "interaction",
|
|
@@ -1770,7 +1845,7 @@ export class PageAnalyzer {
|
|
|
1770
1845
|
inputType === "radio" ||
|
|
1771
1846
|
inputType === "checkbox");
|
|
1772
1847
|
}
|
|
1773
|
-
|
|
1848
|
+
buildControlInteractionTestInteraction(item, startingPath, sizeClass, uid, startingPageStateId, dependencyTestInteractionId) {
|
|
1774
1849
|
const label = this.describeActionableItem(item);
|
|
1775
1850
|
const role = (item.role ?? "").toLowerCase();
|
|
1776
1851
|
const inputType = (item.inputType ?? "").toLowerCase();
|
|
@@ -1836,6 +1911,7 @@ export class PageAnalyzer {
|
|
|
1836
1911
|
role || inputType || item.actionKind || "control",
|
|
1837
1912
|
],
|
|
1838
1913
|
priority: 3,
|
|
1914
|
+
dependencyTestInteractionId,
|
|
1839
1915
|
startingPageStateId,
|
|
1840
1916
|
startingPath,
|
|
1841
1917
|
steps: [
|
|
@@ -1856,7 +1932,7 @@ export class PageAnalyzer {
|
|
|
1856
1932
|
? `${label} should remain non-interactive despite appearing disabled`
|
|
1857
1933
|
: `${label} should react without runtime errors`),
|
|
1858
1934
|
uid,
|
|
1859
|
-
generatedKey: this.buildGeneratedKey("control", startingPageStateId, isImmutable ? "immutable" : "enabled", role || inputType || item.actionKind || "control", item.stableKey ?? item.selector ?? label),
|
|
1935
|
+
generatedKey: this.buildGeneratedKey("control", startingPageStateId, dependencyTestInteractionId, isImmutable ? "immutable" : "enabled", role || inputType || item.actionKind || "control", item.stableKey ?? item.selector ?? label),
|
|
1860
1936
|
};
|
|
1861
1937
|
}
|
|
1862
1938
|
buildImmutableControlExpectations(item, label) {
|