I have a test that uses a Mat-Select click event looking for some data (bolded line in code). The test only works sometimes. The data for the select is coming from an Observable/Async pipe. The test either works perfectly or the drop down never loads and the test fails. The bolded line fails because the data never shows up. But the test does work sometimes. I tried waiting, but when it fails it times out.
When manually running the app the drop down is always loaded. So I'm thinking it's some sort of async/timing issue but I'm stumped right now, any help is appreciated
Test:
it('visits the root', () => {
cy.visit('/');
});
it('clicks the menu button expenses option', () => {
cy.get('mat-icon').click();
cy.contains('a', 'expenses').click();
});
it('clicks add icon', () => {
cy.intercept('GET', 'http://localhost:8080/api/employees').as(
'dataGetEmployees'
);
cy.contains('control_point').click();
cy.wait('@dataGetEmployees');
});
it('fills in fields', () => {
cy.get('mat-select[formcontrolname="employeeid"]').click();
**cy.contains('Smartypants').click().should('exist', { timeout: 2000 });**
cy.get('mat-select[formcontrolname="categoryid"]').click();
cy.get('mat-option').contains('Travel').click();
cy.get('input[formcontrolname=description]').type('plane tickets');
cy.get('input[formcontrolname=amount]').type('129.99');
cy.get('input[formcontrolname=dateincurred]').type('2022-04-25').click();
});
it('clicks the save button', () => {
cy.get('button').contains('Save').click();
});
it('confirms add', () => {
cy.contains('added!');
});
});
This is the error when it fails:
Error: AssertionError: Timed out retrying after 4000ms: Expected to find element: `mat-option`, but never found it.
at Context.eval (http://localhost:4200/__cypress/tests?p=cypress\e2e\expense\expense-add.spec.cy.ts:113:30)
CodePudding user response:
If your mat-select inside of the form, for the first step you need to get the form.
it('fills in fields', () => {
cy.get('form').within((form) => {
cy.get('mat-select[formcontrolname="employeeid"]').click();
**cy.contains('Smartypants').click().should('exist', { timeout: 2000
});**
cy.get('mat-select[formcontrolname="categoryid"]').click();
cy.get('mat-option').contains('Travel').click();
cy.get('input[formcontrolname=description]').type('plane tickets');
cy.get('input[formcontrolname=amount]').type('129.99');
cy.get('input[formcontrolname=dateincurred]').type('2022-04-25').click();
})
});
CodePudding user response:
Since observable is asynchronous, it may need a wait for the options to appear.
Try adding a check on the options list length.
cy.get('mat-select[formcontrolname="employeeid"]').click(); // open the list
cy.get('mat-option').should('have.length', 5) // wait for options
cy.contains('Smartypants').click()
The mat-option
elements come and go from the DOM each time the user opens/selects from a list, so there will only ever be one set of mat-option
present after a mat-select
click.