Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need tab key support #299

Open
robdodson opened this issue Nov 17, 2016 · 91 comments
Open

Need tab key support #299

robdodson opened this issue Nov 17, 2016 · 91 comments
Labels
existing workaround pkg/driver This is due to an issue in the packages/driver directory topic: native events type: feature New feature that does not currently exist

Comments

@robdodson
Copy link

Description
As mentioned here https://docs.cypress.io/v1.0/docs/type#section-typing-tab-key-does-not-work. For accessibility testing I need to be able to tell the keyboard to press tab. If cy.tab is not currently supported is there some way to work around this?

@jennifer-shehane
Copy link
Member

jennifer-shehane commented Nov 17, 2016

I'd like to hear more about what you are looking to cover in terms of accessibility testing. Can you give me an example of a use case you are trying to test with the tab key?

Right now there is not a way to press "tab".

Currently we simulate all events in Cypress - although we automatically backfill in the browser's default behavior on all actions, which means that your application does what it does identically to native events.

The problem with tab is that it is extremely complicated and its behavior is not necessarily normalized across all behaviors.

The solution for us is to enable native events within Cypress. We can "opt into" native events whenever we want, the problem is mostly with the UX experience around the debugger protocol. Namely that you cannot have Dev Tools open and issue native events due to the limitation of Chrome's debugger protocol.

There is an open issue in Chromium to add multiplexing support so we've been waiting for that to go live. Until then we will kick the can, or eventually be forced into creating a good UX experience that either automatically closes Dev Tools, or prompts the user that their tests cannot continue until it is closed.

@jennifer-shehane jennifer-shehane added the type: feature New feature that does not currently exist label Nov 17, 2016
@robdodson
Copy link
Author

robdodson commented Nov 17, 2016

thanks for the response

The tab key is one of the primary ways a keyboard user moves around the page so it's difficult to write a high confidence accessibility test without it. In my case I'm building custom components that comply with the aria authoring practices guide. The first thing I would like to do on every page is press tab to focus the element. I can fake this by calling click() but it's not really the same. A non-sighted user will never use the mouse so calling click() feels a bit like cheating and you could imagine a situation where an element has one behavior when clicked and a different behavior when focused via the tab key.

@brian-mann
Copy link
Member

If you're testing the behavior of an element coming into focus, or you're testing things like styles you can just focus the element directly.

cy.get("input").focus()

What this doesn't test for is what the browser's behavior when clicking "tab". But you can often indirectly test this.

For instance, you could just make sure that the element it's supposed to focus on has tabindex set.

@robdodson
Copy link
Author

What this doesn't test for is what the browser's behavior when clicking "tab". But you can often indirectly test this.

Yeah that's what I've been doing. Still, I would prefer tab key support if it were there because it'd be less boilerplate to write :)

@kamituel
Copy link

I have a different use case for .tab() - in our app we have a fairly advanced search input (multiline, hence implemented as a <textarea>). A user is supposed to enter a query written in a custom grammar. It might look like this: some.path.here = something. Tab completion is supported, so when the user enters, say, some.p and pressed a tab key, it might get expanded to some.path..

This is obviously distinct from accessibility use cases (as described above).

Any update on .tab()?

@jennifer-shehane
Copy link
Member

In Chrome 63, there is support for multiplexing and we can now better handle native events. See #311

@protoEvangelion
Copy link

@jennifer-shehane Is this on the road map to be implemented? Or should we not expect this any time soon?

@awhill19
Copy link

awhill19 commented Dec 1, 2017

I'd love to know as well. Just ran into this issue while writing a form validation test.

@jennifer-shehane jennifer-shehane added pkg/driver This is due to an issue in the packages/driver directory topic: native events labels Dec 4, 2017
@davidszepernick
Copy link

Me too . I was expecting some way to tab to the next field like .type({tab})

@siemiatj
Copy link

Same as the above. I'm testing an app that mimics desktop application and heavily relies on keyboard usage.

@mirandashort
Copy link

