radix-ui / themes

Radix Themes is an open-source component library optimized for fast development, easy maintenance, and accessibility. Maintained by @workos.
https://radix-ui.com/themes
MIT License
5.6k stars 200 forks source link

Targeting Select.Trigger with cypress #377

Closed eseyfert closed 7 months ago

eseyfert commented 7 months ago

Hey there,

what would be the correct way to apply an accessible label for the <Select.Trigger> component? I am in the process of writing some Cypress tests and no matter what I try, the button never shows up in the list of available DOM nodes.

I already looked at the primitives page for guidance but the example sadly does not help: https://www.radix-ui.com/primitives/docs/components/select#labelling

This is what I tried so far to no avail:

<Select.Trigger aria-label="Label" />
<label htmlFor="trigger">Label</label>
<Select.Trigger id="trigger" />
<span id="trigger-label">Label</span>
<Select.Trigger aria-labelledby="trigger-label" />

Any ideas? Help would be much appreciated. :)

Edit: Have a seemingly similar issue with <TextField.Input>.

vladmoroz commented 7 months ago

I am in the process of writing some Cypress tests and no matter what I try, the button never shows up in the list of available DOM nodes.

How are you targeting it?

eseyfert commented 7 months ago

I am using @testing-library/cypress, so with a query like cy.findByRole('combobox', { name: 'Example' }). Tried it using cy.findByRole('button') as well. I can target the elements using more generic methods just fine, but if I specifically try to look for a role in combination with a name, it can't find it, because seemingly the name does not get applied.

Screenshot 2024-03-15 at 11 48 11

vladmoroz commented 7 months ago

Are you setting the name attribute on your form controls?

eseyfert commented 7 months ago

I am not sure exactly what you mean.

This is what my <Select> component looks like:

    <Select.Root size="3" {...props}>
        <Select.Trigger color="gray" className="font-medium cursor-pointer" />

        <Select.Content>
            <Select.Item value="email">Email</Select.Item>
            <Select.Item value="design">Design Series</Select.Item>
            <Select.Item value="format">Format</Select.Item>
            <Select.Item value="color">Color</Select.Item>
        </Select.Content>
    </Select.Root>

What form controls or name attribute are you referring to?

vladmoroz commented 7 months ago

cy.findByRole('combobox', { name: 'Example' }) looks for an element with role="combobox" and name="Example"; the latter is missing from your code.

It sounds like you might want to take a step back and try to figure out how forms and testing them works with native <input> elements before using a component library.

The difference between labelling a form control and adding a name is that labels are used by humans, and name is used by computers to identify which form control a piece of data from your form relates to. There’s plenty of in-depth info out there on how this stuff works.

eseyfert commented 7 months ago

The name in Cypress is inferred from the accessible text the element has. <button>Text</button> would have the name of Text. I am also not sure why you are talking about <input> elements when I am seeking help for your <Select> component, that is made up of a trigger <button> and item <div> elements.

I have worked with a11y topics for quite a long time now and have written plenty of Cypress tests with accessible components. I also understand what the name attribute in form children is used for, but it is completely irrelevant here, as we are not working with forms or form inputs. And as stated before, Name: in Cypress refers to the accessible label/text of an element.

vladmoroz commented 7 months ago

Hm, yeah, you are right, apologies. I assumed that was related to the name attribute like most other testing tools. I don't know how exactly Cypress heuristics work there, but I see all the relevant attributes applied to the HTML nodes correctly.

Edit: Have a seemingly similar issue with

Can you confirm that your tests work with a regular input?

eseyfert commented 7 months ago

I feel very silly now but it was an issue with my test environment where the attribute changes I made weren't reflected in the actual tests. 😅 I now have it working and aria-label works on both the <Select.Trigger> and <TextField.Input>, so no issues from my side anymore.

Honestly, thank you for taking the time and for your patience. 😄 Hope you have a great weekend!

vladmoroz commented 7 months ago

No worries, happens to everyone. Sorry for my mixup too 🙂