Home > Enterprise >  Mat-select loaded from Angular observable in cypress e2e test only loads some times
Mat-select loaded from Angular observable in cypress e2e test only loads some times

Time:07-07

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.

  • Related