@immense/vue-pom-generator 1.0.57 → 1.0.58

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/README.md CHANGED
@@ -54,7 +54,7 @@ export class UserEditorPage extends BasePage {
54
54
  get SaveButton() { /* Playwright locator */ }
55
55
 
56
56
  async typeEmailAddress(text: string, annotationText = "") { /* ... */ }
57
- async clickSave(wait: boolean = true) { /* ... */ }
57
+ async clickSave(wait: boolean = true, annotationText = "") { /* ... */ }
58
58
  }
59
59
  ```
60
60
 
package/RELEASE_NOTES.md CHANGED
@@ -1,30 +1,47 @@
1
- ## Highlights
1
+ I'll fetch the actual commits and PRs between v1.0.57 and HEAD to generate accurate release
2
+ notes.
2
3
 
3
- - Fixed router introspection cleanup to properly restore DOM globals after execution
4
- - Improved test coverage for router introspection with 83 new test lines
5
- - Refactored router-introspection implementation for better DOM shim management
4
+ Based on the commit range v1.0.57..HEAD, only PR #19 is included in this release. Here are the
5
+ release notes:
6
+
7
+ ---
8
+
9
+ ## Highlights
10
+
11
+ - Pass annotation text through generated click helpers for better test documentation
12
+ - Resolve Vue compiler and Nuxt kit dependencies from consuming app setups instead of the
13
+ plugin's own tree
14
+ - Centralize Playwright video dimension configuration for consistent local and CI test
15
+ recordings
6
16
 
7
17
  ## Changes
8
18
 
9
- ### Bug Fixes
10
- - **Router introspection**: Restored router DOM globals after introspection to prevent state
11
- pollution between test runs and avoid interfering with downstream code that depends on these
12
- globals
19
+ **Local integration hardening:**
20
+ - Generated click helpers now accept and document annotation text parameters
21
+ - Resolve `@vue/compiler-sfc.parse` and `@nuxt/kit` from real consuming-app setups to avoid
22
+ version mismatches
23
+ - Add centralized Playwright video dimensions configuration (`playwright-video-dimensions.json`)
24
+ - Add script to normalize Playwright video settings across local config and CI environments
13
25
 
14
- ### Testing
15
- - Added comprehensive test coverage for router DOM global restoration behavior
26
+ **Test coverage improvements:**
27
+ - Add regression tests for project-local Nuxt kit loading
28
+ - Enhance Nuxt discovery test coverage with real-world integration scenarios
16
29
 
17
30
  ## Breaking Changes
18
31
 
19
- None
32
+ None.
20
33
 
21
34
  ## Pull Requests Included
22
35
 
23
- - #18 fix: restore router DOM globals after introspection
24
- (https://github.com/immense/vue-pom-generator/pull/18)
36
+ - [#19](https://github.com/immense/vue-pom-generator/pull/19) fix: harden local app integration
25
37
 
26
38
  ## Testing
27
39
 
28
- Added 83 lines of test coverage for router introspection DOM global handling. All existing tests
29
- continue to pass.
40
+ Validated with:
41
+ - `npm run lint`
42
+ - `npm run typecheck`
43
+ - `npm run build`
44
+ - `npm test`
45
+
46
+ All tests passing with 258 net lines added across 13 files.
30
47
 
package/dist/index.cjs CHANGED
@@ -104,6 +104,21 @@ function createLogger(options) {
104
104
  };
105
105
  }
106
106
  const requireFromModule = node_module.createRequire(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index.cjs", document.baseURI).href);
107
+ function resolveNuxtKitEntry(cwd) {
108
+ const attemptResolvers = [
109
+ node_module.createRequire(path.resolve(cwd, "package.json")),
110
+ requireFromModule
111
+ ];
112
+ let lastError;
113
+ for (const resolver of attemptResolvers) {
114
+ try {
115
+ return resolver.resolve("@nuxt/kit");
116
+ } catch (error) {
117
+ lastError = error instanceof Error ? error : new Error(String(error));
118
+ }
119
+ }
120
+ throw lastError ?? new Error("Unknown module resolution error");
121
+ }
107
122
  function toUniqueResolvedPaths(paths) {
108
123
  return Array.from(new Set(paths.map((value) => path.resolve(value))));
109
124
  }
@@ -214,7 +229,7 @@ async function loadNuxtProjectDiscovery(cwd = process.cwd()) {
214
229
  let loadNuxtConfig;
215
230
  let getLayerDirectories;
216
231
  try {
217
- const nuxtKitEntry = requireFromModule.resolve("@nuxt/kit");
232
+ const nuxtKitEntry = resolveNuxtKitEntry(cwd);
218
233
  ({ loadNuxtConfig, getLayerDirectories } = await import(node_url.pathToFileURL(nuxtKitEntry).href));
219
234
  } catch (error) {
220
235
  throw new TypeError(
@@ -403,7 +418,14 @@ function generateClickMethod(methodName, formattedDataTestId, alternateFormatted
403
418
  const candidatesExpr = [formattedDataTestId, ...alternates].map(testIdExpression).join(", ");
404
419
  const clickMethod = createAsyncMethod(
405
420
  name,
406
- hasParam(params, "key") ? [...baseParameters, createInlineParameter("wait", { type: "boolean", initializer: "true" })] : [createInlineParameter("wait", { type: "boolean", initializer: "true" })],
421
+ hasParam(params, "key") ? [
422
+ ...baseParameters,
423
+ createInlineParameter("wait", { type: "boolean", initializer: "true" }),
424
+ createInlineParameter("annotationText", { type: "string", initializer: '""' })
425
+ ] : [
426
+ createInlineParameter("wait", { type: "boolean", initializer: "true" }),
427
+ createInlineParameter("annotationText", { type: "string", initializer: '""' })
428
+ ],
407
429
  (writer) => {
408
430
  writer.writeLine(`const candidates = [${candidatesExpr}] as const;`);
409
431
  writer.writeLine("let lastError: unknown;");
@@ -411,7 +433,7 @@ function generateClickMethod(methodName, formattedDataTestId, alternateFormatted
411
433
  writer.writeLine("const locator = this.locatorByTestId(testId);");
412
434
  writer.write("try ").block(() => {
413
435
  writer.write("if (await locator.count()) ").block(() => {
414
- writer.writeLine('await this.clickLocator(locator, "", wait);');
436
+ writer.writeLine("await this.clickLocator(locator, annotationText, wait);");
415
437
  writer.writeLine("return;");
416
438
  });
417
439
  });
@@ -422,10 +444,10 @@ function generateClickMethod(methodName, formattedDataTestId, alternateFormatted
422
444
  writer.writeLine(`throw (lastError instanceof Error) ? lastError : new Error("[pom] Failed to click any candidate locator for ${name}.");`);
423
445
  }
424
446
  );
425
- const noWaitArgs = argsForForward ? `${argsForForward}, false` : "false";
447
+ const noWaitArgs = argsForForward ? `${argsForForward}, false, annotationText` : "false, annotationText";
426
448
  const noWaitMethod = createAsyncMethod(
427
449
  noWaitName,
428
- hasParam(params, "key") ? baseParameters : [],
450
+ hasParam(params, "key") ? [...baseParameters, createInlineParameter("annotationText", { type: "string", initializer: '""' })] : [createInlineParameter("annotationText", { type: "string", initializer: '""' })],
429
451
  (writer) => {
430
452
  writer.writeLine(`await this.${name}(${noWaitArgs});`);
431
453
  }
@@ -434,21 +456,44 @@ function generateClickMethod(methodName, formattedDataTestId, alternateFormatted
434
456
  }
435
457
  if (hasParam(params, "key")) {
436
458
  return [
437
- createAsyncMethod(name, [...baseParameters, createInlineParameter("wait", { type: "boolean", initializer: "true" })], (writer) => {
438
- writer.writeLine(`await this.clickByTestId(\`${formattedDataTestId}\`, "", wait);`);
439
- }),
440
- createAsyncMethod(noWaitName, baseParameters, (writer) => {
441
- writer.writeLine(`await this.${name}(${argsForForward}, false);`);
442
- })
459
+ createAsyncMethod(
460
+ name,
461
+ [
462
+ ...baseParameters,
463
+ createInlineParameter("wait", { type: "boolean", initializer: "true" }),
464
+ createInlineParameter("annotationText", { type: "string", initializer: '""' })
465
+ ],
466
+ (writer) => {
467
+ writer.writeLine(`await this.clickByTestId(\`${formattedDataTestId}\`, annotationText, wait);`);
468
+ }
469
+ ),
470
+ createAsyncMethod(
471
+ noWaitName,
472
+ [...baseParameters, createInlineParameter("annotationText", { type: "string", initializer: '""' })],
473
+ (writer) => {
474
+ writer.writeLine(`await this.${name}(${argsForForward}, false, annotationText);`);
475
+ }
476
+ )
443
477
  ];
