@testid/antd-testid-runtime 1.0.3 → 1.0.5

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
@@ -33,10 +33,12 @@ interface TestIdMarkConfig {
33
33
  /**
34
34
  * Ant Design Vue CSS 类名前缀 (对应 ConfigProvider 的 prefixCls)
35
35
  *
36
- * 默认: 'ant' → 匹配 .ant-modal, .ant-picker-dropdown 等
37
- * 若项目使用 <a-config-provider prefixCls="my-ui"> 则设为 'my-ui'
36
+ * 支持数组,可同时匹配多个前缀体系:
37
+ * 默认: ['ant'] → 匹配 .ant-modal, .ant-picker-dropdown
38
+ * 若项目使用 <a-config-provider prefixCls="my-ui"> 则设为 ['my-ui']
39
+ * 混合使用: ['ant', 'my-ui'] → 同时匹配两个体系的所有浮层组件
38
40
  */
39
- antdClassPrefix: string;
41
+ antdClassPrefix: string[];
40
42
  /** 忽略不打标的 HTML 标签名 */
41
43
  ignoreTags: string[];
42
44
  /** 包含此 class 的 DOM 跳过打标 */
@@ -176,11 +178,13 @@ declare function resetPopupCounter(type: PopupType): void;
176
178
  */
177
179
  declare function getPopupCounterSnapshot(): Record<PopupType, number>;
178
180
  /**
179
- * 生成浮层节点 testid
181
+ * 生成浮层根节点 testid
180
182
  *
181
- * 格式: ${prefix}${tag}_${counterId}
183
+ * 格式: ${runtimePagePrefix}${popupPrefix}${tag}_${counterId}
184
+ * 例: hall_dynamic_modal_div_0, hall_dynamic_select_div_2
182
185
  *
183
- * 例: modal_button_0, select_div_2
186
+ * 浮层均为运行时注入,因此统一使用 runtimePagePrefix 作为前缀,
187
+ * 与页面内动态节点保持一致。
184
188
  *
185
189
  * @param type - 浮层类型
186
190
  * @param tag - HTML 标签名 (简化后)
@@ -297,6 +301,8 @@ declare class TestIdObserver {
297
301
  private reachesBody;
298
302
  /**
299
303
  * 检测节点 class 是否匹配某个浮层类型
304
+ *
305
+ * 遍历 popupClassMap 中的所有 class 组合,任一组合全部命中即匹配。
300
306
  */
301
307
  private matchPopupClass;
302
308
  /**
@@ -308,8 +314,10 @@ declare class TestIdObserver {
308
314
  /**
309
315
  * 处理浮层内部子节点 (Modal/Drawer/Dropdown 内的按钮、输入框等)
310
316
  *
311
- * ID 格式: ${popupPrefix}${popupType}_${tag}_${counter}
312
- * 例: hall_modal_button_0, hall_select_div_2
317
+ * ID 格式: ${runtimePagePrefix}${popupPrefix}${tag}_${counter}
318
+ * 例: hall_dynamic_modal_button_0, hall_dynamic_select_div_2
319
+ *
320
+ * 浮层子元素均为运行时注入,统一使用 runtimePagePrefix 前缀。
313
321
  */
314
322
  private handlePopupChildNode;
315
323
  /**
package/dist/index.d.ts CHANGED
@@ -33,10 +33,12 @@ interface TestIdMarkConfig {
33
33
  /**
34
34
  * Ant Design Vue CSS 类名前缀 (对应 ConfigProvider 的 prefixCls)
35
35
  *
36
- * 默认: 'ant' → 匹配 .ant-modal, .ant-picker-dropdown 等
37
- * 若项目使用 <a-config-provider prefixCls="my-ui"> 则设为 'my-ui'
36
+ * 支持数组,可同时匹配多个前缀体系:
37
+ * 默认: ['ant'] → 匹配 .ant-modal, .ant-picker-dropdown
38
+ * 若项目使用 <a-config-provider prefixCls="my-ui"> 则设为 ['my-ui']
39
+ * 混合使用: ['ant', 'my-ui'] → 同时匹配两个体系的所有浮层组件
38
40
  */
39
- antdClassPrefix: string;
41
+ antdClassPrefix: string[];
40
42
  /** 忽略不打标的 HTML 标签名 */
41
43
  ignoreTags: string[];
42
44
  /** 包含此 class 的 DOM 跳过打标 */
@@ -176,11 +178,13 @@ declare function resetPopupCounter(type: PopupType): void;
176
178
  */
177
179
  declare function getPopupCounterSnapshot(): Record<PopupType, number>;
178
180
  /**
179
- * 生成浮层节点 testid
181
+ * 生成浮层根节点 testid
180
182
  *
181
- * 格式: ${prefix}${tag}_${counterId}
183
+ * 格式: ${runtimePagePrefix}${popupPrefix}${tag}_${counterId}
184
+ * 例: hall_dynamic_modal_div_0, hall_dynamic_select_div_2
182
185
  *
183
- * 例: modal_button_0, select_div_2
186
+ * 浮层均为运行时注入,因此统一使用 runtimePagePrefix 作为前缀,
187
+ * 与页面内动态节点保持一致。
184
188
  *
185
189
  * @param type - 浮层类型
186
190
  * @param tag - HTML 标签名 (简化后)
@@ -297,6 +301,8 @@ declare class TestIdObserver {
297
301
  private reachesBody;
298
302
  /**
299
303
  * 检测节点 class 是否匹配某个浮层类型
304
+ *
305
+ * 遍历 popupClassMap 中的所有 class 组合,任一组合全部命中即匹配。
300
306
  */
301
307
  private matchPopupClass;
302
308
  /**
@@ -308,8 +314,10 @@ declare class TestIdObserver {
308
314
  /**
309
315
  * 处理浮层内部子节点 (Modal/Drawer/Dropdown 内的按钮、输入框等)
310
316
  *
311
- * ID 格式: ${popupPrefix}${popupType}_${tag}_${counter}
312
- * 例: hall_modal_button_0, hall_select_div_2
317
+ * ID 格式: ${runtimePagePrefix}${popupPrefix}${tag}_${counter}
318
+ * 例: hall_dynamic_modal_button_0, hall_dynamic_select_div_2
319
+ *
320
+ * 浮层子元素均为运行时注入,统一使用 runtimePagePrefix 前缀。
313
321
  */
314
322
  private handlePopupChildNode;
315
323
  /**
package/dist/index.js CHANGED
@@ -60,7 +60,7 @@ var defaultConfig = {
60
60
  globalPrefix: "",
61
61
  compilePrefix: "static_",
62
62
  runtimePagePrefix: "dynamic_",
63
- antdClassPrefix: "ant",
63
+ antdClassPrefix: ["ant"],
64
64
  popupPrefixMap: {
65
65
  modal: "modal_",
66
66
  drawer: "drawer_",
@@ -101,9 +101,10 @@ function applyGlobalPrefix(cfg) {
101
101
  ...cfg,
102
102
  compilePrefix: prepend(cfg.compilePrefix),
103
103
  runtimePagePrefix: prepend(cfg.runtimePagePrefix),
104
- popupPrefixMap: Object.fromEntries(
105
- Object.entries(cfg.popupPrefixMap).map(([k, v]) => [k, prepend(v)])
106
- )
104
+ // 注意: popupPrefixMap 不拼接 globalPrefix
105
+ // 浮层 testid 格式为 ${runtimePagePrefix}${popupPrefixMap[type]}...,
106
+ // runtimePagePrefix 已携带 globalPrefix,避免重复
107
+ popupPrefixMap: { ...cfg.popupPrefixMap }
107
108
  };
108
109
  }
109
110
  var globalConfig = { ...defaultConfig };
@@ -177,25 +178,27 @@ function getPopupCounterSnapshot() {
177
178
  }
178
179
  function buildPopupTestId(type, tag, counterId) {
179
180
  const config = getConfig();
180
- const prefix = config.popupPrefixMap[type] || `${type}_`;
181
- return `${prefix}${tag}_${counterId}`;
181
+ const popupPrefix = config.popupPrefixMap[type] || `${type}_`;
182
+ return `${config.runtimePagePrefix}${popupPrefix}${tag}_${counterId}`;
182
183
  }
183
184
 
184
185
  // src/utils/testIdObserver.ts
185
186
  var POPUP_CLASS_SUFFIX_MAP = {
186
- modal: ".{prefix}-modal",
187
- drawer: ".{prefix}-drawer",
188
- select: ".{prefix}-select-dropdown",
189
- datePicker: ".{prefix}-picker-dropdown",
190
- popconfirm: ".{prefix}-popover.{prefix}-popconfirm",
191
- dropdown: ".{prefix}-dropdown",
192
- tooltip: ".{prefix}-tooltip"
187
+ modal: ["-modal"],
188
+ drawer: ["-drawer"],
189
+ select: ["-select-dropdown"],
190
+ datePicker: ["-picker-dropdown"],
191
+ popconfirm: ["-popover", "-popconfirm"],
192
+ dropdown: ["-dropdown"],
193
+ tooltip: ["-tooltip"]
193
194
  };
194
- function buildPopupClassMap(prefix) {
195
+ function buildPopupClassMap(prefixes) {
195
196
  const result = {};
196
197
  const entries = Object.entries(POPUP_CLASS_SUFFIX_MAP);
197
- for (const [type, template] of entries) {
198
- result[type] = template.replace(/\{prefix\}/g, prefix);
198
+ for (const [type, suffixClasses] of entries) {
199
+ result[type] = prefixes.map(
200
+ (prefix) => suffixClasses.map((suffix) => `${prefix}${suffix}`)
201
+ );
199
202
  }
200
203
  return result;
201
204
  }
@@ -448,18 +451,19 @@ var TestIdObserver = class {
448
451
  }
449
452
  /**
450
453
  * 检测节点 class 是否匹配某个浮层类型
454
+ *
455
+ * 遍历 popupClassMap 中的所有 class 组合,任一组合全部命中即匹配。
451
456
  */
452
457
  matchPopupClass(node) {
453
458
  const classStr = node.className || "";
454
459
  if (typeof classStr !== "string") return null;
460
+ const classList = classStr.split(/\s+/);
455
461
  const entries = Object.entries(this.popupClassMap);
456
- for (const [type, selector] of entries) {
457
- const classes = selector.replace(/^\./, "").split(".");
458
- const allMatch = classes.every(
459
- (cls) => classStr.split(/\s+/).includes(cls)
460
- );
461
- if (allMatch) {
462
- return type;
462
+ for (const [type, selectorSets] of entries) {
463
+ for (const requiredClasses of selectorSets) {
464
+ if (requiredClasses.every((cls) => classList.includes(cls))) {
465
+ return type;
466
+ }
463
467
  }
464
468
  }
465
469
  return null;
@@ -485,8 +489,10 @@ var TestIdObserver = class {
485
489
  /**
486
490
  * 处理浮层内部子节点 (Modal/Drawer/Dropdown 内的按钮、输入框等)
487
491
  *
488
- * ID 格式: ${popupPrefix}${popupType}_${tag}_${counter}
489
- * 例: hall_modal_button_0, hall_select_div_2
492
+ * ID 格式: ${runtimePagePrefix}${popupPrefix}${tag}_${counter}
493
+ * 例: hall_dynamic_modal_button_0, hall_dynamic_select_div_2
494
+ *
495
+ * 浮层子元素均为运行时注入,统一使用 runtimePagePrefix 前缀。
490
496
  */
491
497
  handlePopupChildNode(node, popupType, config) {
492
498
  if (config.onlyInteractive && !this.isInteractive(node)) return;
@@ -494,8 +500,8 @@ var TestIdObserver = class {
494
500
  const key = `${popupType}_${tag}`;
495
501
  const current = this.state.popupChildCounter.get(key) ?? 0;
496
502
  this.state.popupChildCounter.set(key, current + 1);
497
- const prefix = config.popupPrefixMap[popupType] || `${popupType}_`;
498
- const testId = `${prefix}${tag}_${current}`;
503
+ const popupPrefix = config.popupPrefixMap[popupType] || `${popupType}_`;
504
+ const testId = `${config.runtimePagePrefix}${popupPrefix}${tag}_${current}`;
499
505
  node.setAttribute("data-testid", testId);
500
506
  }
501
507
  // ==========================================================
package/dist/index.mjs CHANGED
@@ -18,7 +18,7 @@ var defaultConfig = {
18
18
  globalPrefix: "",
19
19
  compilePrefix: "static_",
20
20
  runtimePagePrefix: "dynamic_",
21
- antdClassPrefix: "ant",
21
+ antdClassPrefix: ["ant"],
22
22
  popupPrefixMap: {
23
23
  modal: "modal_",
24
24
  drawer: "drawer_",
@@ -59,9 +59,10 @@ function applyGlobalPrefix(cfg) {
59
59
  ...cfg,
60
60
  compilePrefix: prepend(cfg.compilePrefix),
61
61
  runtimePagePrefix: prepend(cfg.runtimePagePrefix),
62
- popupPrefixMap: Object.fromEntries(
63
- Object.entries(cfg.popupPrefixMap).map(([k, v]) => [k, prepend(v)])
64
- )
62
+ // 注意: popupPrefixMap 不拼接 globalPrefix
63
+ // 浮层 testid 格式为 ${runtimePagePrefix}${popupPrefixMap[type]}...,
64
+ // runtimePagePrefix 已携带 globalPrefix,避免重复
65
+ popupPrefixMap: { ...cfg.popupPrefixMap }
65
66
  };
66
67
  }
67
68
  var globalConfig = { ...defaultConfig };
@@ -135,25 +136,27 @@ function getPopupCounterSnapshot() {
135
136
  }
136
137
  function buildPopupTestId(type, tag, counterId) {
137
138
  const config = getConfig();
138
- const prefix = config.popupPrefixMap[type] || `${type}_`;
139
- return `${prefix}${tag}_${counterId}`;
139
+ const popupPrefix = config.popupPrefixMap[type] || `${type}_`;
140
+ return `${config.runtimePagePrefix}${popupPrefix}${tag}_${counterId}`;
140
141
  }
141
142
 
142
143
  // src/utils/testIdObserver.ts
143
144
  var POPUP_CLASS_SUFFIX_MAP = {
144
- modal: ".{prefix}-modal",
145
- drawer: ".{prefix}-drawer",
146
- select: ".{prefix}-select-dropdown",
147
- datePicker: ".{prefix}-picker-dropdown",
148
- popconfirm: ".{prefix}-popover.{prefix}-popconfirm",
149
- dropdown: ".{prefix}-dropdown",
150
- tooltip: ".{prefix}-tooltip"
145
+ modal: ["-modal"],
146
+ drawer: ["-drawer"],
147
+ select: ["-select-dropdown"],
148
+ datePicker: ["-picker-dropdown"],
149
+ popconfirm: ["-popover", "-popconfirm"],
150
+ dropdown: ["-dropdown"],
151
+ tooltip: ["-tooltip"]
151
152
  };
152
- function buildPopupClassMap(prefix) {
153
+ function buildPopupClassMap(prefixes) {
153
154
  const result = {};
154
155
  const entries = Object.entries(POPUP_CLASS_SUFFIX_MAP);
155
- for (const [type, template] of entries) {
156
- result[type] = template.replace(/\{prefix\}/g, prefix);
156
+ for (const [type, suffixClasses] of entries) {
157
+ result[type] = prefixes.map(
158
+ (prefix) => suffixClasses.map((suffix) => `${prefix}${suffix}`)
159
+ );
157
160
  }
158
161
  return result;
159
162
  }
@@ -406,18 +409,19 @@ var TestIdObserver = class {
406
409
  }
407
410
  /**
408
411
  * 检测节点 class 是否匹配某个浮层类型
412
+ *
413
+ * 遍历 popupClassMap 中的所有 class 组合,任一组合全部命中即匹配。
409
414
  */
410
415
  matchPopupClass(node) {
411
416
  const classStr = node.className || "";
412
417
  if (typeof classStr !== "string") return null;
418
+ const classList = classStr.split(/\s+/);
413
419
  const entries = Object.entries(this.popupClassMap);
414
- for (const [type, selector] of entries) {
415
- const classes = selector.replace(/^\./, "").split(".");
416
- const allMatch = classes.every(
417
- (cls) => classStr.split(/\s+/).includes(cls)
418
- );
419
- if (allMatch) {
420
- return type;
420
+ for (const [type, selectorSets] of entries) {
421
+ for (const requiredClasses of selectorSets) {
422
+ if (requiredClasses.every((cls) => classList.includes(cls))) {
423
+ return type;
424
+ }
421
425
  }
422
426
  }
423
427
  return null;
@@ -443,8 +447,10 @@ var TestIdObserver = class {
443
447
  /**
444
448
  * 处理浮层内部子节点 (Modal/Drawer/Dropdown 内的按钮、输入框等)
445
449
  *
446
- * ID 格式: ${popupPrefix}${popupType}_${tag}_${counter}
447
- * 例: hall_modal_button_0, hall_select_div_2
450
+ * ID 格式: ${runtimePagePrefix}${popupPrefix}${tag}_${counter}
451
+ * 例: hall_dynamic_modal_button_0, hall_dynamic_select_div_2
452
+ *
453
+ * 浮层子元素均为运行时注入,统一使用 runtimePagePrefix 前缀。
448
454
  */
449
455
  handlePopupChildNode(node, popupType, config) {
450
456
  if (config.onlyInteractive && !this.isInteractive(node)) return;
@@ -452,8 +458,8 @@ var TestIdObserver = class {
452
458
  const key = `${popupType}_${tag}`;
453
459
  const current = this.state.popupChildCounter.get(key) ?? 0;
454
460
  this.state.popupChildCounter.set(key, current + 1);
455
- const prefix = config.popupPrefixMap[popupType] || `${popupType}_`;
456
- const testId = `${prefix}${tag}_${current}`;
461
+ const popupPrefix = config.popupPrefixMap[popupType] || `${popupType}_`;
462
+ const testId = `${config.runtimePagePrefix}${popupPrefix}${tag}_${current}`;
457
463
  node.setAttribute("data-testid", testId);
458
464
  }
459
465
  // ==========================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testid/antd-testid-runtime",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "运行时兜底打标模块 — MutationObserver + 锚点计数器 + 浮层计数器 + ID 重复检测",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",