Recently I showed how to interact with the Microsoft FAST design Select component. Someone asked how they could interact with Cloudscape Design components, in particular with its React Select component. In particular, these components include a test wrapper utilities that are supposed to help write stable tests. Well, you will see that those utilities are less than helpful, and you can get a simpler and better test just by using Cypress best practices for selecting elements.
🎁 You can find my source code in the repo bahmutov/cypress-cloudscape-example.
The application page
My application uses the standard demo of the React Select component from the Cloudscape documentation pages. I only added the data-testid
attribute.
1 | import * as React from 'react' |
The app runs using Vite. My initial test simply visits the page.
1 | // enables intelligent code completion for Cypress commands |
Let's see the HTML markup the Cloudscape Select component places on the page. It is a lot of custom styling. But we see the data-testid
attribute, so we can find the component's top element at least.
1 | describe('Cloudscape Design System: Select', () => { |
Let's make the test stronger. We know that the first option should be selected by default. Thus the element should show "Option 1" at the start. Instead of cy.get we can use cy.contains command.
1 | describe('Cloudscape Design System: Select', () => { |
Initially the select element is closed. We can confirm it by checking the aria-expanded
attribute on the button that opens it.
1 | describe('Cloudscape Design System: Select', () => { |
Let's open the Select dropdown. We need to click on it. The select closes when we move the mouse away, so here is my trick to "catch" the dropdown HTML markup: add cy.wait and hover over the WAIT
command to restore the DOM snapshot.
1 | describe('Cloudscape Design System: Select', () => { |
Click on the "WAIT" command and inspect the HTML markup.
Now we can confirm the Select is open and the "Option 1" is selected by default.
1 | describe('Cloudscape Design System: Select', () => { |
So far, so good.
Now let's select the "Option 3" and confirm the dropdown closes.
1 | describe('Cloudscape Design System: Select', () => { |
Looking good. We are using data-testid
plus aria attributes and roles to find and control the elements.
Cloudscape test wrappers
For something a little less impressive, let's try using Select test wrappers that Cloudscape Design recommends. We can import the testing utility in our Cypress spec. The wrapper gives us ... a selector string. Let's see how we can select the component's element.
1 | import createWrapper from '@cloudscape-design/components/test-utils/selectors' |
Oh my. The helpers like createWrapper().findSelect().findDropdown().toSelector()
return the long mangles class name prefixes.
🤔 Maybe I am using the test wrappers incorrectly? I followed the examples in the documentation. If you can suggest a better way, I am all ears.
The test passes, but it is really cumbersome to read, and the Command Log is less than helpful. I think these Cloudscape test wrappers might be useful for Jest / Enzyme / js-dom test runners, but they only hurt the developers that use Cypress and can see the actual HTML markup shown by the browser. If I were designing a testing wrapper for these components I would concentrate on semantic HTML attributes, rather than the mangled class names.