Has anyone found a good workaround for this? It seems as if we're not getting a tab function..

@scottschafer
Copy link

scottschafer commented Apr 9, 2018

This seems to work:

Cypress.Commands.add('typeTab', (shiftKey, ctrlKey) => {
  cy.focused().then(($el) => {
    cy.wrap($el).trigger('keydown', {
      keyCode: 9,
      which: 9,
      shiftKey: shiftKey,
      ctrlKey: ctrlKey
    });
  });
});

@brian-mann
Copy link
Member

@scottschafer that fires the event, but the browser will not perform the default action such as moving the tab focus to the next focusable element

@jennifer-shehane
Copy link
Member

@scottschafer This should be able to be simplified to this:

Cypress.Commands.add('typeTab', (shiftKey, ctrlKey) => {
  cy.focused().trigger('keydown', {
      keyCode: 9,
      which: 9,
      shiftKey: shiftKey,
      ctrlKey: ctrlKey
  });
});

@scottschafer
Copy link

@brian-mann , ah. In our web app we specifically handle keyboard events and change focus programmatically. It works for us - sorry this won't work for you.

@jennifer-shehane
Copy link
Member

@scottschafer Yes, glad to see you got this work in your use case. It should help anyone else that programmatically works off of the user's specific keydown of the tab key.

@lazarljubenovic
Copy link

Whaaat? Tabbing was literally the first thing I tried testing 😄 Wanted to test the login form and the fact that pressing Tab on the password form doesn't focus the Show/hide password button but the Login button...

The problem with tab is that it is extremely complicated and its behavior is not necessarily normalized across all behaviors.

Wouldn't it be possible to allow users to customize the "algorithm" for tabbing? Figuring out where the focus will go is indeed a tricky problem, but for a majority of usecases it should work pretty straightforward. Figure out what is the next focusable element in the DOM after the current document.activeElement. Something like button:not([tabindex=0]),a:not([tabindex=0]),[tabindex=1],[tabindex=2],...)?

There are a few very good libs which also try to figure out which elements are focusable in order to trap focus in a modal or a dropdown. Maybe it's a good starting point to figure out what kind of algorithm they use to intercept focus leaving the modal and taking it back to the first focusable element in it?

@decafdennis
Copy link

I think the key is to find or come up with an implementation that works for your use case. It's hard to come up with a general solution.

FWIW, here's my implementation roughly based off of some of jQuery UI's logic: https://github.com/getstreamline/menu/blob/master/cypress/support/index.js#L39

One of the gotchas is that the focused() command does not work reliably when the browser is not currently in focus, so I also added a separate active() command that is more consistent: https://github.com/getstreamline/menu/blob/master/cypress/support/index.js#L63

It's naive but works for my use case!

@samjulien
Copy link

@decafdennis your tabbing stuff works well for me, thanks! The solution @jennifer-shehane posted wasn't working with the "shiftKey" variable for some reason. Tabbed forward but not backward.

@kuceb kuceb added this to the 4.0.0 milestone Jul 30, 2018
@kuceb

This comment has been minimized.

@wilsonpage
Copy link

Just use cypress-real-events, works great.

@harryeastwood
Copy link

This would be a great feature and I don't know why it's not already supported for tabbing between elements. It is required a great deal in most web based workflows.

@arashid-sh
Copy link

arashid-sh commented Aug 24, 2023

Just use cypress-real-events, works great.

just FYI for those who are testing in firefox. cypress-real-events is not supported in firefox

@ghost

This comment was marked as off-topic.

@AlexDaniel
Copy link

@walleyyang could very well be that the way Cypress works does not allow an easy implementation of this. How many more times people need to tell you to use Playwright instead? 😆

@mryellow
Copy link

Just use cypress-real-events, works great.

No. It does not work great.

@jops87
Copy link

jops87 commented Feb 3, 2024

Is there any update on this feature request?

@thomasboyt
Copy link

