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).
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 forinput[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).
Most helpful comment
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 forinput[type="text"]).