Dom-testing-library: What do we recommend people do for elements that have no implicit role (like input[type=password])

Created on 12 May 2020  路  7Comments  路  Source: testing-library/dom-testing-library

Say you have a login form:

<form>
  <div>
    <label for="username-field">Username</label>
    <input id="username-field" name="username" type="text" />
  </div>
  <div>
    <label for="password-field">Password</label>
    <input id="password-field" name="password" type="password" />
  </div>
  <div>
    <button type="submit">Submit</button>
  </div>
</form>

You can retrieve the username field via: screen.getByRole('textbox', {name: /username/i}) However, the password field has no implicit role so you'd have to use getByLabelText(/password/i) for that one.

I'm guessing that we just recommend people use getByLabelText as a fallback in this case, but I'm curious what other people think about this (especially curious to hear @eps1lon's thoughts here).

Most helpful comment

I'm guessing that we just recommend people use getByLabelText as a fallback in this case

I think this is our safest bet. I wouldn't want to diverge from the spec. Otherwise people might use <input type="text" role="password" />.

If people stumble over this often when doing getByRole('textbox', { name: 'Password' }) we could check if there are other roles with the same superclass (related to #448) and name (and add a special case for input[type="text"]).

All 7 comments

Interesting discussion on the reason passwords don't have a role: https://github.com/w3c/aria/issues/935

I'm guessing that we just recommend people use getByLabelText as a fallback in this case

I think this is our safest bet. I wouldn't want to diverge from the spec. Otherwise people might use <input type="text" role="password" />.

If people stumble over this often when doing getByRole('textbox', { name: 'Password' }) we could check if there are other roles with the same superclass (related to #448) and name (and add a special case for input[type="text"]).

Quite conveniently (or not), I've just faced this issue and was confused as to why my password input just couldn't be found. Using getByLabelText works, but it does a look a bit strange in my test;

const usernameInput = getByRole("textbox", { name: /username/i });
const domainInput = getByRole("textbox", { name: /domain/i });
const passwordInput = getByLabelText(/password/i);

I'd appreciate eps1lon's suggestion, but if this would result in some hacky, unstable solution I'd rather stick with what I already have.

I would suggest to use getByLabelText as that would improve the accessibility of the form by the need of adding a label. If they don't want to see the label they can always hide the label element visually.

Thanks for the input @weyert. You actually get the exact same benefit (and more) by using getByRole with a name which is why it's recommended over getByLabel.

The issues is brought up because password fields don't have an implicit role assigned to them like regular inputs, so (as @Tohaker pointed out) it looks a little odd.

I'm pretty sure this is what we'll recommend however, so I'll go ahead and close this.

I'm guessing that we just recommend people use getByLabelText as a fallback in this case

I think this is our safest bet. I wouldn't want to diverge from the spec. Otherwise people might use <input type="text" role="password" />.

If people stumble over this often when doing getByRole('textbox', { name: 'Password' }) we could check if there are other roles with the same superclass (related to #448) and name (and add a special case for input[type="text"]).

Disclaimer: Speculation & My Opinion
Wouldnt this be a security risk that would enable malicious scripts the ability to find password fields much easier. I think much like certain Checkout Cart behaviors that obfuscate what the fields are being used for, this is a similar thing. Not bulletproof security or anything but a simple layer

Password fields aren't encrypted, so they have pretty much no security in the client. What matters is that they have secure transport over the network (like a secure API using HTTPS).

Was this page helpful?
0 / 5 - 0 ratings