pomwright 1.5.1 → 2.0.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.
Files changed (119) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +5 -5
  3. package/dist/index.d.mts +75 -970
  4. package/dist/index.d.ts +75 -970
  5. package/dist/index.js +585 -1872
  6. package/dist/index.mjs +598 -1880
  7. package/package.json +9 -11
  8. package/AGENTS.md +0 -37
  9. package/docs/v1/BaseApi-explanation.md +0 -63
  10. package/docs/v1/BasePage-explanation.md +0 -96
  11. package/docs/v1/LocatorSchema-explanation.md +0 -271
  12. package/docs/v1/LocatorSchemaPath-explanation.md +0 -165
  13. package/docs/v1/PlaywrightReportLogger-explanation.md +0 -56
  14. package/docs/v1/get-locator-methods-explanation.md +0 -250
  15. package/docs/v1/intro-to-using-pomwright.md +0 -899
  16. package/docs/v1/sessionStorage-methods-explanation.md +0 -38
  17. package/docs/v1/tips-folder-structure.md +0 -38
  18. package/docs/v1-to-v2-migration/bridge-migration-guide.md +0 -159
  19. package/docs/v1-to-v2-migration/direct-migration-guide.md +0 -238
  20. package/docs/v1-to-v2-migration/v1-to-v2-comparison.md +0 -547
  21. package/docs/v2/PageObject.md +0 -293
  22. package/docs/v2/composing-locator-modules.md +0 -93
  23. package/docs/v2/locator-registry.md +0 -695
  24. package/docs/v2/logging.md +0 -168
  25. package/docs/v2/overview.md +0 -515
  26. package/docs/v2/session-storage.md +0 -160
  27. package/index.ts +0 -75
  28. package/intTestV2/.env +0 -0
  29. package/intTestV2/fixtures/testApp.fixtures.ts +0 -43
  30. package/intTestV2/package.json +0 -22
  31. package/intTestV2/page-object-models/testApp/pages/iframe/iframe.locatorSchema.ts +0 -24
  32. package/intTestV2/page-object-models/testApp/pages/iframe/iframe.page.ts +0 -17
  33. package/intTestV2/page-object-models/testApp/pages/testPage.locatorSchema.ts +0 -32
  34. package/intTestV2/page-object-models/testApp/pages/testPage.page.ts +0 -119
  35. package/intTestV2/page-object-models/testApp/pages/testPath/[color]/color.locatorSchema.ts +0 -29
  36. package/intTestV2/page-object-models/testApp/pages/testPath/[color]/color.page.ts +0 -48
  37. package/intTestV2/page-object-models/testApp/pages/testPath/testPath.locatorSchema.ts +0 -9
  38. package/intTestV2/page-object-models/testApp/pages/testPath/testPath.page.ts +0 -23
  39. package/intTestV2/page-object-models/testApp/pages/testfilters/testfilters.locatorSchema.ts +0 -114
  40. package/intTestV2/page-object-models/testApp/pages/testfilters/testfilters.page.ts +0 -23
  41. package/intTestV2/page-object-models/testApp/testApp.base.ts +0 -20
  42. package/intTestV2/playwright.config.ts +0 -54
  43. package/intTestV2/server.js +0 -216
  44. package/intTestV2/test-data/staticPage/index.html +0 -280
  45. package/intTestV2/test-data/staticPage/w3images/avatar2.png +0 -0
  46. package/intTestV2/test-data/staticPage/w3images/avatar3.png +0 -0
  47. package/intTestV2/test-data/staticPage/w3images/avatar5.png +0 -0
  48. package/intTestV2/test-data/staticPage/w3images/avatar6.png +0 -0
  49. package/intTestV2/test-data/staticPage/w3images/forest.jpg +0 -0
  50. package/intTestV2/test-data/staticPage/w3images/lights.jpg +0 -0
  51. package/intTestV2/test-data/staticPage/w3images/mountains.jpg +0 -0
  52. package/intTestV2/test-data/staticPage/w3images/nature.jpg +0 -0
  53. package/intTestV2/test-data/staticPage/w3images/snow.jpg +0 -0
  54. package/intTestV2/tests/locatorRegistry/add/add.describe.spec.ts +0 -54
  55. package/intTestV2/tests/locatorRegistry/add/add.filter.spec.ts +0 -143
  56. package/intTestV2/tests/locatorRegistry/add/add.frameLocator.spec.ts +0 -23
  57. package/intTestV2/tests/locatorRegistry/add/add.get.clone.spec.ts +0 -76
  58. package/intTestV2/tests/locatorRegistry/add/add.getByAltText.spec.ts +0 -23
  59. package/intTestV2/tests/locatorRegistry/add/add.getById.spec.ts +0 -45
  60. package/intTestV2/tests/locatorRegistry/add/add.getByLabel.spec.ts +0 -23
  61. package/intTestV2/tests/locatorRegistry/add/add.getByPlaceholder.spec.ts +0 -23
  62. package/intTestV2/tests/locatorRegistry/add/add.getByRole.spec.ts +0 -23
  63. package/intTestV2/tests/locatorRegistry/add/add.getByTestId.spec.ts +0 -23
  64. package/intTestV2/tests/locatorRegistry/add/add.getByText.spec.ts +0 -23
  65. package/intTestV2/tests/locatorRegistry/add/add.getByTitle.spec.ts +0 -23
  66. package/intTestV2/tests/locatorRegistry/add/add.locator.spec.ts +0 -23
  67. package/intTestV2/tests/locatorRegistry/add/add.reuseExisting.spec.ts +0 -107
  68. package/intTestV2/tests/locatorRegistry/add/add.reuseReusable.spec.ts +0 -311
  69. package/intTestV2/tests/locatorRegistry/add/add.spec.ts +0 -159
  70. package/intTestV2/tests/locatorRegistry/filter.cycle.spec.ts +0 -39
  71. package/intTestV2/tests/locatorRegistry/getLocator/getLocator.spec.ts +0 -253
  72. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.clearSteps.spec.ts +0 -105
  73. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.describe.spec.ts +0 -23
  74. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.filter.spec.ts +0 -368
  75. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.getLocator.spec.ts +0 -56
  76. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.getNestedLocator.spec.ts +0 -175
  77. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.nth.spec.ts +0 -60
  78. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.remove.spec.ts +0 -32
  79. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.replace.spec.ts +0 -24
  80. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.spec.ts +0 -110
  81. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.update.spec.ts +0 -322
  82. package/intTestV2/tests/locatorRegistry/getNestedLocator/getNestedLocator.spec.ts +0 -412
  83. package/intTestV2/tests/locatorRegistry/registry/registry.binding.spec.ts +0 -50
  84. package/intTestV2/tests/locatorRegistry/validation/validation.locatorSchemaPath.spec.ts +0 -115
  85. package/intTestV2/tests/locatorRegistry/validation/validation.locatorSchemaPath.typecheck.ts +0 -86
  86. package/intTestV2/tests/locatorRegistry/validation/validation.sub-path.spec.ts +0 -45
  87. package/intTestV2/tests/step/step.spec.ts +0 -49
  88. package/intTestV2/tests/testApp/color.spec.ts +0 -15
  89. package/intTestV2/tests/testApp/iframe.spec.ts +0 -57
  90. package/intTestV2/tests/testApp/testFilters.spec.ts +0 -24
  91. package/intTestV2/tests/testApp/testPage.spec.ts +0 -161
  92. package/intTestV2/tests/testApp/testPath.spec.ts +0 -18
  93. package/pack-build.sh +0 -11
  94. package/pack-test-v2.sh +0 -36
  95. package/playwright.base.ts +0 -42
  96. package/skills/README.md +0 -56
  97. package/skills/pomwright-v1-5-bridge-migration/SKILL.md +0 -40
  98. package/skills/pomwright-v1-5-bridge-migration/references/call-site-migration.md +0 -178
  99. package/skills/pomwright-v1-5-bridge-migration/references/schema-translation.md +0 -183
  100. package/skills/pomwright-v2-migration/SKILL.md +0 -63
  101. package/skills/pomwright-v2-migration/references/call-site-migration.md +0 -265
  102. package/skills/pomwright-v2-migration/references/class-migration.md +0 -266
  103. package/skills/pomwright-v2-migration/references/fixture-and-helpers.md +0 -423
  104. package/skills/pomwright-v2-migration/references/locator-registration.md +0 -344
  105. package/srcV2/fixture/base.fixtures.ts +0 -23
  106. package/srcV2/helpers/navigation.ts +0 -153
  107. package/srcV2/helpers/playwrightReportLogger.ts +0 -196
  108. package/srcV2/helpers/sessionStorage.ts +0 -251
  109. package/srcV2/helpers/stepDecorator.ts +0 -106
  110. package/srcV2/locators/index.ts +0 -15
  111. package/srcV2/locators/locatorQueryBuilder.ts +0 -427
  112. package/srcV2/locators/locatorRegistrationBuilder.ts +0 -558
  113. package/srcV2/locators/locatorRegistry.ts +0 -583
  114. package/srcV2/locators/locatorUpdateBuilder.ts +0 -602
  115. package/srcV2/locators/reusableLocatorBuilder.ts +0 -200
  116. package/srcV2/locators/types.ts +0 -256
  117. package/srcV2/locators/utils.ts +0 -309
  118. package/srcV2/locators/v1SchemaTranslator.ts +0 -178
  119. package/srcV2/pageObject.ts +0 -105
