@immense/vue-pom-generator 1.0.26 → 1.0.27

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/RELEASE_NOTES.md CHANGED
@@ -1,31 +1,36 @@
1
- ## Highlights
1
+ ```markdown
2
+ ## Highlights
2
3
 
3
- - Fixed issue where radio options were incorrectly inferred as wrapper elements
4
- - Added test coverage for radio option inference logic
5
- - Improved PR workflow with automated release-notes preview comments
4
+ - Fixed strict wrapper selector collision merging to prevent duplicate or conflicting selectors
5
+ - Enhanced utility functions for better selector handling and conflict detection
6
+ - Added comprehensive test coverage for selector collision scenarios
6
7
 
7
8
  ## Changes
8
9
 
9
- **Bug Fixes**
10
- - Avoid inferring radio options as wrappers ([5f6d7bf])
10
+ ### Bug Fixes
11
+ - Resolved strict wrapper selector collisions that could occur during transformation
12
+ - Improved selector merging logic to handle edge cases
11
13
 
12
- **Testing**
13
- - Added test cases for utils coverage
14
+ ### Testing
15
+ - Added 45 new test cases covering selector collision scenarios
16
+ - Expanded test suite in `tests/transform.test.ts`
14
17
 
15
- **Developer Experience**
16
- - Added PR release-notes preview comments (#1)
18
+ ### Internal
19
+ - Enhanced `utils.ts` with improved selector handling utilities (12 additions, 4 deletions)
20
+ - Updated `transform.ts` with collision resolution logic (80 additions, 1 deletion)
17
21
 
18
22
  ## Breaking Changes
19
23
 
20
- None
24
+ None.
21
25
 
22
26
  ## Pull Requests Included
23
27
 
24
28
  - #1 [Add PR release-notes preview
25
- comments](https://github.com/immense/vue-pom-generator/pull/1) by @dkattan
29
+ comments](https://github.com/immense/vue-pom-generator/pull/1) (by @dkattan)
26
30
 
27
31
  ## Testing
28
32
 
29
- Added 11 lines of test coverage in `tests/utils-coverage.test.ts` to verify the radio options
30
- inference fix.
33
+ Comprehensive test coverage added with 45 new test cases validating selector collision handling
34
+ and merge behavior.
35
+ ```
31
36
 
package/dist/index.cjs CHANGED
@@ -1863,9 +1863,6 @@ Fix: either (1) include ${args.bestKeyPlaceholder} in your :${attrLabel} templat
1863
1863
  })();