444
478
  }
445
479
  return [
446
- createAsyncMethod(name, [createInlineParameter("wait", { type: "boolean", initializer: "true" })], (writer) => {
447
- writer.writeLine(`await this.clickByTestId("${formattedDataTestId}", "", wait);`);
448
- }),
449
- createAsyncMethod(noWaitName, [], (writer) => {
450
- writer.writeLine(`await this.${name}(false);`);
451
- })
480
+ createAsyncMethod(
481
+ name,
482
+ [
483
+ createInlineParameter("wait", { type: "boolean", initializer: "true" }),
484
+ createInlineParameter("annotationText", { type: "string", initializer: '""' })
485
+ ],
486
+ (writer) => {
487
+ writer.writeLine(`await this.clickByTestId("${formattedDataTestId}", annotationText, wait);`);
488
+ }
489
+ ),
490
+ createAsyncMethod(
491
+ noWaitName,
492
+ [createInlineParameter("annotationText", { type: "string", initializer: '""' })],
493
+ (writer) => {
494
+ writer.writeLine(`await this.${name}(false, annotationText);`);
495
+ }
496
+ )
452
497
  ];
453
498
  }
454
499
  function generateRadioMethod(methodName, formattedDataTestId) {
@@ -2893,10 +2938,13 @@ Fix: make the element identifiable (e.g. add id/name/inner text or use a more sp
2893
2938
  formattedDataTestId: formattedDataTestIdForPom
2894
2939
  },
2895
2940
  keyLiteral: rawValue,
2896
- params: { wait: "boolean = true" }
2941
+ params: { wait: "boolean = true", annotationText: 'string = ""' }
2897
2942
  });
