我正在开发一个有数千个 html 文件的 Angular 项目。现在我们正在尝试使用cypress 来实现UI 测试自动化。然而,我们在唯一标识 cypress 中的 UI 元素方面面临一些困难。将 data-testid 添加到所有 UI 元素将解决此问题。但手动将 data-testid 添加到所有 UI 元素将是一项耗时的任务。
我正在寻找一种解决方案,通过组合 context_name_element_id 来自动向所有 UI 元素添加唯一的 data-testid。
如有任何帮助,我们将不胜感激。
期望有一个简单的解决方案来自动将 data-testid 自动添加到 Angular 应用程序中的所有 UI 元素。
要自动向所有 UI 元素添加 data-testid 属性而无需手动编辑每个元素,您可以使用适用于所有元素的自定义 Angular 指令。但是,您可以修改指令以在 Angular 应用程序的引导过程中全局应用到所有元素,而不是将指令添加到每个元素。
以下是如何实现这一点的高级方法:
创建指令:创建一个指令,该指令将自动将 data-testid 属性添加到它所应用到的任何元素。
import { Directive, ElementRef, Renderer2 } from '@angular/core';
@Directive({
selector: '[autoTestId]'
})
export class AutoTestIdDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {
const element = el.nativeElement;
const tagName = element.tagName.toLowerCase();
const testId = `${tagName}-${AutoTestIdDirective.generateUniqueId()}`;
this.renderer.setAttribute(element, 'data-testid', testId);
}
private static generateUniqueId(): string {
// Your unique ID generation logic here
return Math.random().toString(36).substr(2, 9);
}
}
修改应用程序引导进程:修改 Angular 应用程序的引导进程以全局应用此指令。
import { ApplicationRef, ComponentFactoryResolver, Injector } from '@angular/core';
export class AppBootstrapListener {
constructor(
private appRef: ApplicationRef,
private componentFactoryResolver: ComponentFactoryResolver,
private injector: Injector
) {
this.appRef.isStable.subscribe((isStable) => {
if (isStable) {
this.addTestIdToAllElements();
}
});
}
private addTestIdToAllElements() {
const elements = document.querySelectorAll('*');
elements.forEach((element) => {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(AutoTestIdDirective);
componentFactory.create(this.injector, [], element);
});
}
}
注册监听器:在主模块中注册AppBootstrapListener,以确保它在应用程序稳定时运行。
providers: [{ provide: APP_INITIALIZER, useFactory: appBootstrapListenerFactory, deps: [AppBootstrapListener], multi: true }]
此方法会自动向 Angular 应用程序中的每个元素添加 data-testid 属性,而无需手动编辑每个 UI 元素。应调整 AutoTestIdDirective 中的唯一 ID 生成逻辑,以满足您对数据 testid 格式的特定要求。