@testid/antd-testid-runtime 1.0.16 → 1.0.18

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/index.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { App } from 'vue';
2
+
1
3
  /**
2
4
  * UI 库适配器接口 — adapters/types.ts
3
5
  *
@@ -10,7 +12,7 @@
10
12
  /**
11
13
  * 支持的浮层类型
12
14
  */
13
- type PopupType = 'modal' | 'drawer' | 'select' | 'datePicker' | 'popconfirm' | 'popover' | 'dropdown' | 'tooltip' | 'message';
15
+ type PopupType = 'modal' | 'drawer' | 'select' | 'datePicker' | 'popconfirm' | 'popover' | 'dropdown' | 'tooltip' | 'message' | 'submenu';
14
16
  /**
15
17
  * UI 库适配器接口
16
18
  *
@@ -486,4 +488,30 @@ declare class TestIdChecker {
486
488
  private static reportGroupDuplicates;
487
489
  }
488
490
 
489
- export { type ParsedBaseKey, type PopupType, TestIdChecker, type TestIdMarkConfig, TestIdObserver, type UiAdapter, antdAdapter, buildAnchorTestId, buildPopupTestId, defaultConfig, elementAdapter, getAnchorCounterMap, getConfig, getNextAnchorLocalIndex, getNextPopupId, getPopupCounterSnapshot, initConfig, mergeConfig, parseBaseKey, resetAllAnchorCounters, resetAllPopupCounters, resetPopupCounter };
491
+ /**
492
+ * Vue 3 插件桥接 — testIdVuePlugin.ts
493
+ *
494
+ * 铁三角第二层:绕过 UI 库组件 inheritAttrs: false 的限制。
495
+ *
496
+ * 问题背景:
497
+ * 编译期在 <a-menu-item data-test-base-key="..."> 上注入属性,
498
+ * 但 Ant Design Vue 等 UI 库组件通常设置 inheritAttrs: false,
499
+ * 导致非 prop 属性不会自动传递到渲染后的 DOM 元素上。
500
+ *
501
+ * 解决方案:
502
+ * 通过 app.mixin({ mounted() }) 全局混入,在每个组件挂载后,
503
+ * 从 Vue 内部的 $attrs 中读取插件关注的属性并手动写入 $el。
504
+ *
505
+ * 对于 inheritAttrs: true (默认) 的组件,Vue 已自动应用属性到 $el,
506
+ * hasAttribute 检查会跳过避免重复写入。
507
+ *
508
+ * 使用方式:
509
+ * import { TestIdVuePlugin } from '@testid/antd-testid-runtime';
510
+ * app.use(TestIdVuePlugin); // 必须在 app.mount() 之前调用
511
+ */
512
+
513
+ declare const TestIdVuePlugin: {
514
+ install(app: App): void;
515
+ };
516
+
517
+ export { type ParsedBaseKey, type PopupType, TestIdChecker, type TestIdMarkConfig, TestIdObserver, TestIdVuePlugin, type UiAdapter, antdAdapter, buildAnchorTestId, buildPopupTestId, defaultConfig, elementAdapter, getAnchorCounterMap, getConfig, getNextAnchorLocalIndex, getNextPopupId, getPopupCounterSnapshot, initConfig, mergeConfig, parseBaseKey, resetAllAnchorCounters, resetAllPopupCounters, resetPopupCounter };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { App } from 'vue';
2
+
1
3
  /**
2
4
  * UI 库适配器接口 — adapters/types.ts
3
5
  *
@@ -10,7 +12,7 @@
10
12
  /**
11
13
  * 支持的浮层类型
12
14
  */