@@ -1,602 +0,0 @@
1
- import type { Page } from "@playwright/test";
2
- import type { LocatorQueryBuilder } from "./locatorQueryBuilder";
3
- import type {
4
- LocatorChainPaths,
5
- LocatorStrategyDefinition,
6
- LocatorUpdate,
7
- RegistryPath,
8
- RoleDefinition,
9
- } from "./types";
10
- import { normalizeIdValue } from "./utils";
11
-
12
- const parseUpdateArguments = <Primary, OptionsType>(
13
- primaryOrOptions?: Primary | OptionsType,
14
- options?: OptionsType,
15
- optionsProvided?: boolean,
16
- ) => {
17
- let primary: Primary | undefined;
18
- let parsedOptions: OptionsType | undefined;
19
- let hasOptions = optionsProvided ?? false;
20
-
21
- if (options !== undefined) {
22
- parsedOptions = options;
23
- hasOptions = true;
24
- }
25
-
26
- if (primaryOrOptions !== undefined) {
27
- const treatAsOptions =
28
- !hasOptions &&
29
- options === undefined &&
30
- typeof primaryOrOptions === "object" &&
31
- !(primaryOrOptions instanceof RegExp);
32
-
33
- if (treatAsOptions) {
34
- parsedOptions = primaryOrOptions as OptionsType;
35
- hasOptions = true;
36
- } else {
37
- primary = primaryOrOptions as Primary;
38
- }
39
- }
40
-
41
- return { primary, options: parsedOptions, hasOptions };
42
- };
43
-
44
- const mergeOptions = <OptionsType>(
45
- currentOptions: OptionsType | undefined,
46
- updates: { options?: OptionsType } | undefined,
47
- ) => {
48
- if (updates && "options" in updates) {
49
- const updateOptions = updates.options;
50
- if (updateOptions && typeof updateOptions === "object") {
51
- return {
52
- ...(typeof currentOptions === "object" && currentOptions !== null ? currentOptions : {}),
53
- ...updateOptions,
54
- } as OptionsType;
55
- }
56
- return updateOptions as OptionsType;
57
- }
58
-
59
- return currentOptions as OptionsType;
60
- };
61
-
62
- type UpdateArgsWithOptions<Primary, Options> = [] | [Primary] | [Options] | [Primary, Options];
63
-
64
- type UpdateArgsWithoutOptions<Primary> = [] | [Primary];
65
-
66
- const mergeLocatorDefinition = (
67
- current: LocatorStrategyDefinition,
68
- updates: LocatorUpdate,
69
- path: string,
70
- preferredSource?: LocatorStrategyDefinition,
71
- baseline?: LocatorStrategyDefinition,
72
- ): LocatorStrategyDefinition => {
73
- if (!updates || typeof updates !== "object" || !("type" in updates)) {
74
- throw new Error(`Locator update for "${path}" requires a "type" property.`);
75
- }
76
-
77
- const source = <TType extends LocatorStrategyDefinition["type"]>(targetType: TType) => {
78
- if (current.type === targetType) {
79
- return current as Extract<LocatorStrategyDefinition, { type: TType }>;
80
- }
81
- if (preferredSource?.type === targetType) {
82
- return preferredSource as Extract<LocatorStrategyDefinition, { type: TType }>;
83
- }
84
- if (baseline?.type === targetType) {
85
- return baseline as Extract<LocatorStrategyDefinition, { type: TType }>;
86
- }
87
- return undefined;
88
- };
89
-
90
- switch (updates.type) {
91
- case "role": {
92
- const roleSource = source("role");
93
- const role = updates.role ?? roleSource?.role;
94
- if (role === undefined) {
95
- throw new Error(`Locator update for "${path}" of type "role" requires a "role" value.`);
96
- }
97
- const options = mergeOptions(roleSource?.options, updates);
98
- return options !== undefined
99
- ? ({ type: "role", role, options } as RoleDefinition)
100
- : ({ type: "role", role } as RoleDefinition);
101
- }
102
- case "text": {
103
- const textSource = source("text");
104
- const text = updates.text ?? textSource?.text;
105
- if (text === undefined) {
106
- throw new Error(`Locator update for "${path}" of type "text" requires a "text" value.`);
107
- }
108
- const options = mergeOptions(textSource?.options, updates);
109
- return options !== undefined
110
- ? ({ type: "text", text, options } as LocatorStrategyDefinition)
111
- : ({ type: "text", text } as LocatorStrategyDefinition);
112
- }
113
- case "label": {
114
- const textSource = source("label");
115
- const text = updates.text ?? textSource?.text;
116
- if (text === undefined) {
117
- throw new Error(`Locator update for "${path}" of type "label" requires a "text" value.`);
118
- }
119
- const options = mergeOptions(textSource?.options, updates);
120
- return options !== undefined
121
- ? ({ type: "label", text, options } as LocatorStrategyDefinition)
122
- : ({ type: "label", text } as LocatorStrategyDefinition);
123
- }
124
- case "placeholder": {
125
- const textSource = source("placeholder");
126
- const text = updates.text ?? textSource?.text;
127
- if (text === undefined) {
128
- throw new Error(`Locator update for "${path}" of type "placeholder" requires a "text" value.`);
129
- }
130
- const options = mergeOptions(textSource?.options, updates);
131
- return options !== undefined
132
- ? ({ type: "placeholder", text, options } as LocatorStrategyDefinition)
133
- : ({ type: "placeholder", text } as LocatorStrategyDefinition);
134
- }
135
- case "altText": {
136
- const textSource = source("altText");
137
- const text = updates.text ?? textSource?.text;
138
- if (text === undefined) {
139
- throw new Error(`Locator update for "${path}" of type "altText" requires a "text" value.`);
140
- }
141
- const options = mergeOptions(textSource?.options, updates);
142
- return options !== undefined
143
- ? ({ type: "altText", text, options } as LocatorStrategyDefinition)
144
- : ({ type: "altText", text } as LocatorStrategyDefinition);
145
- }
146
- case "title": {
147
- const textSource = source("title");
148
- const text = updates.text ?? textSource?.text;
149
- if (text === undefined) {
150
- throw new Error(`Locator update for "${path}" of type "title" requires a "text" value.`);
151
- }
152
- const options = mergeOptions(textSource?.options, updates);
153
- return options !== undefined
154
- ? ({ type: "title", text, options } as LocatorStrategyDefinition)
155
- : ({ type: "title", text } as LocatorStrategyDefinition);
156
- }
157
- case "locator": {
158
- const selectorSource = source("locator");
159
- const selector = updates.selector ?? selectorSource?.selector;
160
- if (selector === undefined) {
161
- throw new Error(`Locator update for "${path}" of type "locator" requires a "selector" value.`);
162
- }
163
- const options = mergeOptions(selectorSource?.options, updates);
164
- return options !== undefined
165
- ? ({ type: "locator", selector, options } as LocatorStrategyDefinition)
166
- : ({ type: "locator", selector } as LocatorStrategyDefinition);
167
- }
168
- case "frameLocator": {
169
- const selectorSource = source("frameLocator");
170
- const selector = updates.selector ?? selectorSource?.selector;
171
- if (selector === undefined) {
172
- throw new Error(`Locator update for "${path}" of type "frameLocator" requires a "selector" value.`);
173
- }
174
- return { type: "frameLocator", selector } as LocatorStrategyDefinition;
175
- }
176
- case "testId": {
177
- const testIdSource = source("testId");
178
- const testId = updates.testId ?? testIdSource?.testId;
179
- if (testId === undefined) {
180
- throw new Error(`Locator update for "${path}" of type "testId" requires a "testId" value.`);
181
- }
182
- return { type: "testId", testId } as LocatorStrategyDefinition;
183
- }
184
- case "id": {
185
- const idSource = source("id");
186
- const rawId = updates.id ?? idSource?.id;
187
- const id = normalizeIdValue(rawId);
188
- if (id === undefined) {
189
- throw new Error(`Locator update for "${path}" of type "id" requires an "id" value.`);
190
- }
191
- return { type: "id", id } as LocatorStrategyDefinition;
192
- }
193
- default: {
194
- const exhaustive: never = updates;
195
- return exhaustive;
196
- }
197
- }
198
- };
199
-
200
- const buildReplacementDefinition = (updates: LocatorUpdate, path: string): LocatorStrategyDefinition => {
201
- if (!updates || typeof updates !== "object" || !("type" in updates)) {
202
- throw new Error(`Locator replace for "${path}" requires a "type" property.`);
203
- }
204
-
205
- switch (updates.type) {
206
- case "role": {
207
- const { role, options } = updates;
208
- if (role === undefined) {
209
- throw new Error(`Locator replace for "${path}" of type "role" requires a "role" value.`);
210
- }
211
- return options !== undefined
212
- ? ({ type: "role", role, options } as RoleDefinition)
213
- : ({ type: "role", role } as RoleDefinition);
214
- }
215
- case "text": {
216
- const { text, options } = updates;
217
- if (text === undefined) {
218
- throw new Error(`Locator replace for "${path}" of type "text" requires a "text" value.`);
219
- }
220
- return options !== undefined
221
- ? ({ type: "text", text, options } as LocatorStrategyDefinition)
222
- : ({ type: "text", text } as LocatorStrategyDefinition);
223
- }
224
- case "label": {
225
- const { text, options } = updates;
226
- if (text === undefined) {
227
- throw new Error(`Locator replace for "${path}" of type "label" requires a "text" value.`);
228
- }
229
- return options !== undefined
230
- ? ({ type: "label", text, options } as LocatorStrategyDefinition)
231
- : ({ type: "label", text } as LocatorStrategyDefinition);
232
- }
233
- case "placeholder": {
234
- const { text, options } = updates;
235
- if (text === undefined) {
236
- throw new Error(`Locator replace for "${path}" of type "placeholder" requires a "text" value.`);
237
- }
238
- return options !== undefined
239
- ? ({ type: "placeholder", text, options } as LocatorStrategyDefinition)
240
- : ({ type: "placeholder", text } as LocatorStrategyDefinition);
241
- }
242
- case "altText": {
243
- const { text, options } = updates;
244
- if (text === undefined) {
245
- throw new Error(`Locator replace for "${path}" of type "altText" requires a "text" value.`);
246
- }
247
- return options !== undefined
248
- ? ({ type: "altText", text, options } as LocatorStrategyDefinition)
249
- : ({ type: "altText", text } as LocatorStrategyDefinition);
250
- }
251
- case "title": {
252
- const { text, options } = updates;
253
- if (text === undefined) {
254
- throw new Error(`Locator replace for "${path}" of type "title" requires a "text" value.`);
255
- }
256
- return options !== undefined
257
- ? ({ type: "title", text, options } as LocatorStrategyDefinition)
258
- : ({ type: "title", text } as LocatorStrategyDefinition);
259
- }
260
- case "locator": {
261
- const { selector, options } = updates;
262
- if (selector === undefined) {
263
- throw new Error(`Locator replace for "${path}" of type "locator" requires a "selector" value.`);
264
- }
265
- return options !== undefined
266
- ? ({ type: "locator", selector, options } as LocatorStrategyDefinition)
267
- : ({ type: "locator", selector } as LocatorStrategyDefinition);
268
- }
269
- case "frameLocator": {
270
- const { selector } = updates;
271
- if (selector === undefined) {
272
- throw new Error(`Locator replace for "${path}" of type "frameLocator" requires a "selector" value.`);
273
- }
274
- return { type: "frameLocator", selector } as LocatorStrategyDefinition;
275
- }
276
- case "testId": {
277
- const { testId } = updates;
278
- if (testId === undefined) {
279
- throw new Error(`Locator replace for "${path}" of type "testId" requires a "testId" value.`);
280
- }
281
- return { type: "testId", testId } as LocatorStrategyDefinition;
282
- }
283
- case "id": {
284
- const rawId = updates.id;
285
- const id = normalizeIdValue(rawId);
286
- if (id === undefined) {
287
- throw new Error(`Locator replace for "${path}" of type "id" requires an "id" value.`);
288
- }
289
- return { type: "id", id } as LocatorStrategyDefinition;
290
- }
291
- default: {
292
- const exhaustive: never = updates;
293
- return exhaustive;
294
- }
295
- }
296
- };
297
- export class LocatorUpdateBuilder<
298
- LocatorSchemaPathType extends string,
299
- LocatorSubstring extends RegistryPath<LocatorSchemaPathType>,
300
- SubPath extends LocatorChainPaths<RegistryPath<LocatorSchemaPathType>, LocatorSubstring>,
301
- > {
302
- constructor(
303
- private readonly parent: LocatorQueryBuilder<LocatorSchemaPathType, LocatorSubstring>,
304
- private readonly subPath: SubPath,
305
- private readonly mode: "update" | "replace" = "update",
306
- ) {}
307
-
308
- /**
309
- * Defines or patches a `getByRole` locator strategy for the target subpath. In `update` mode the
310
- * `role` and `options` arguments are optional (PATCH semantics); in `replace` mode they follow
311
- * Playwright requirements (POST semantics) and `role` is required.
312
- *
313
- * @example
314
- * ```ts
315
- * getLocatorSchema("form.button")
316
- * .update("form.button")
317
- * .getByRole({ name: "Save" })
318
- * .getNestedLocator();
319
- * ```
320
- */
321
- getByRole(...args: UpdateArgsWithOptions<RoleDefinition["role"], RoleDefinition["options"]>) {
322
- const [roleOrOptions, options] = args;
323
- const {
324
- primary: role,
325
- options: parsedOptions,
326
- hasOptions,
327
- } = parseUpdateArguments<RoleDefinition["role"], RoleDefinition["options"]>(
328
- roleOrOptions,
329
- options,
330
- args.length >= 2,
331
- );
332
-
333
- const definition: LocatorUpdate = {
334
- type: "role",
335
- ...(role !== undefined ? { role } : {}),
336
- ...(hasOptions ? { options: parsedOptions } : {}),
337
- };
338
-
339
- return this.commit(definition);
340
- }
341
-
342
- /**
343
- * Defines or patches a `getByText` locator strategy for the target subpath. In `update` mode,
344
- * text/options are optional; in `replace` mode text is required.
345
- *
346
- * @example
347
- * ```ts
348
- * getLocatorSchema("banner.message")
349
- * .replace("banner.message")
350
- * .getByText(/Updated/, { exact: false })
351
- * .getNestedLocator();
352
- * ```
353
- */
354
- getByText(...args: UpdateArgsWithOptions<Parameters<Page["getByText"]>[0], Parameters<Page["getByText"]>[1]>) {
355
- const [textOrOptions, options] = args;
356
- const {
357
- primary: text,
358
- options: parsedOptions,
359
- hasOptions,
360
- } = parseUpdateArguments<Parameters<Page["getByText"]>[0], Parameters<Page["getByText"]>[1]>(
361
- textOrOptions,
362
- options,
363
- args.length >= 2,
364
- );
365
-
366
- const definition: LocatorUpdate = {
367
- type: "text",
368
- ...(text !== undefined ? { text } : {}),
369
- ...(hasOptions ? { options: parsedOptions } : {}),
370
- };
371
-
372
- return this.commit(definition);
373
- }
374
-
375
- /**
376
- * Defines or patches a `getByLabel` locator strategy for the target subpath. In `update` mode the
377
- * label text/options are optional; in `replace` mode text is required.
378
- *
379
- * @example
380
- * ```ts
381
- * getLocatorSchema("form.email").update("form.email").getByLabel({ exact: true }).getNestedLocator();
382
- * ```
383
- */
384
- getByLabel(...args: UpdateArgsWithOptions<Parameters<Page["getByLabel"]>[0], Parameters<Page["getByLabel"]>[1]>) {
385
- const [textOrOptions, options] = args;
386
- const {
387
- primary: text,
388
- options: parsedOptions,
389
- hasOptions,
390
- } = parseUpdateArguments<Parameters<Page["getByLabel"]>[0], Parameters<Page["getByLabel"]>[1]>(
391
- textOrOptions,
392
- options,
393
- args.length >= 2,
394
- );
395
-
396
- const definition: LocatorUpdate = {
397
- type: "label",
398
- ...(text !== undefined ? { text } : {}),
399
- ...(hasOptions ? { options: parsedOptions } : {}),
400
- };
401
-
402
- return this.commit(definition);
403
- }
404
-
405
- /**
406
- * Defines or patches a `getByPlaceholder` locator strategy for the target subpath. In `update`
407
- * mode text/options are optional; in `replace` mode text is required.
408
- *
409
- * @example
410
- * ```ts
411
- * getLocatorSchema("form.search").update("form.search").getByPlaceholder({ exact: true }).getNestedLocator();
412
- * ```
413
- */
414
- getByPlaceholder(
415
- ...args: UpdateArgsWithOptions<Parameters<Page["getByPlaceholder"]>[0], Parameters<Page["getByPlaceholder"]>[1]>
416
- ) {
417
- const [textOrOptions, options] = args;
418
- const {
419
- primary: text,
420
- options: parsedOptions,
421
- hasOptions,
422
- } = parseUpdateArguments<Parameters<Page["getByPlaceholder"]>[0], Parameters<Page["getByPlaceholder"]>[1]>(
423
- textOrOptions,
424
- options,
425
- args.length >= 2,
426
- );
427
-
428
- const definition: LocatorUpdate = {
429
- type: "placeholder",
430
- ...(text !== undefined ? { text } : {}),
431
- ...(hasOptions ? { options: parsedOptions } : {}),
432
- };
433
-
434
- return this.commit(definition);
435
- }
436
-
437
- /**
438
- * Defines or patches a `getByAltText` locator strategy for the target subpath. In `update` mode
439
- * text/options are optional; in `replace` mode text is required.
440
- *
441
- * @example
442
- * ```ts
443
- * getLocatorSchema("image.logo").replace("image.logo").getByAltText("Logo").getNestedLocator();
444
- * ```
445
- */
446
- getByAltText(
447
- ...args: UpdateArgsWithOptions<Parameters<Page["getByAltText"]>[0], Parameters<Page["getByAltText"]>[1]>
448
- ) {
449
- const [textOrOptions, options] = args;
450
- const {
451
- primary: text,
452
- options: parsedOptions,
453
- hasOptions,
454
- } = parseUpdateArguments<Parameters<Page["getByAltText"]>[0], Parameters<Page["getByAltText"]>[1]>(
455
- textOrOptions,
456
- options,
457
- args.length >= 2,
458
- );
459
-
460
- const definition: LocatorUpdate = {
461
- type: "altText",
462
- ...(text !== undefined ? { text } : {}),
463
- ...(hasOptions ? { options: parsedOptions } : {}),
464
- };
465
-
466
- return this.commit(definition);
467
- }
468
-
469
- /**
470
- * Defines or patches a `getByTitle` locator strategy for the target subpath. In `update` mode
471
- * text/options are optional; in `replace` mode text is required.
472
- *
473
- * @example
474
- * ```ts
475
- * getLocatorSchema("icon.info").update("icon.info").getByTitle({ exact: true }).getNestedLocator();
476
- * ```
477
- */
478
- getByTitle(...args: UpdateArgsWithOptions<Parameters<Page["getByTitle"]>[0], Parameters<Page["getByTitle"]>[1]>) {
479
- const [textOrOptions, options] = args;
480
- const {
481
- primary: text,
482
- options: parsedOptions,
483
- hasOptions,
484
- } = parseUpdateArguments<Parameters<Page["getByTitle"]>[0], Parameters<Page["getByTitle"]>[1]>(
485
- textOrOptions,
486
- options,
487
- args.length >= 2,
488
- );
489
-
490
- const definition: LocatorUpdate = {
491
- type: "title",
492
- ...(text !== undefined ? { text } : {}),
493
- ...(hasOptions ? { options: parsedOptions } : {}),
494
- };
495
-
496
- return this.commit(definition);
497
- }
498
-
499
- /**
500
- * Defines or patches a `locator` strategy for the target subpath. In `update` mode selector and
501
- * options are optional and merge with the existing definition; in `replace` mode selector is
502
- * required.
503
- *
504
- * @example
505
- * ```ts
506
- * getLocatorSchema("list.items")
507
- * .replace("list.items")
508
- * .locator("ul > li", { hasText: /Row/ })
509
- * .getNestedLocator();
510
- * ```
511
- */
512
- locator(...args: UpdateArgsWithOptions<Parameters<Page["locator"]>[0], Parameters<Page["locator"]>[1]>) {
513
- const [selectorOrOptions, options] = args;
514
- const {
515
- primary: selector,
516
- options: parsedOptions,
517
- hasOptions,
518
- } = parseUpdateArguments<Parameters<Page["locator"]>[0], Parameters<Page["locator"]>[1]>(
519
- selectorOrOptions,
520
- options,
521
- args.length >= 2,
522
- );
523
-
524
- const definition: LocatorUpdate = {
525
- type: "locator",
526
- ...(selector !== undefined ? { selector } : {}),
527
- ...(hasOptions ? { options: parsedOptions } : {}),
528
- };
529
-
530
- return this.commit(definition);
531
- }
532
-
533
- /**
534
- * Defines or patches a `frameLocator` strategy for the target subpath. In `update` mode the
535
- * selector is optional and, when omitted, inherits the existing selector; in `replace` mode the
536
- * selector is required.
537
- *
538
- * @example
539
- * ```ts
540
- * getLocatorSchema("frame.login").replace("frame.login").frameLocator("iframe.auth").getNestedLocator();
541
- * ```
542
- */
543
- frameLocator(...args: UpdateArgsWithoutOptions<Parameters<Page["frameLocator"]>[0]>) {
544
- const [selector] = args;
545
-
546
- const definition: LocatorUpdate = {
547
- type: "frameLocator",
548
- ...(selector !== undefined ? { selector } : {}),
549
- };
550
-
551
- return this.commit(definition);
552
- }
553
-
554
- /**
555
- * Defines or patches a `getByTestId` locator strategy for the target subpath. In `update` mode
556
- * `testId` is optional and merges with existing options; in `replace` mode it is required.
557
- *
558
- * @example
559
- * ```ts
560
- * getLocatorSchema("card.title").update("card.title").getByTestId().getNestedLocator();
561
- * ```
562
- */
563
- getByTestId(...args: UpdateArgsWithoutOptions<Parameters<Page["getByTestId"]>[0]>) {
564
- const [testId] = args;
565
-
566
- const definition: LocatorUpdate = {
567
- type: "testId",
568
- ...(testId !== undefined ? { testId } : {}),
569
- };
570
-
571
- return this.commit(definition);
572
- }
573
-
574
- /**
575
- * Defines or patches an `id` locator strategy for the target subpath. In `update` mode the id is
576
- * optional and will be normalized if provided; in `replace` mode the id is required.
577
- *
578
- * @example
579
- * ```ts
580
- * getLocatorSchema("modal.close").update("modal.close").getById().getNestedLocator();
581
- * ```
582
- */
583
- getById(...args: UpdateArgsWithoutOptions<string | RegExp>) {
584
- const [idValue] = args;
585
- const id = idValue !== undefined ? normalizeIdValue(idValue) : undefined;
586
-
587
- const definition: LocatorUpdate = {
588
- type: "id",
589
- ...(id !== undefined ? { id } : {}),
590
- };
591
-
592
- return this.commit(definition);
593
- }
594
-
595
- private commit(definition: LocatorUpdate) {
596
- return this.mode === "replace"
597
- ? this.parent.applyReplacement(this.subPath, definition)
598
- : this.parent.applyUpdate(this.subPath, definition);
599
- }
600
- }
601
-
602
- export { buildReplacementDefinition, mergeLocatorDefinition };