1864
1864
  const tryMergeWithExistingPrimary = (candidateActionName) => {
1865
1865
  const mergeKey = (args.pomMergeKey ?? "").trim();
1866
- if (!mergeKey) {
1867
- return false;
1868
- }
1869
1866
  if (isKeyed) {
1870
1867
  return false;
1871
1868
  }
@@ -1874,7 +1871,15 @@ Fix: either (1) include ${args.bestKeyPlaceholder} in your :${attrLabel} templat
1874
1871
  if (!existingEntry || !existingPom) {
1875
1872
  return false;
1876
1873
  }
1877
- if ((existingPom.mergeKey ?? "").trim() !== mergeKey) {
1874
+ const existingSelectors = [
1875
+ existingPom.formattedDataTestId,
1876
+ ...existingPom.alternateFormattedDataTestIds ?? []
1877
+ ];
1878
+ const sharesSelectorIdentity = existingSelectors.includes(formattedDataTestIdForPom);
1879
+ if (!mergeKey && !sharesSelectorIdentity) {
1880
+ return false;
1881
+ }
1882
+ if (mergeKey && (existingPom.mergeKey ?? "").trim() !== mergeKey && !sharesSelectorIdentity) {
1878
1883
  return false;
1879
1884
  }
1880
1885
  if (existingPom.nativeRole !== normalizedRole) {
@@ -4840,8 +4845,46 @@ function createTestIdTransform(componentName, componentHierarchyMap, nativeWrapp
4840
4845
  const normalizedViewsDirAbs = path.normalize(safeRealpath(path.resolve(viewsDirAbs)));
4841
4846
  const generatedMethodContentByComponent = /* @__PURE__ */ new Map();
4842
4847
  const lastConditionalHintByParent = /* @__PURE__ */ new WeakMap();
4848
+ const lastConditionalMergeGroupByParent = /* @__PURE__ */ new WeakMap();
4843
4849
  const conditionalHintByElement = /* @__PURE__ */ new WeakMap();
4844
4850
  const conditionalHintByIfBranch = /* @__PURE__ */ new WeakMap();
4851
+ const conditionalMergeGroupByElement = /* @__PURE__ */ new WeakMap();
4852
+ const conditionalMergeGroupByElementLoc = /* @__PURE__ */ new Map();
4853
+ const conditionalMergeGroupByIfBranch = /* @__PURE__ */ new WeakMap();
4854
+ let conditionalMergeGroupCounter = 0;
4855
+ const getElementLocationKey = (element) => {
4856
+ const startOffset = element.loc?.start.offset;
4857
+ const endOffset = element.loc?.end.offset;
4858
+ if (typeof startOffset !== "number" || typeof endOffset !== "number") {
4859
+ return null;
4860
+ }
4861
+ return `${element.tag}:${startOffset}:${endOffset}`;
4862
+ };
4863
+ const markConditionalMergeGroup = (nodes, mergeGroupKey) => {
4864
+ for (const child of nodes) {
4865
+ if (child.type === compilerCore.NodeTypes.ELEMENT) {
4866
+ const element = child;
4867
+ conditionalMergeGroupByElement.set(element, mergeGroupKey);
4868
+ const elementLocationKey = getElementLocationKey(element);
4869
+ if (elementLocationKey) {
4870
+ conditionalMergeGroupByElementLoc.set(elementLocationKey, mergeGroupKey);
4871
+ }
4872
+ markConditionalMergeGroup(element.children, mergeGroupKey);
4873
+ continue;
4874
+ }
4875
+ if (child.type === compilerCore.NodeTypes.IF) {
4876
+ const ifNode = child;
4877
+ for (const branch of ifNode.branches ?? []) {
4878
+ markConditionalMergeGroup(branch.children, mergeGroupKey);
4879
+ }
4880
+ continue;
4881
+ }
4882
+ if (child.type === compilerCore.NodeTypes.IF_BRANCH || child.type === compilerCore.NodeTypes.FOR) {
4883
+ const branchLike = child;
4884
+ markConditionalMergeGroup(branchLike.children ?? [], mergeGroupKey);
4885
+ }
4886
+ }
4887
+ };
4845
4888
  return (node, context) => {
4846
4889
  if (excludedComponents.includes(componentName)) {
4847
4890
  return;
@@ -4849,8 +4892,15 @@ function createTestIdTransform(componentName, componentHierarchyMap, nativeWrapp
4849
4892
  if (node.type === compilerCore.NodeTypes.IF) {
4850
4893
  const ifNode = node;
4851
4894
  const branches = ifNode.branches ?? [];
4895
+ const mergeGroupKey = `if-group:${++conditionalMergeGroupCounter}`;
4896
+ const ifParentKey = context?.parent ? context.parent : null;
4897
+ if (ifParentKey) {
4898
+ lastConditionalMergeGroupByParent.set(ifParentKey, mergeGroupKey);
4899
+ }
4852
4900
  let lastHint = null;
4853
4901
  for (const branch of branches) {
4902
+ conditionalMergeGroupByIfBranch.set(branch, mergeGroupKey);
4903
+ markConditionalMergeGroup(branch.children ?? [], mergeGroupKey);
4854
4904
  const cond = branch.condition ?? null;
4855
4905
  if (!cond) {
4856
4906
  const hint = lastHint ? `else ${lastHint}` : "else";
@@ -4929,10 +4979,28 @@ function createTestIdTransform(componentName, componentHierarchyMap, nativeWrapp
4929
4979
  const bestKeyPlaceholder = isSlotKey ? `\${${bestKeyInferred}}` : bestKeyInferred;
4930
4980
  const bestKeyVariable = isSlotKey ? bestKeyInferred : null;
4931
4981
  const keyValuesOverride = tryGetContainedInStaticVForSourceLiteralValues(context);
4932
- const parentKey = !parentIsRoot && context?.parent ? context.parent : null;
4982
+ const parentKey = context?.parent ? context.parent : null;
4933
4983
  const conditional = getConditionalDirectiveInfo(element);
4934
4984
  let conditionalHint = null;
4985
+ const elementLocationKey = getElementLocationKey(element);
4986
+ let conditionalMergeGroupKey = (elementLocationKey ? conditionalMergeGroupByElementLoc.get(elementLocationKey) ?? null : null) ?? conditionalMergeGroupByElement.get(element) ?? null;
4987
+ if (!conditionalMergeGroupKey && context?.parent?.type === compilerCore.NodeTypes.IF_BRANCH) {
4988
+ const branch = context.parent;
4989
+ conditionalMergeGroupKey = conditionalMergeGroupByIfBranch.get(branch) ?? null;
4990
+ }
4935
4991
  if (conditional && (conditional.kind === "if" || conditional.kind === "else-if")) {
4992
+ if (parentKey) {
4993
+ if (!conditionalMergeGroupKey) {
4994
+ if (conditional.kind === "if") {
4995
+ conditionalMergeGroupKey = `if-group:${++conditionalMergeGroupCounter}`;
4996
+ } else {
4997
+ conditionalMergeGroupKey = lastConditionalMergeGroupByParent.get(parentKey) ?? null;
4998
+ }
4999
+ }
5000
+ if (conditionalMergeGroupKey) {
5001
+ lastConditionalMergeGroupByParent.set(parentKey, conditionalMergeGroupKey);
5002
+ }
5003
+ }
4936
5004
  conditionalHint = tryExtractStableHintFromConditionalExpressionSource(conditional.source);
4937
5005
  if (conditionalHint && parentKey) {
4938
5006
  lastConditionalHintByParent.set(parentKey, conditionalHint);
@@ -4941,6 +5009,7 @@ function createTestIdTransform(componentName, componentHierarchyMap, nativeWrapp
4941
5009
  if (parentKey) {
4942
5010
  const previousHint = lastConditionalHintByParent.get(parentKey) ?? null;
4943
5011
  conditionalHint = previousHint ? `else ${previousHint}` : null;
5012
+ conditionalMergeGroupKey = lastConditionalMergeGroupByParent.get(parentKey) ?? null;
4944
5013
  }
4945
5014
  }
4946
5015
  if (!conditionalHint && context?.parent?.type === compilerCore.NodeTypes.IF_BRANCH) {
@@ -5048,11 +5117,13 @@ Fix: remove the explicit ${attrLabel}, or change existingIdBehavior to "overwrit
5048
5117
  const nativeRole = nativeWrappers[element.tag]?.role ?? element.tag;
5049
5118
  const primarySemanticHint = semanticNameHint || conditionalHint || void 0;
5050
5119
  const alternates = nameCollisionBehavior === "error" && semanticNameHint && conditionalHint ? [`${semanticNameHint} ${conditionalHint}`] : void 0;
5120
+ const pomMergeKey = semanticNameHint && conditionalMergeGroupKey ? `wrapper:ifgroup:${conditionalMergeGroupKey}:model:${semanticNameHint}` : void 0;
5051
5121
  applyResolvedDataTestIdForElement({
5052
5122
  preferredGeneratedValue: nativeWrappersValue,
5053
5123
  nativeRoleOverride: nativeRole,
5054
5124
  semanticNameHint: primarySemanticHint,
5055
- semanticNameHintAlternates: alternates
5125
+ semanticNameHintAlternates: alternates,
5126
+ pomMergeKey
5056
5127
  });
5057
5128
  return;
5058
5129
  }