2898
2943
  if (added) {
2899
- registerGeneratedMethodSignature(generatedName, { params: `wait: boolean = true`, argNames: ["wait"] });
2944
+ registerGeneratedMethodSignature(generatedName, {
2945
+ params: `wait: boolean = true, annotationText: string = ""`,
2946
+ argNames: ["wait", "annotationText"]
2947
+ });
2900
2948
  }
2901
2949
  }
2902
2950
  return;
@@ -8060,6 +8108,13 @@ function tryCreateElementMetadata(args) {
8060
8108
  };
8061
8109
  return metadata;
8062
8110
  }
8111
+ function resolveCompilerSfcParse(compilerSfc2) {
8112
+ const parse = compilerSfc2.parse ?? compilerSfc2.default?.parse;
8113
+ if (typeof parse !== "function") {
8114
+ throw new TypeError("[vue-pom-generator] Failed to resolve @vue/compiler-sfc.parse.");
8115
+ }
8116
+ return parse;
8117
+ }
8063
8118
  function extractMetadataAfterTransform(ast, componentName, elementMetadata, semanticNameMap, testIdAttribute) {
8064
8119
  const componentMetadata = /* @__PURE__ */ new Map();
8065
8120
  function traverseNode(node) {
@@ -8256,7 +8311,8 @@ function createVuePluginWithTestIds(options) {
8256
8311
  }
8257
8312
  const componentName = getComponentNameFromPath(cleanPath);
8258
8313
  loggerRef.current.debug(`Collecting metadata for ${cleanPath} (component: ${componentName})`);
8259
- const { parse } = await import("@vue/compiler-sfc");
8314
+ const compilerSfc2 = await import("@vue/compiler-sfc");
8315
+ const parse = resolveCompilerSfcParse(compilerSfc2);
8260
8316
  const compilerDom2 = await import("@vue/compiler-dom");
8261
8317
  const compile = compilerDom2.compile;
8262
8318
  const { descriptor } = parse(code, { filename: cleanPath });