如果您使用 material 表单,请在 Angular 中使用 cypress 进行选择
Make selection using cypress in Angular if you're using material forms
我有一个看起来像这样的表格:
<form class="col s12" materialize [formGroup]="newUserForm">
...
<div class="row">
<div class="input-field col m4 s12">
<select formControlName="genderBound" materialize="material_select" id="gender" name="test">
<option value="" disabled selected name="chooseGender">Choose gender</option>
<option *ngFor="let gender of genders">{{gender}}</option>
</select>
<label for="gender">Gender</label>
</div>
...
当我尝试使用 cypress select 下拉菜单时,它告诉我它不可见。当我按照 cypress 提供的解释 URL 时,它建议我在我的点击中使用 {force: true}
。这让我的测试通过了,但实际上似乎从未 select 项目。
我也遵循了 提供的解决方案,并在实际选项上实现了 jQuery 单击(请注意,我的 select 和选项标签不是 md-select 和 md-option 标签)
sample.spec.js 在我的 cypress 目录中:
...
it('signs up a new user', () =>{
cy.get('button[id=new-account-button]').click();
cy.get('input[id=affiliation]').type(affiliation);
cy.get('input[id=password]').type(pass);
cy.get('input[id=userName]').type(name);
cy.get('input[id=email]').type(email);
//Now the options
cy.get('[name="chooseGender"]').click({force: true});
cy.get('option').contains("Female").then(option =>{
cy.wrap(option).contains("Female");
option[0].click();
});
...
我想有两件事我不太明白:
- 为什么实际上 select 没有一个选项?
- 尽管如此,为什么测试还是通过了?
我在下面提供了一个包含我的确切问题的回购协议:
git clone https://github.com/Atticus29/dataJitsu.git
cd dataJitsu
git checkout cypress-SO
在 /src/app 中创建一个 api-keys.ts 文件,并用后面的文本填充它
npm install
ng serve
(在单独的终端选项卡中)
npm run e2e
api-keys.ts:
export var masterFirebaseConfig = {
apiKey: "AIzaSyCaYbzcG2lcWg9InMZdb10pL_3d1LBqE1A",
authDomain: "dataJitsu.firebaseapp.com",
databaseURL: "https://datajitsu.firebaseio.com",
storageBucket: "",
messagingSenderId: "495992924984"
};
export var masterStripeConfig = {
publicApiTestKey: "pk_test_NKyjLSwnMosdX0mIgQaRRHbS",
secretApiTestKey: "sk_test_6YWZDNhzfMq3UWZwdvcaOwSa",
publicApiKey: "",
secretApiKey: ""
};
我发现以下测试适用于您的存储库(最新提交 353633c),
describe('Test Gender Select', () => {
before(function () {
cy.visit('http://localhost:4200/')
})
it('signs up a new user', () => {
cy.get('button').contains('Create New Account').click();
cy.get('#gender').select('Female', {
force: true
});
cy.get('#gender').contains('Female')
});
});
从Cypress test runner可以看出确实选择了Female选项,所以我相信它涵盖了你原来测试的目的。
如果我尝试像这样使用 click()
cy.get('#gender').click({
force: true
});
赛普拉斯给出消息
CypressError: cy.click() cannot be called on a element. Use cy.select() command instead to change the value.
因此,按照此说明并使用
cy.get('#gender').select('Female');
给出以下关于可见性的错误消息,这似乎是使用 material 设计的 select
的标准(angular-material 和 material大小).
CypressError: Timed out retrying: cy.select() failed because this element is not visible ... Fix this problem, or use {force: true} to disable error checking.
所以在 cy.select()
上使用 { force: true }
选项可以解决这个问题。
我理解可见性问题的发生是因为 material 设计用选项列表覆盖了父级,而 Cypress 使用基于父级的可见性标准(参见此 ),尽管现在 force 选项有效(使用 Cypress v3.0.3)。
对于 Angular 7+ 中的 mat-select,您必须使用 promises 来等待模态 cdk-overlay 中的选项可用。
这里有一个复用辅助函数:
function selectMaterialDropDown(formControlName, selectOption) {
cy.get(`[formcontrolname="${formControlName}"]`).click().then(() => {
cy.get(`.cdk-overlay-container .mat-select-panel .mat-option-text`).should('contain', selectOption);
cy.get(`.cdk-overlay-container .mat-select-panel .mat-option-text:contains("${selectOption}")`).first().click().then(() => {
// After click, mat-select should contain the text of the selected option
cy.get(`[formcontrolname="${formControlName}"]`).contains(selectOption);
});
});
}
调用函数:
selectMaterialDropDown('myMatSelectControlName', 'OptionTextToSelect');
对于 Angular 9,此代码适用于我:
cy.get('.selector').children('mat-form-field').click()
cy.get('mat-option').contains('Option text').click()
我有一个看起来像这样的表格:
<form class="col s12" materialize [formGroup]="newUserForm">
...
<div class="row">
<div class="input-field col m4 s12">
<select formControlName="genderBound" materialize="material_select" id="gender" name="test">
<option value="" disabled selected name="chooseGender">Choose gender</option>
<option *ngFor="let gender of genders">{{gender}}</option>
</select>
<label for="gender">Gender</label>
</div>
...
当我尝试使用 cypress select 下拉菜单时,它告诉我它不可见。当我按照 cypress 提供的解释 URL 时,它建议我在我的点击中使用 {force: true}
。这让我的测试通过了,但实际上似乎从未 select 项目。
我也遵循了
sample.spec.js 在我的 cypress 目录中:
...
it('signs up a new user', () =>{
cy.get('button[id=new-account-button]').click();
cy.get('input[id=affiliation]').type(affiliation);
cy.get('input[id=password]').type(pass);
cy.get('input[id=userName]').type(name);
cy.get('input[id=email]').type(email);
//Now the options
cy.get('[name="chooseGender"]').click({force: true});
cy.get('option').contains("Female").then(option =>{
cy.wrap(option).contains("Female");
option[0].click();
});
...
我想有两件事我不太明白:
- 为什么实际上 select 没有一个选项?
- 尽管如此,为什么测试还是通过了?
我在下面提供了一个包含我的确切问题的回购协议:
git clone https://github.com/Atticus29/dataJitsu.git
cd dataJitsu
git checkout cypress-SO
在 /src/app 中创建一个 api-keys.ts 文件,并用后面的文本填充它
npm install
ng serve
(在单独的终端选项卡中)
npm run e2e
api-keys.ts:
export var masterFirebaseConfig = {
apiKey: "AIzaSyCaYbzcG2lcWg9InMZdb10pL_3d1LBqE1A",
authDomain: "dataJitsu.firebaseapp.com",
databaseURL: "https://datajitsu.firebaseio.com",
storageBucket: "",
messagingSenderId: "495992924984"
};
export var masterStripeConfig = {
publicApiTestKey: "pk_test_NKyjLSwnMosdX0mIgQaRRHbS",
secretApiTestKey: "sk_test_6YWZDNhzfMq3UWZwdvcaOwSa",
publicApiKey: "",
secretApiKey: ""
};
我发现以下测试适用于您的存储库(最新提交 353633c),
describe('Test Gender Select', () => {
before(function () {
cy.visit('http://localhost:4200/')
})
it('signs up a new user', () => {
cy.get('button').contains('Create New Account').click();
cy.get('#gender').select('Female', {
force: true
});
cy.get('#gender').contains('Female')
});
});
从Cypress test runner可以看出确实选择了Female选项,所以我相信它涵盖了你原来测试的目的。
如果我尝试像这样使用 click()
cy.get('#gender').click({
force: true
});
赛普拉斯给出消息
CypressError: cy.click() cannot be called on a element. Use cy.select() command instead to change the value.
因此,按照此说明并使用
cy.get('#gender').select('Female');
给出以下关于可见性的错误消息,这似乎是使用 material 设计的 select
的标准(angular-material 和 material大小).
CypressError: Timed out retrying: cy.select() failed because this element is not visible ... Fix this problem, or use {force: true} to disable error checking.
所以在 cy.select()
上使用 { force: true }
选项可以解决这个问题。
我理解可见性问题的发生是因为 material 设计用选项列表覆盖了父级,而 Cypress 使用基于父级的可见性标准(参见此
对于 Angular 7+ 中的 mat-select,您必须使用 promises 来等待模态 cdk-overlay 中的选项可用。
这里有一个复用辅助函数:
function selectMaterialDropDown(formControlName, selectOption) {
cy.get(`[formcontrolname="${formControlName}"]`).click().then(() => {
cy.get(`.cdk-overlay-container .mat-select-panel .mat-option-text`).should('contain', selectOption);
cy.get(`.cdk-overlay-container .mat-select-panel .mat-option-text:contains("${selectOption}")`).first().click().then(() => {
// After click, mat-select should contain the text of the selected option
cy.get(`[formcontrolname="${formControlName}"]`).contains(selectOption);
});
});
}
调用函数:
selectMaterialDropDown('myMatSelectControlName', 'OptionTextToSelect');
对于 Angular 9,此代码适用于我:
cy.get('.selector').children('mat-form-field').click()
cy.get('mat-option').contains('Option text').click()