Will Cypress's new paid accessibility product cover tab navigation of forms and other interactable elements? https://www.cypress.io/blog/2024/02/16/introducing-cypress-accessibility

@WORMSS
Copy link

WORMSS commented Apr 19, 2024

Wow, is this still going on? May I suggest everyone do the correct thing... cough Playwright cough

@mryellow
Copy link

Will Cypress's new paid accessibility product cover tab navigation of forms and other interactable elements? https://www.cypress.io/blog/2024/02/16/introducing-cypress-accessibility

From my read that just checks tags and things exist. Some kind of basic checklist, surely not worth paying for.

While Cypress itself will continue being incapable of actually testing the types of interactions needed to confirm accessibility.

Well the website for the underlying service certainly has the "Use enough contrast as to be painful to look at" part down ;D

https://dequeuniversity.com/checklists/web/

@alexzavg

This comment was marked as off-topic.

@scottohara
Copy link
Contributor

@alexzavg This issue is in relation to Cypress not having support for simulating a press of the TAB key.

It sounds like your comment may be for something related to multiple browser tabs?

@sebb-m0
Copy link

sebb-m0 commented May 21, 2024

I stumbled over this feature today and can't believe, that Cypress does not support the {tab} key since 2016 and still do not support it natively. 😮

+1 for adding {tab} to this list: https://docs.cypress.io/api/commands/type#Arguments

@alexzavg

This comment was marked as off-topic.

@luciarodriguez
Copy link

+1 for adding {tab} to this list: https://docs.cypress.io/api/commands/type#Arguments. Is there any timeline?

@mryellow
Copy link

+1 for adding {tab} to this list: https://docs.cypress.io/api/commands/type#Arguments. Is there any timeline?

It's not that list.

It's that you can't test pressing tab to navigate between fields. Thus can't test accessibility.

It will never be implemented. We're all just hanging out here for the laughs.

@lazarljubenovic
Copy link

lazarljubenovic commented May 27, 2024

The laughs is the only way to play right!

@morrisseybr
Copy link

How can this never have been implemented before? Any news?

@NicholasBoll
Copy link
Contributor

It is the way Cypress interacts with your application. It runs in the same JavaScript context your application does. It is largely what made Cypress so great to work with in the first place. It was before there was a debug protocol to work with. All interactions are simulated. The events fired are not trusted events.

For example, a click event is really a lot of events. There's a mousedown event, a mouseup event, many others, and interactability checks to make sure a real user could actually click on the element. Cypress scrolls to the element, like a user would do. Each browser and operating system and even OS settings change what the tab key does: https://stackblitz.com/edit/testing-browser-button-focus-tab-dltes?file=package.json

The browser does not have a focus management API, meaning there is no way to tell the browser "focus on the next focusable element"

The cypress-real-events use real events sent to the browser (trusted events), but are not synchronous and not in the same JavaScript context as your application. There are tradeoffs which is probably why the entire event system wasn't switched over to use it.

As for if you should be testing what the tab key does... You will get a different result in each browser and operating system. There are edge cases of specifications that have no defined behavior. For example, what should the enter key do on a select element? Browsers don't agree: https://stackblitz.com/edit/native-select-forms-prjaxg

In my cases, I use cypress-real-events (cy.realTab()) when I'm testing the tab key in a controlled way. Meaning I understand that different browsers will consider different elements. Chrome is consistent across operating systems and considers buttons to be focusable, so I only test real tab in Chrome. I use the links above when QA complains about tab order in Firefox or Safari. Usually they have to test in Chrome or enable buttons to be focusable in OSX to test properly in Firefox or Safari in OSX.

@jennifer-shehane jennifer-shehane changed the title Need tab support Need tab key support Dec 12, 2024
@jennifer-shehane jennifer-shehane moved this from Understanding to Designing / Scoping in Cypress App Priorities Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
existing workaround pkg/driver This is due to an issue in the packages/driver directory topic: native events type: feature New feature that does not currently exist
Projects
Status: Designing / Scoping
Development

No branches or pull requests