'Cypress: How to properly close a mat-select
So I'm using Cypress for testing our Angular application, but for some reason I always have an issue with closing mat-select components which are multiselect. Has anyone got a good solution for this?
function selectValue(id: string, value: string) {
return cy.get(`mat-select[id="${id}"]`)
.click()
.then(() =>
cy.get('mat-option')
.contains(value)
.click();
}
Solution 1:[1]
To close the list on a multi-select dropdown, do what a user does and click outside the list, e.g on the body
it('selects, closes, verifies', () => {
cy.visit('https://material.angular.io/components/select/overview#multiple-selection')
cy.get('div[role="listbox"]').should('not.exist') // check list isn't open
cy.get('select-multiple-example').click() // open
cy.get('div[role="listbox"]').should('exist') // check list is open
cy.contains('Extra cheese').click() // select an item
cy.contains('Onion').click() // select an item
cy.contains('Tomato').click() // select an item
cy.get('body').click() // click outside the list
cy.get('div[role="listbox"]').should('not.exist') // check list isn't open
cy.get('select-multiple-example')
.should('contain', 'Extra cheese, Onion, Tomato') // verify
cy.get('select-multiple-example')
.should('not.contain', 'Mushroom') // verify contra
})
Solution 2:[2]
Another thing that worked in my case was
cy.get(`mat-select[data-testid="${dropdownTestId}"]`).focus().type('{esc}');
Solution 3:[3]
I suggest something like this:
Cypress.Commands.add('selectValue', (value) => {
cy
.get('mat-select').first().click()
.get('.mat-option-text').contains(value).click()
.get('.mat-option-text').should('not.visible')
.get('.mat-select-value-text').first().should(([{ innerText }]) => {
expect(innerText).equal(value)
})
});
I tested it on https://material.angular.io/components/select/overview and it works on my local machine.
If something fails, feel free to ask questions
Solution 4:[4]
A better way is to use the new feature components harnesses
https://material.angular.io/cdk/test-harnesses/overview
for your problem it should work like this, first you create harness loader from the fixture in beforeEach statement
loader = TestbedHarnessEnvironment.loader(fixture);
then you can get the select harness by doing something like this
let selectHarness = await loader.getHarness(MatSelectHarness.with({selector: '#select-id'}));
now you can simply use the close method
selectHarness.close()
Solution 5:[5]
in my case it was not possible to click outside of the select box because overlay issue is blocking everything, for my case this "weird solution" worked:
cy.get('mat-option').contains(text).click().type('{end}').type('{esc}');
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Bat0u89 |
Solution 3 | Przemyslaw Jan Beigert |
Solution 4 | Nichola |
Solution 5 | Yuqiu G. |