Skip to content

Using tab without needing a start element. #63

@DToppingWW

Description

@DToppingWW

Hey

Firstly, thanks for your awesome plugin that solves a massive a11y hole in the Cypress feature-set.

Context

I'd like to be able to write a regression test for skip to navigation links in the application I am working on.

The application works something like this:

<body>
  <a href="#maincontent">Skip to main content</a>
  <header>
    // menus
  </header>
  <main id="maincontent">
    <input data-testid="first-input">Next</input>
  </main>
</body>

and the test I've tried to write goes something like this:

it("skip to content", () => {
   cy.findByTestId("first-input").should("not.be.focused");
   cy.findByRole("link", {name: "Skip to main content"}).click();
   cy.get("body").tab();
   cy.findByTestId("first-input").should("be.focused");
})

Problem

It all works fine until the tab. I what I think is happening, is clicking the "Skip to content" anchor tag reloads the page, with it scrolled and focused onto the main tag (which isn't tabbable or focusable, but is important for setting the focus order of the page correctly for subsequent TAB keypress events)

I think the cy.get('body').tab(); is first clicking or focusing the body in order to send the tab keypress event.

This is not desirable in this scenario, as I wanted to just send the tab without affecting where in the page the focus is after the feature that I am testing.

What I've tried

  • I've tried using the main element as the target to send the tab event from (cy.get('#main-content').tab());
    • But this isn't possible as the plugin checks for a tabbable element, but main is a non-interactive element for a11y aria-role purposes only (and I don't really want to have to add a tabindex="0" to it either),
    • Also I think doing this sort-of invalidates the test the same way as cy.get("body") does, as its doing a click inbetween what I want to test and my assertion.

Would it be possible to send a tab event without affecting page focus state?

Ideally I'd like to be able to write:

it("skip to content", () => {
   cy.findByTestId("first-input").should("not.be.focused");
   cy.findByRole("link", {name: "Skip to main content"}).click();
   cy.tab();
   cy.findByTestId("first-input").should("be.focused");
})

and it just work. 🙂

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions