From c5cac90df03628664ea7d2735c7c231e0034ce4e Mon Sep 17 00:00:00 2001 From: jacobshandling <61553566+jacobshandling@users.noreply.github.com> Date: Tue, 9 Dec 2025 14:10:23 -0800 Subject: [PATCH] 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) **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: ![ezgif-758724f23b5b7550](https://github.com/user-attachments/assets/9ba83634-9211-4c61-9798-d84a1ebb9a15) - 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 --- .../forms/LoginForm/LoginForm.tests.tsx | 25 +++++++++++++++++++ .../components/forms/LoginForm/LoginForm.tsx | 14 ++++++----- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/frontend/components/forms/LoginForm/LoginForm.tests.tsx b/frontend/components/forms/LoginForm/LoginForm.tests.tsx index b27371c92f..22aabb8443 100644 --- a/frontend/components/forms/LoginForm/LoginForm.tests.tsx +++ b/frontend/components/forms/LoginForm/LoginForm.tests.tsx @@ -140,4 +140,29 @@ describe("LoginForm - component", () => { password, }); }); + it("tabs in the expected order", async () => { + const { user } = renderWithSetup( + + ); + + 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(); + }); }); diff --git a/frontend/components/forms/LoginForm/LoginForm.tsx b/frontend/components/forms/LoginForm/LoginForm.tsx index 957f8fd7ee..566d9cc5eb 100644 --- a/frontend/components/forms/LoginForm/LoginForm.tsx +++ b/frontend/components/forms/LoginForm/LoginForm.tsx @@ -84,28 +84,28 @@ const LoginForm = ({ const showLegendWithImage = () => { let legend = "Single sign-on"; - if (idpName !== "") { + if (idpName) { legend = `Sign in with ${idpName}`; } return ( -
+ <> {idpName} {legend} -
+ ); }; 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} > -
{legend}
+ {legend} ); }; @@ -183,6 +184,7 @@ const LoginForm = ({ className={`${baseClass}__login-btn`} isLoading={isSubmitting} type="submit" + tabIndex={0} > Log in