13
- type PopupType = 'modal' | 'drawer' | 'select' | 'datePicker' | 'popconfirm' | 'popover' | 'dropdown' | 'tooltip' | 'message';
15
+ type PopupType = 'modal' | 'drawer' | 'select' | 'datePicker' | 'popconfirm' | 'popover' | 'dropdown' | 'tooltip' | 'message' | 'submenu';
14
16
  /**
15
17
  * UI 库适配器接口
16
18
  *
@@ -486,4 +488,30 @@ declare class TestIdChecker {
486
488
  private static reportGroupDuplicates;
487
489
  }
488
490
 
489
- export { type ParsedBaseKey, type PopupType, TestIdChecker, type TestIdMarkConfig, TestIdObserver, type UiAdapter, antdAdapter, buildAnchorTestId, buildPopupTestId, defaultConfig, elementAdapter, getAnchorCounterMap, getConfig, getNextAnchorLocalIndex, getNextPopupId, getPopupCounterSnapshot, initConfig, mergeConfig, parseBaseKey, resetAllAnchorCounters, resetAllPopupCounters, resetPopupCounter };
491
+ /**
492
+ * Vue 3 插件桥接 — testIdVuePlugin.ts
493
+ *
494
+ * 铁三角第二层:绕过 UI 库组件 inheritAttrs: false 的限制。
495
+ *
496
+ * 问题背景:
497
+ * 编译期在 <a-menu-item data-test-base-key="..."> 上注入属性,
498
+ * 但 Ant Design Vue 等 UI 库组件通常设置 inheritAttrs: false,
499
+ * 导致非 prop 属性不会自动传递到渲染后的 DOM 元素上。
500
+ *
501
+ * 解决方案:
502
+ * 通过 app.mixin({ mounted() }) 全局混入,在每个组件挂载后,
503
+ * 从 Vue 内部的 $attrs 中读取插件关注的属性并手动写入 $el。
504
+ *
505
+ * 对于 inheritAttrs: true (默认) 的组件,Vue 已自动应用属性到 $el,
506
+ * hasAttribute 检查会跳过避免重复写入。
507
+ *
508
+ * 使用方式:
509
+ * import { TestIdVuePlugin } from '@testid/antd-testid-runtime';
510
+ * app.use(TestIdVuePlugin); // 必须在 app.mount() 之前调用
511
+ */
512
+
513
+ declare const TestIdVuePlugin: {
514
+ install(app: App): void;
515
+ };
516
+
517
+ export { type ParsedBaseKey, type PopupType, TestIdChecker, type TestIdMarkConfig, TestIdObserver, TestIdVuePlugin, type UiAdapter, antdAdapter, buildAnchorTestId, buildPopupTestId, defaultConfig, elementAdapter, getAnchorCounterMap, getConfig, getNextAnchorLocalIndex, getNextPopupId, getPopupCounterSnapshot, initConfig, mergeConfig, parseBaseKey, resetAllAnchorCounters, resetAllPopupCounters, resetPopupCounter };
package/dist/index.js CHANGED
@@ -39,6 +39,7 @@ var index_exports = {};
39
39
  __export(index_exports, {
40
40
  TestIdChecker: () => TestIdChecker,
41
41
  TestIdObserver: () => TestIdObserver,
42
+ TestIdVuePlugin: () => TestIdVuePlugin,
42
43
  antdAdapter: () => antdAdapter,
43
44
  buildAnchorTestId: () => buildAnchorTestId,
44
45
  buildPopupTestId: () => buildPopupTestId,
@@ -73,7 +74,8 @@ var popupClassSuffixMap = {
73
74
  popover: [["-popover"]],
74
75
  dropdown: [["-dropdown"]],
75
76
  tooltip: [["-tooltip"]],
76
- message: [["-message"]]
77
+ message: [["-message"]],
78
+ submenu: [["-menu-submenu-popup"]]
77
79
  };
78
80
  var antdAdapter = {
79
81
  name: "ant-design-vue",
@@ -119,7 +121,8 @@ var defaultConfig = {
119
121
  popover: "popover_",
120
122
  dropdown: "dropdown_",
121
123
  tooltip: "tooltip_",
122
- message: "message_"
124
+ message: "message_",
125
+ submenu: "submenu_"
123
126
  },
124
127
  ignoreTags: ["script", "style", "svg", "br", "iframe"],
125
128
  ignoreClass: ["no-test-mark", "hidden"],
@@ -187,7 +190,8 @@ var popupClassSuffixMap2 = {
187
190
  popover: [["-popover"]],
188
191
  dropdown: [["-dropdown-menu"]],
189
192
  tooltip: [["-tooltip__popper"]],
190
- message: [["-message"]]
193
+ message: [["-message"]],
194
+ submenu: []
191
195
  };
192
196
  var elementAdapter = {
193
197
  name: "element-ui",
@@ -260,7 +264,8 @@ var popupCounters = {
260
264
  popover: 0,
261
265
  dropdown: 0,
262
266
  tooltip: 0,
263
- message: 0
267
+ message: 0,
268
+ submenu: 0
264
269
  };
265
270
  function getNextPopupId(type) {
266
271
  const key = type in popupCounters ? type : "modal";
@@ -688,7 +693,7 @@ var TestIdObserver = class {
688
693
  if (node.hasAttribute("tabindex")) return true;
689
694
  const classStr = node.className;
690
695
  if (typeof classStr === "string") {
691
- if (/\bant-(?:menu-item|dropdown-menu-item|select-item|tabs-tab|picker-cell|breadcrumb-link)\b/.test(classStr)) {
696
+ if (/\bant-(?:menu-item|menu-submenu|dropdown-menu-item|select-item|tabs-tab|picker-cell|breadcrumb-link)\b/.test(classStr)) {
692
697
  return true;
693
698
  }
694
699
  if (/\bel-(?:menu-item|dropdown-menu__item|select-dropdown__item|tabs__item)\b/.test(classStr)) {
@@ -726,7 +731,8 @@ var GROUP_LABELS = {
726
731
  popover: "[Popover \u6D6E\u5C42]",
727
732
  dropdown: "[Dropdown \u6D6E\u5C42]",
728
733
  tooltip: "[Tooltip \u6D6E\u5C42]",
729
- message: "[Message \u6D6E\u5C42]"
734
+ message: "[Message \u6D6E\u5C42]",
735
+ submenu: "[SubMenu \u6D6E\u5C42]"
730
736
  };
731
737
  var GROUP_SUGGESTIONS = {
732
738
  custom: "\u4E1A\u52A1\u4EE3\u7801\u4E2D\u5B58\u5728\u624B\u5199\u56FA\u5B9A\u91CD\u590D data-testid\uFF0C\u8BF7\u68C0\u67E5\u76F8\u5173\u6A21\u677F\u4EE3\u7801",
@@ -740,7 +746,8 @@ var GROUP_SUGGESTIONS = {
740
746
  popover: "Popover \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548",
741
747
  dropdown: "Dropdown \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548",
742
748
  tooltip: "Tooltip \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548",
743
- message: "Message \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548"
749
+ message: "Message \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548",
750
+ submenu: "SubMenu \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548"
744
751
  };
745
752
  var TestIdChecker = class {
746
753
  /**
@@ -839,7 +846,8 @@ var TestIdChecker = class {
839
846
  "popover",
840
847
  "dropdown",
841
848
  "tooltip",
842
- "message"
849
+ "message",
850
+ "submenu"
843
851
  ];
844
852
  for (const type of popupTypes) {
845
853
  if (prefix === `${type}_`) return type;
@@ -875,10 +883,32 @@ var TestIdChecker = class {
875
883
  console.groupEnd();
876
884
  }
877
885
  };
886
+
887
+ // src/utils/testIdVuePlugin.ts
888
+ var WATCHED_ATTRS = ["data-testid", "data-test-base-key"];
889
+ var TestIdVuePlugin = {
890
+ install(app) {
891
+ app.mixin({
892
+ mounted() {
893
+ const el = this.$el;
894
+ if (!el) return;
895
+ const attrs = this.$attrs || {};
896
+ if (!attrs || typeof attrs !== "object") return;
897
+ for (const attr of WATCHED_ATTRS) {
898
+ const value = attrs[attr];
899
+ if (value != null && !el.hasAttribute(attr)) {
900
+ el.setAttribute(attr, String(value));
901
+ }
902
+ }
903
+ }
904
+ });
905
+ }
906
+ };
878
907
  // Annotate the CommonJS export names for ESM import in node:
879
908
  0 && (module.exports = {
880
909
  TestIdChecker,
881
910
  TestIdObserver,
911
+ TestIdVuePlugin,
882
912
  antdAdapter,
883
913
  buildAnchorTestId,
884
914
  buildPopupTestId,
package/dist/index.mjs CHANGED
@@ -33,7 +33,8 @@ var popupClassSuffixMap = {
33
33
  popover: [["-popover"]],
34
34
  dropdown: [["-dropdown"]],
35
35
  tooltip: [["-tooltip"]],
36
- message: [["-message"]]
36
+ message: [["-message"]],
37
+ submenu: [["-menu-submenu-popup"]]
37
38
  };
38
39
  var antdAdapter = {
39
40
  name: "ant-design-vue",
@@ -79,7 +80,8 @@ var defaultConfig = {
79
80
  popover: "popover_",
80
81
  dropdown: "dropdown_",
81
82
  tooltip: "tooltip_",
82
- message: "message_"
83
+ message: "message_",
84
+ submenu: "submenu_"
83
85
  },
84
86
  ignoreTags: ["script", "style", "svg", "br", "iframe"],
85
87
  ignoreClass: ["no-test-mark", "hidden"],
@@ -147,7 +149,8 @@ var popupClassSuffixMap2 = {
147
149
  popover: [["-popover"]],
148
150
  dropdown: [["-dropdown-menu"]],
149
151
  tooltip: [["-tooltip__popper"]],
150
- message: [["-message"]]
152
+ message: [["-message"]],
153
+ submenu: []
151
154
  };
152
155
  var elementAdapter = {
153
156
  name: "element-ui",
@@ -220,7 +223,8 @@ var popupCounters = {
220
223
  popover: 0,
221
224
  dropdown: 0,
222
225
  tooltip: 0,
223
- message: 0
226
+ message: 0,
227
+ submenu: 0
224
228
  };
225
229
  function getNextPopupId(type) {
226
230
  const key = type in popupCounters ? type : "modal";
@@ -648,7 +652,7 @@ var TestIdObserver = class {
648
652
  if (node.hasAttribute("tabindex")) return true;
649
653
  const classStr = node.className;
650
654
  if (typeof classStr === "string") {
651
- if (/\bant-(?:menu-item|dropdown-menu-item|select-item|tabs-tab|picker-cell|breadcrumb-link)\b/.test(classStr)) {
655
+ if (/\bant-(?:menu-item|menu-submenu|dropdown-menu-item|select-item|tabs-tab|picker-cell|breadcrumb-link)\b/.test(classStr)) {
652
656
  return true;
653
657
  }
654
658
  if (/\bel-(?:menu-item|dropdown-menu__item|select-dropdown__item|tabs__item)\b/.test(classStr)) {
@@ -686,7 +690,8 @@ var GROUP_LABELS = {
686
690
  popover: "[Popover \u6D6E\u5C42]",
687
691
  dropdown: "[Dropdown \u6D6E\u5C42]",
688
692
  tooltip: "[Tooltip \u6D6E\u5C42]",
689
- message: "[Message \u6D6E\u5C42]"
693
+ message: "[Message \u6D6E\u5C42]",
694
+ submenu: "[SubMenu \u6D6E\u5C42]"
690
695
  };
691
696
  var GROUP_SUGGESTIONS = {
692
697
  custom: "\u4E1A\u52A1\u4EE3\u7801\u4E2D\u5B58\u5728\u624B\u5199\u56FA\u5B9A\u91CD\u590D data-testid\uFF0C\u8BF7\u68C0\u67E5\u76F8\u5173\u6A21\u677F\u4EE3\u7801",
@@ -700,7 +705,8 @@ var GROUP_SUGGESTIONS = {
700
705
  popover: "Popover \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548",
701
706
  dropdown: "Dropdown \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548",
702
707
  tooltip: "Tooltip \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548",
703
- message: "Message \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548"
708
+ message: "Message \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548",
709
+ submenu: "SubMenu \u72EC\u7ACB\u8BA1\u6570\u5668\u81EA\u589E\u903B\u8F91\u5931\u6548"
704
710
  };
705
711
  var TestIdChecker = class {
706
712
  /**
@@ -799,7 +805,8 @@ var TestIdChecker = class {
799
805
  "popover",
800
806
  "dropdown",
801
807
  "tooltip",
802
- "message"
808
+ "message",
809
+ "submenu"
803
810
  ];
804
811
  for (const type of popupTypes) {
805
812
  if (prefix === `${type}_`) return type;
@@ -835,9 +842,31 @@ var TestIdChecker = class {
835
842
  console.groupEnd();
836
843
  }
837
844
  };
845
+
846
+ // src/utils/testIdVuePlugin.ts
847
+ var WATCHED_ATTRS = ["data-testid", "data-test-base-key"];
848
+ var TestIdVuePlugin = {
849
+ install(app) {
850
+ app.mixin({
851
+ mounted() {
852
+ const el = this.$el;
853
+ if (!el) return;
854
+ const attrs = this.$attrs || {};
855
+ if (!attrs || typeof attrs !== "object") return;
856
+ for (const attr of WATCHED_ATTRS) {
857
+ const value = attrs[attr];
858
+ if (value != null && !el.hasAttribute(attr)) {
859
+ el.setAttribute(attr, String(value));
860
+ }
861
+ }
862
+ }
863
+ });
864
+ }
865
+ };
838
866
  export {
839
867
  TestIdChecker,
840
868
  TestIdObserver,
869
+ TestIdVuePlugin,
841
870
  antdAdapter,
842
871
  buildAnchorTestId,
843
872
  buildPopupTestId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testid/antd-testid-runtime",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "运行时兜底打标模块 — MutationObserver + 锚点计数器 + 浮层计数器 + ID 重复检测",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -25,8 +25,12 @@
25
25
  "dev": "tsup src/index.ts --dts --format esm,cjs --watch --target es2015"
26
26
  },
27
27
  "dependencies": {},
28
+ "peerDependencies": {
29
+ "vue": "^3.0.0"
30
+ },
28
31
  "devDependencies": {
29
32
  "tsup": "^8.0.0",
30
- "typescript": "^5.3.0"
33
+ "typescript": "^5.3.0",
34
+ "vue": "^3.4.0"
31
35
  }
32
36
  }