Explicitly set tabIndex for log in buttons, since Safari does not interpret them as "interactive elements" in the same way it does input fields; clean up, test (#37019)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #36735 (see https://fleetdm.slack.com/archives/C019WG4GH0A/p1765304390750399?thread_ts=1765303643.855049&cid=C019WG4GH0A) Safari now has same tab order without having to hold option button while tabbing:  - Confirmed order is maintained on Firefox and Chrome - Cleaned up inaccurate emptiness checks and unnecessary wrappers - Test - [x] QA'd all new/changed functionality manually - [x] Added tests - [x] Confirmed that the fix is not expected to adversely impact load test results
This commit is contained in:
@@ -140,4 +140,29 @@ describe("LoginForm - component", () => {
|
||||
password,
|
||||
});
|
||||
});
|
||||
it("tabs in the expected order", async () => {
|
||||
const { user } = renderWithSetup(
|
||||
<LoginForm
|
||||
handleSubmit={submitSpy}
|
||||
isSubmitting={false}
|
||||
pendingEmail={false}
|
||||
ssoSettings={{
|
||||
sso_enabled: true,
|
||||
idp_name: "Test IdP",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByPlaceholderText("Email")).toHaveFocus();
|
||||
await user.tab();
|
||||
expect(screen.getByPlaceholderText("Password")).toHaveFocus();
|
||||
await user.tab();
|
||||
expect(screen.getByText("Log in").parentElement).toHaveFocus();
|
||||
await user.tab();
|
||||
expect(
|
||||
screen.getByText("Sign in with Test IdP").parentElement
|
||||
).toHaveFocus();
|
||||
await user.tab();
|
||||
expect(screen.getByText("Forgot password?")).toHaveFocus();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -84,28 +84,28 @@ const LoginForm = ({
|
||||
|
||||
const showLegendWithImage = () => {
|
||||
let legend = "Single sign-on";
|
||||
if (idpName !== "") {
|
||||
if (idpName) {
|
||||
legend = `Sign in with ${idpName}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
<img
|
||||
src={imageURL}
|
||||
alt={idpName}
|
||||
className={`${baseClass}__sso-image`}
|
||||
/>
|
||||
<span className={`${baseClass}__sso-legend`}>{legend}</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const renderSingleSignOnButton = () => {
|
||||
let legend: string | JSX.Element = "Single sign-on";
|
||||
if (idpName !== "") {
|
||||
if (idpName) {
|
||||
legend = `Sign in with ${idpName}`;
|
||||
}
|
||||
if (imageURL !== "") {
|
||||
if (imageURL) {
|
||||
legend = showLegendWithImage();
|
||||
}
|
||||
|
||||
@@ -116,8 +116,9 @@ const LoginForm = ({
|
||||
title="Single sign-on"
|
||||
variant="inverse"
|
||||
onClick={handleSSOSignOn}
|
||||
tabIndex={0}
|
||||
>
|
||||
<div>{legend}</div>
|
||||
{legend}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@@ -183,6 +184,7 @@ const LoginForm = ({
|
||||
className={`${baseClass}__login-btn`}
|
||||
isLoading={isSubmitting}
|
||||
type="submit"
|
||||
tabIndex={0}
|
||||
>
|
||||
Log in
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user