@testid/antd-testid-runtime 1.0.1 → 1.0.2
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 +41 -4
- package/dist/index.d.ts +41 -4
- package/dist/index.js +81 -6
- package/dist/index.mjs +81 -6
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -207,6 +207,10 @@ declare class TestIdObserver {
|
|
|
207
207
|
* 更新当前路由 (路由切换时调用)
|
|
208
208
|
*/
|
|
209
209
|
setRoute(routeName: string): void;
|
|
210
|
+
/**
|
|
211
|
+
* 重置浮层子节点计数器 (路由切换时调用)
|
|
212
|
+
*/
|
|
213
|
+
resetPopupChildCounter(): void;
|
|
210
214
|
/**
|
|
211
215
|
* 全量扫描当前 DOM (用于启动时兜底, 处理 Observer 启动前已渲染的节点)
|
|
212
216
|
*/
|
|
@@ -225,8 +229,9 @@ declare class TestIdObserver {
|
|
|
225
229
|
* 决策优先级:
|
|
226
230
|
* 0. 已有 data-testid → 跳过
|
|
227
231
|
* 1. 带 data-test-base-key → 公共组件实例 (锚点定位)
|
|
228
|
-
* 2. body
|
|
229
|
-
* 3.
|
|
232
|
+
* 2. body 直系浮层根节点 → 匹配浮层类型 → 独立前缀
|
|
233
|
+
* 3. 浮层内部子节点 → 查找浮层祖先 → 浮层独立前缀 + 计数器
|
|
234
|
+
* 4. #app 内普通节点 → dynamic
|
|
230
235
|
*/
|
|
231
236
|
private processSingleNode;
|
|
232
237
|
/**
|
|
@@ -254,18 +259,50 @@ declare class TestIdObserver {
|
|
|
254
259
|
*/
|
|
255
260
|
private handlePopupNode;
|
|
256
261
|
/**
|
|
257
|
-
*
|
|
262
|
+
* 检测节点是否为浮层根节点
|
|
263
|
+
*
|
|
264
|
+
* Ant Design Vue 4.x 可能用一层 wrapper DIV 包裹浮层再 append 到 body:
|
|
265
|
+
* body → DIV(wrapper) → DIV.ant-picker-dropdown → panel
|
|
266
|
+
*
|
|
267
|
+
* 因此不要求 parentElement === document.body,
|
|
268
|
+
* 只要节点 class 匹配浮层类型且不在 #app 内即可。
|
|
258
269
|
*
|
|
259
270
|
* @param node - 待检测节点
|
|
260
|
-
* @returns 浮层类型或 null
|
|
271
|
+
* @returns 浮层类型或 null
|
|
261
272
|
*/
|
|
262
273
|
private detectPopupType;
|
|
274
|
+
/**
|
|
275
|
+
* 向上遍历 DOM,检测节点是否在某个浮层内部
|
|
276
|
+
*
|
|
277
|
+
* 查找最近的匹配 POPUP_CLASS_MAP 的祖先元素 (不要求它本身是 body 直系,
|
|
278
|
+
* 因为 Ant Design Vue 4 可能在浮层根节点外包一层 wrapper DIV)。
|
|
279
|
+
* 找到浮层根节点后,继续向上验证其祖先链能到达 body (确保不在 #app 内)。
|
|
280
|
+
*
|
|
281
|
+
* @returns 浮层类型或 null (不在任何浮层内)
|
|
282
|
+
*/
|
|
283
|
+
private detectPopupAncestor;
|
|
284
|
+
/**
|
|
285
|
+
* 验证节点的祖先链是否能到达 document.body
|
|
286
|
+
* (经过若干层 wrapper 后依然是 body 下的浮层)
|
|
287
|
+
*/
|
|
288
|
+
private reachesBody;
|
|
289
|
+
/**
|
|
290
|
+
* 检测节点 class 是否匹配某个浮层类型
|
|
291
|
+
*/
|
|
292
|
+
private matchPopupClass;
|
|
263
293
|
/**
|
|
264
294
|
* 处理页面内动态新增节点 (v-for / 异步 v-if 等)
|
|
265
295
|
*
|
|
266
296
|
* ID 格式: ${runtimePagePrefix}${route}_${tag}_${counter}
|
|
267
297
|
*/
|
|
268
298
|
private handleDynamicNode;
|
|
299
|
+
/**
|
|
300
|
+
* 处理浮层内部子节点 (Modal/Drawer/Dropdown 内的按钮、输入框等)
|
|
301
|
+
*
|
|
302
|
+
* ID 格式: ${popupPrefix}${popupType}_${tag}_${counter}
|
|
303
|
+
* 例: hall_modal_button_0, hall_select_div_2
|
|
304
|
+
*/
|
|
305
|
+
private handlePopupChildNode;
|
|
269
306
|
/**
|
|
270
307
|
* 检测元素是否在 #app 容器内
|
|
271
308
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -207,6 +207,10 @@ declare class TestIdObserver {
|
|
|
207
207
|
* 更新当前路由 (路由切换时调用)
|
|
208
208
|
*/
|
|
209
209
|
setRoute(routeName: string): void;
|
|
210
|
+
/**
|
|
211
|
+
* 重置浮层子节点计数器 (路由切换时调用)
|
|
212
|
+
*/
|
|
213
|
+
resetPopupChildCounter(): void;
|
|
210
214
|
/**
|
|
211
215
|
* 全量扫描当前 DOM (用于启动时兜底, 处理 Observer 启动前已渲染的节点)
|
|
212
216
|
*/
|
|
@@ -225,8 +229,9 @@ declare class TestIdObserver {
|
|
|
225
229
|
* 决策优先级:
|
|
226
230
|
* 0. 已有 data-testid → 跳过
|
|
227
231
|
* 1. 带 data-test-base-key → 公共组件实例 (锚点定位)
|
|
228
|
-
* 2. body
|
|
229
|
-
* 3.
|
|
232
|
+
* 2. body 直系浮层根节点 → 匹配浮层类型 → 独立前缀
|
|
233
|
+
* 3. 浮层内部子节点 → 查找浮层祖先 → 浮层独立前缀 + 计数器
|
|
234
|
+
* 4. #app 内普通节点 → dynamic
|
|
230
235
|
*/
|
|
231
236
|
private processSingleNode;
|
|
232
237
|
/**
|
|
@@ -254,18 +259,50 @@ declare class TestIdObserver {
|
|
|
254
259
|
*/
|
|
255
260
|
private handlePopupNode;
|
|
256
261
|
/**
|
|
257
|
-
*
|
|
262
|
+
* 检测节点是否为浮层根节点
|
|
263
|
+
*
|
|
264
|
+
* Ant Design Vue 4.x 可能用一层 wrapper DIV 包裹浮层再 append 到 body:
|
|
265
|
+
* body → DIV(wrapper) → DIV.ant-picker-dropdown → panel
|
|
266
|
+
*
|
|
267
|
+
* 因此不要求 parentElement === document.body,
|
|
268
|
+
* 只要节点 class 匹配浮层类型且不在 #app 内即可。
|
|
258
269
|
*
|
|
259
270
|
* @param node - 待检测节点
|
|
260
|
-
* @returns 浮层类型或 null
|
|
271
|
+
* @returns 浮层类型或 null
|
|
261
272
|
*/
|
|
262
273
|
private detectPopupType;
|
|
274
|
+
/**
|
|
275
|
+
* 向上遍历 DOM,检测节点是否在某个浮层内部
|
|
276
|
+
*
|
|
277
|
+
* 查找最近的匹配 POPUP_CLASS_MAP 的祖先元素 (不要求它本身是 body 直系,
|
|
278
|
+
* 因为 Ant Design Vue 4 可能在浮层根节点外包一层 wrapper DIV)。
|
|
279
|
+
* 找到浮层根节点后,继续向上验证其祖先链能到达 body (确保不在 #app 内)。
|
|
280
|
+
*
|
|
281
|
+
* @returns 浮层类型或 null (不在任何浮层内)
|
|
282
|
+
*/
|
|
283
|
+
private detectPopupAncestor;
|
|
284
|
+
/**
|
|
285
|
+
* 验证节点的祖先链是否能到达 document.body
|
|
286
|
+
* (经过若干层 wrapper 后依然是 body 下的浮层)
|
|
287
|
+
*/
|
|
288
|
+
private reachesBody;
|
|
289
|
+
/**
|
|
290
|
+
* 检测节点 class 是否匹配某个浮层类型
|
|
291
|
+
*/
|
|
292
|
+
private matchPopupClass;
|
|
263
293
|
/**
|
|
264
294
|
* 处理页面内动态新增节点 (v-for / 异步 v-if 等)
|
|
265
295
|
*
|
|
266
296
|
* ID 格式: ${runtimePagePrefix}${route}_${tag}_${counter}
|
|
267
297
|
*/
|
|
268
298
|
private handleDynamicNode;
|
|
299
|
+
/**
|
|
300
|
+
* 处理浮层内部子节点 (Modal/Drawer/Dropdown 内的按钮、输入框等)
|
|
301
|
+
*
|
|
302
|
+
* ID 格式: ${popupPrefix}${popupType}_${tag}_${counter}
|
|
303
|
+
* 例: hall_modal_button_0, hall_select_div_2
|
|
304
|
+
*/
|
|
305
|
+
private handlePopupChildNode;
|
|
269
306
|
/**
|
|
270
307
|
* 检测元素是否在 #app 容器内
|
|
271
308
|
*/
|
package/dist/index.js
CHANGED
|
@@ -212,7 +212,8 @@ var TestIdObserver = class {
|
|
|
212
212
|
observer: null,
|
|
213
213
|
isRunning: false,
|
|
214
214
|
currentRoute: "",
|
|
215
|
-
dynamicCounter: /* @__PURE__ */ new Map()
|
|
215
|
+
dynamicCounter: /* @__PURE__ */ new Map(),
|
|
216
|
+
popupChildCounter: /* @__PURE__ */ new Map()
|
|
216
217
|
};
|
|
217
218
|
}
|
|
218
219
|
// ==========================================================
|
|
@@ -249,6 +250,12 @@ var TestIdObserver = class {
|
|
|
249
250
|
setRoute(routeName) {
|
|
250
251
|
this.state.currentRoute = routeName;
|
|
251
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* 重置浮层子节点计数器 (路由切换时调用)
|
|
255
|
+
*/
|
|
256
|
+
resetPopupChildCounter() {
|
|
257
|
+
this.state.popupChildCounter.clear();
|
|
258
|
+
}
|
|
252
259
|
/**
|
|
253
260
|
* 全量扫描当前 DOM (用于启动时兜底, 处理 Observer 启动前已渲染的节点)
|
|
254
261
|
*/
|
|
@@ -286,8 +293,9 @@ var TestIdObserver = class {
|
|
|
286
293
|
* 决策优先级:
|
|
287
294
|
* 0. 已有 data-testid → 跳过
|
|
288
295
|
* 1. 带 data-test-base-key → 公共组件实例 (锚点定位)
|
|
289
|
-
* 2. body
|
|
290
|
-
* 3.
|
|
296
|
+
* 2. body 直系浮层根节点 → 匹配浮层类型 → 独立前缀
|
|
297
|
+
* 3. 浮层内部子节点 → 查找浮层祖先 → 浮层独立前缀 + 计数器
|
|
298
|
+
* 4. #app 内普通节点 → dynamic
|
|
291
299
|
*/
|
|
292
300
|
processSingleNode(node) {
|
|
293
301
|
const config = getConfig();
|
|
@@ -303,6 +311,11 @@ var TestIdObserver = class {
|
|
|
303
311
|
this.handlePopupNode(node, popupType);
|
|
304
312
|
return;
|
|
305
313
|
}
|
|
314
|
+
const popupAncestorType = this.detectPopupAncestor(node);
|
|
315
|
+
if (popupAncestorType) {
|
|
316
|
+
this.handlePopupChildNode(node, popupAncestorType, config);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
306
319
|
if (this.isInsideApp(node)) {
|
|
307
320
|
this.handleDynamicNode(node, config);
|
|
308
321
|
}
|
|
@@ -373,13 +386,59 @@ var TestIdObserver = class {
|
|
|
373
386
|
node.setAttribute("data-testid", testId);
|
|
374
387
|
}
|
|
375
388
|
/**
|
|
376
|
-
*
|
|
389
|
+
* 检测节点是否为浮层根节点
|
|
390
|
+
*
|
|
391
|
+
* Ant Design Vue 4.x 可能用一层 wrapper DIV 包裹浮层再 append 到 body:
|
|
392
|
+
* body → DIV(wrapper) → DIV.ant-picker-dropdown → panel
|
|
393
|
+
*
|
|
394
|
+
* 因此不要求 parentElement === document.body,
|
|
395
|
+
* 只要节点 class 匹配浮层类型且不在 #app 内即可。
|
|
377
396
|
*
|
|
378
397
|
* @param node - 待检测节点
|
|
379
|
-
* @returns 浮层类型或 null
|
|
398
|
+
* @returns 浮层类型或 null
|
|
380
399
|
*/
|
|
381
400
|
detectPopupType(node) {
|
|
382
|
-
if (node
|
|
401
|
+
if (this.isInsideApp(node)) return null;
|
|
402
|
+
return this.matchPopupClass(node);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* 向上遍历 DOM,检测节点是否在某个浮层内部
|
|
406
|
+
*
|
|
407
|
+
* 查找最近的匹配 POPUP_CLASS_MAP 的祖先元素 (不要求它本身是 body 直系,
|
|
408
|
+
* 因为 Ant Design Vue 4 可能在浮层根节点外包一层 wrapper DIV)。
|
|
409
|
+
* 找到浮层根节点后,继续向上验证其祖先链能到达 body (确保不在 #app 内)。
|
|
410
|
+
*
|
|
411
|
+
* @returns 浮层类型或 null (不在任何浮层内)
|
|
412
|
+
*/
|
|
413
|
+
detectPopupAncestor(node) {
|
|
414
|
+
let current = node.parentElement;
|
|
415
|
+
while (current) {
|
|
416
|
+
const type = this.matchPopupClass(current);
|
|
417
|
+
if (type) {
|
|
418
|
+
const reachesBody = this.reachesBody(current);
|
|
419
|
+
if (reachesBody) return type;
|
|
420
|
+
}
|
|
421
|
+
if (current === document.body || current.id === "app") break;
|
|
422
|
+
current = current.parentElement;
|
|
423
|
+
}
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* 验证节点的祖先链是否能到达 document.body
|
|
428
|
+
* (经过若干层 wrapper 后依然是 body 下的浮层)
|
|
429
|
+
*/
|
|
430
|
+
reachesBody(node) {
|
|
431
|
+
let current = node;
|
|
432
|
+
while (current && current !== document.body) {
|
|
433
|
+
if (current.id === "app") return false;
|
|
434
|
+
current = current.parentElement;
|
|
435
|
+
}
|
|
436
|
+
return current === document.body;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* 检测节点 class 是否匹配某个浮层类型
|
|
440
|
+
*/
|
|
441
|
+
matchPopupClass(node) {
|
|
383
442
|
const classStr = node.className || "";
|
|
384
443
|
if (typeof classStr !== "string") return null;
|
|
385
444
|
const entries = Object.entries(POPUP_CLASS_MAP);
|
|
@@ -412,6 +471,22 @@ var TestIdObserver = class {
|
|
|
412
471
|
const testId = `${config.runtimePagePrefix}${route}_${tag}_${current}`;
|
|
413
472
|
node.setAttribute("data-testid", testId);
|
|
414
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* 处理浮层内部子节点 (Modal/Drawer/Dropdown 内的按钮、输入框等)
|
|
476
|
+
*
|
|
477
|
+
* ID 格式: ${popupPrefix}${popupType}_${tag}_${counter}
|
|
478
|
+
* 例: hall_modal_button_0, hall_select_div_2
|
|
479
|
+
*/
|
|
480
|
+
handlePopupChildNode(node, popupType, config) {
|
|
481
|
+
if (config.onlyInteractive && !this.isInteractive(node)) return;
|
|
482
|
+
const tag = this.getSimpleTag(node);
|
|
483
|
+
const key = `${popupType}_${tag}`;
|
|
484
|
+
const current = this.state.popupChildCounter.get(key) ?? 0;
|
|
485
|
+
this.state.popupChildCounter.set(key, current + 1);
|
|
486
|
+
const prefix = config.popupPrefixMap[popupType] || `${popupType}_`;
|
|
487
|
+
const testId = `${prefix}${tag}_${current}`;
|
|
488
|
+
node.setAttribute("data-testid", testId);
|
|
489
|
+
}
|
|
415
490
|
// ==========================================================
|
|
416
491
|
// 辅助方法
|
|
417
492
|
// ==========================================================
|
package/dist/index.mjs
CHANGED
|
@@ -170,7 +170,8 @@ var TestIdObserver = class {
|
|
|
170
170
|
observer: null,
|
|
171
171
|
isRunning: false,
|
|
172
172
|
currentRoute: "",
|
|
173
|
-
dynamicCounter: /* @__PURE__ */ new Map()
|
|
173
|
+
dynamicCounter: /* @__PURE__ */ new Map(),
|
|
174
|
+
popupChildCounter: /* @__PURE__ */ new Map()
|
|
174
175
|
};
|
|
175
176
|
}
|
|
176
177
|
// ==========================================================
|
|
@@ -207,6 +208,12 @@ var TestIdObserver = class {
|
|
|
207
208
|
setRoute(routeName) {
|
|
208
209
|
this.state.currentRoute = routeName;
|
|
209
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* 重置浮层子节点计数器 (路由切换时调用)
|
|
213
|
+
*/
|
|
214
|
+
resetPopupChildCounter() {
|
|
215
|
+
this.state.popupChildCounter.clear();
|
|
216
|
+
}
|
|
210
217
|
/**
|
|
211
218
|
* 全量扫描当前 DOM (用于启动时兜底, 处理 Observer 启动前已渲染的节点)
|
|
212
219
|
*/
|
|
@@ -244,8 +251,9 @@ var TestIdObserver = class {
|
|
|
244
251
|
* 决策优先级:
|
|
245
252
|
* 0. 已有 data-testid → 跳过
|
|
246
253
|
* 1. 带 data-test-base-key → 公共组件实例 (锚点定位)
|
|
247
|
-
* 2. body
|
|
248
|
-
* 3.
|
|
254
|
+
* 2. body 直系浮层根节点 → 匹配浮层类型 → 独立前缀
|
|
255
|
+
* 3. 浮层内部子节点 → 查找浮层祖先 → 浮层独立前缀 + 计数器
|
|
256
|
+
* 4. #app 内普通节点 → dynamic
|
|
249
257
|
*/
|
|
250
258
|
processSingleNode(node) {
|
|
251
259
|
const config = getConfig();
|
|
@@ -261,6 +269,11 @@ var TestIdObserver = class {
|
|
|
261
269
|
this.handlePopupNode(node, popupType);
|
|
262
270
|
return;
|
|
263
271
|
}
|
|
272
|
+
const popupAncestorType = this.detectPopupAncestor(node);
|
|
273
|
+
if (popupAncestorType) {
|
|
274
|
+
this.handlePopupChildNode(node, popupAncestorType, config);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
264
277
|
if (this.isInsideApp(node)) {
|
|
265
278
|
this.handleDynamicNode(node, config);
|
|
266
279
|
}
|
|
@@ -331,13 +344,59 @@ var TestIdObserver = class {
|
|
|
331
344
|
node.setAttribute("data-testid", testId);
|
|
332
345
|
}
|
|
333
346
|
/**
|
|
334
|
-
*
|
|
347
|
+
* 检测节点是否为浮层根节点
|
|
348
|
+
*
|
|
349
|
+
* Ant Design Vue 4.x 可能用一层 wrapper DIV 包裹浮层再 append 到 body:
|
|
350
|
+
* body → DIV(wrapper) → DIV.ant-picker-dropdown → panel
|
|
351
|
+
*
|
|
352
|
+
* 因此不要求 parentElement === document.body,
|
|
353
|
+
* 只要节点 class 匹配浮层类型且不在 #app 内即可。
|
|
335
354
|
*
|
|
336
355
|
* @param node - 待检测节点
|
|
337
|
-
* @returns 浮层类型或 null
|
|
356
|
+
* @returns 浮层类型或 null
|
|
338
357
|
*/
|
|
339
358
|
detectPopupType(node) {
|
|
340
|
-
if (node
|
|
359
|
+
if (this.isInsideApp(node)) return null;
|
|
360
|
+
return this.matchPopupClass(node);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* 向上遍历 DOM,检测节点是否在某个浮层内部
|
|
364
|
+
*
|
|
365
|
+
* 查找最近的匹配 POPUP_CLASS_MAP 的祖先元素 (不要求它本身是 body 直系,
|
|
366
|
+
* 因为 Ant Design Vue 4 可能在浮层根节点外包一层 wrapper DIV)。
|
|
367
|
+
* 找到浮层根节点后,继续向上验证其祖先链能到达 body (确保不在 #app 内)。
|
|
368
|
+
*
|
|
369
|
+
* @returns 浮层类型或 null (不在任何浮层内)
|
|
370
|
+
*/
|
|
371
|
+
detectPopupAncestor(node) {
|
|
372
|
+
let current = node.parentElement;
|
|
373
|
+
while (current) {
|
|
374
|
+
const type = this.matchPopupClass(current);
|
|
375
|
+
if (type) {
|
|
376
|
+
const reachesBody = this.reachesBody(current);
|
|
377
|
+
if (reachesBody) return type;
|
|
378
|
+
}
|
|
379
|
+
if (current === document.body || current.id === "app") break;
|
|
380
|
+
current = current.parentElement;
|
|
381
|
+
}
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* 验证节点的祖先链是否能到达 document.body
|
|
386
|
+
* (经过若干层 wrapper 后依然是 body 下的浮层)
|
|
387
|
+
*/
|
|
388
|
+
reachesBody(node) {
|
|
389
|
+
let current = node;
|
|
390
|
+
while (current && current !== document.body) {
|
|
391
|
+
if (current.id === "app") return false;
|
|
392
|
+
current = current.parentElement;
|
|
393
|
+
}
|
|
394
|
+
return current === document.body;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* 检测节点 class 是否匹配某个浮层类型
|
|
398
|
+
*/
|
|
399
|
+
matchPopupClass(node) {
|
|
341
400
|
const classStr = node.className || "";
|
|
342
401
|
if (typeof classStr !== "string") return null;
|
|
343
402
|
const entries = Object.entries(POPUP_CLASS_MAP);
|
|
@@ -370,6 +429,22 @@ var TestIdObserver = class {
|
|
|
370
429
|
const testId = `${config.runtimePagePrefix}${route}_${tag}_${current}`;
|
|
371
430
|
node.setAttribute("data-testid", testId);
|
|
372
431
|
}
|
|
432
|
+
/**
|
|
433
|
+
* 处理浮层内部子节点 (Modal/Drawer/Dropdown 内的按钮、输入框等)
|
|
434
|
+
*
|
|
435
|
+
* ID 格式: ${popupPrefix}${popupType}_${tag}_${counter}
|
|
436
|
+
* 例: hall_modal_button_0, hall_select_div_2
|
|
437
|
+
*/
|
|
438
|
+
handlePopupChildNode(node, popupType, config) {
|
|
439
|
+
if (config.onlyInteractive && !this.isInteractive(node)) return;
|
|
440
|
+
const tag = this.getSimpleTag(node);
|
|
441
|
+
const key = `${popupType}_${tag}`;
|
|
442
|
+
const current = this.state.popupChildCounter.get(key) ?? 0;
|
|
443
|
+
this.state.popupChildCounter.set(key, current + 1);
|
|
444
|
+
const prefix = config.popupPrefixMap[popupType] || `${popupType}_`;
|
|
445
|
+
const testId = `${prefix}${tag}_${current}`;
|
|
446
|
+
node.setAttribute("data-testid", testId);
|
|
447
|
+
}
|
|
373
448
|
// ==========================================================
|
|
374
449
|
// 辅助方法
|
|
375
450
|
// ==========================================================
|