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 support #299

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

Need tab support #299

robdodson opened this issue Nov 17, 2016 · 39 comments

Comments

@robdodson
Copy link

@robdodson robdodson commented Nov 17, 2016

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 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.

@robdodson
Copy link
Author

@robdodson 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

@brian-mann brian-mann commented Nov 17, 2016

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

@robdodson robdodson commented Nov 18, 2016

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

@kamituel kamituel commented Jul 20, 2017

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

@jennifer-shehane jennifer-shehane commented Oct 30, 2017

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

@protoEvangelion
Copy link

@protoEvangelion protoEvangelion commented Dec 1, 2017

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

@awhill19
Copy link

@awhill19 awhill19 commented Dec 1, 2017

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

@davidszepernick
Copy link

@davidszepernick davidszepernick commented Dec 5, 2017

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

@siemiatj
Copy link

@siemiatj siemiatj commented Feb 28, 2018

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

@mirandashort
Copy link

@mirandashort mirandashort commented Mar 26, 2018

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

@scottschafer
Copy link

@scottschafer 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

@brian-mann brian-mann commented Apr 10, 2018

@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

@jennifer-shehane jennifer-shehane commented Apr 10, 2018

@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

@scottschafer scottschafer commented Apr 10, 2018

@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

@jennifer-shehane jennifer-shehane commented Apr 11, 2018

@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

@lazarljubenovic lazarljubenovic commented May 25, 2018

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

@decafdennis decafdennis commented May 25, 2018

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

@samjulien samjulien commented Jun 12, 2018

@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.

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

This comment has been hidden.

@ryami333
Copy link

@ryami333 ryami333 commented Jan 17, 2019

Sorry to pile-on, but thought I would add my use-case here. Like the OP I am trying to add integration tests to assert that our open-source accessible React component ('React Accessible Accordion') complies with the WAI ARIA spec.

You can see the assertions which I needed to make here.

Unfortunately I didn't realise that Cypress was not going to support this functionality (or the 'end'/'home' keys it seems). I'm going to abandon Cypress because I can already get equivalent functionality out of the incumbent testing suite (Jest + Enzyme).

@jennifer-shehane
Copy link
Member

@jennifer-shehane jennifer-shehane commented Jan 30, 2019

There is an issue with an open PR slated for release in 3.2.0 providing end and home key support here: #2033

@Bkucera
Copy link
Member

@Bkucera Bkucera commented Mar 5, 2019

We're still working on tab support (and other keys) as part of Native Events #311 , but in the meantime I've made a plugin that adds a .tab() command (supports .tab({shift: true}) as well). cypress-plugin-tab:

However, the actual tab implementation will not be a separate command, so know if you use this plugin, you'll have to refactor your test code when Native Events lands

🚨 Please open/discuss issues with the plugin in the issues of the plugin repo, not here 🚨

@nmakuch
Copy link

@nmakuch nmakuch commented Mar 20, 2019

I see there has been talk about implementation for the tab key. I sort of need to trigger keypress and keydown events in most of applications I am testing.

I am looking for a work-around for the arrow keys, spacebar and the enter button.

Basically I have set up some custom key events for accessible keyboard navigation through list items but I have no way of triggering the events through keydown or keypress inside of cypress :S.

I'm really liking cypress and want to continue using it, but dont know how to get around this issue as all the applications we make and test for work need to be accessible.

(tried the work-around above with updated keycodes but that didn't seem to work)

jennifer-shehane added a commit to cypress-io/cypress-documentation that referenced this issue Apr 30, 2019
* Update docs for type - tab support

1. According to cypress-io/cypress#299 (comment), "the actual tab implementation will not be a separate command", so the current documentation "Tabbing will be implemented as a separate command as `.tab()`" is out of date.
2. Users can use cypress-plugin-tab as a temporary fix.
3. Users can follow along with the Native Browser Events issue.

* Fix accidental type.md filename change

* Use hexo tags for links
@jevors
Copy link

@jevors jevors commented May 8, 2019

cypress-plugin-tab

Nice one! I've added it to my project

@adampfoster
Copy link

@adampfoster adampfoster commented Jun 28, 2019

Tab is a no brainer. Currently testing a javascript dropdown box where user types in a country for example and the list shortens per character typed and tab is the way to proceed with what's selected onto the next field. This is easy to use as a human, tab is a natural progression out of this field. Cypress is lacking by not having tab key support. Hope to see it arrive soon.

Update: Cypress plugin tab - https://github.com/Bkucera/cypress-plugin-tab - works very well! However, this plugin shouldn't have a reason to exist. Cypress needs to add this as core functionality.

@kvaternio-dev

This comment was marked as off-topic.

@Svish

This comment was marked as off-topic.

@kvaternio-dev

This comment was marked as off-topic.

@dwilches
Copy link

@dwilches dwilches commented Aug 31, 2019

For people testing dropdowns or autocomplete where you use tab to go to the first suggestion, notice that usually you can also use the arrows to navigate among suggestions, so no need to use the tab plugin, instead you can do something like:

cy.get("[cy-data='newLabelInput']").type("lab{downarrow}{enter}");
@lazarljubenovic
Copy link

@lazarljubenovic lazarljubenovic commented Aug 31, 2019

^ But if we've built our own dropdown/autocomplete, the whole point is to test if the tab works properly.

@arttay
Copy link

@arttay arttay commented Dec 11, 2019

I'm going to throw my support in for this as well.

Screen Shot 2019-12-11 at 7 01 10 AM

This is just the use case thats triggering this comment, but this isnt uncommon throughout web apps or our enterprise ( top 50 in the fortune 500).

We need to test that when a user hits tab, it'll go through each of the top elements, then down to the green level. Currently, its skipping the green layer altogether. We want to be able to automate our accessibility testing, this means checking if a keyboard user can get to various parts of the application. Since tabbing is a large part of that, this seems like a pretty clear value add.

@dinover

This comment was marked as off-topic.

@et1421
Copy link

@et1421 et1421 commented Jan 31, 2020

We are building our own library of components and like to test accessibility.
What about also testing that a user can navigate with the arrow keys in a list of radio buttons and that they can actually select a value using the space key.

I tried using .type('{downarrow}') from the radio button and cy.get('body').trigger('keydown', { key: 'ArrowDown', code: 'ArrowDown', which: 40 }); without any success.

@BrambleRamble
Copy link

@BrambleRamble BrambleRamble commented Jun 23, 2020

Will the ability to type {enter} or (space) on an in-focus button to "press" it be included in this work please?

For my team, this is similarly important to tabbing for testing keyboard navigation flows through our UI. We're using cypress-plugin-tab successfully for tabbing, but using type('{enter}') on in-focus buttons doesn't press them the way that manual interaction does. We are currently using click() on in-focus buttons as a compromise, but ideally we'd like to automate all UI interactions with the keyboard only, with no mouse interaction at all.

@Mikilll94

This comment was marked as off-topic.

panzarino pushed a commit that referenced this issue Sep 2, 2020
Co-authored-by: Gleb Bahmutov <gleb.bahmutov@gmail.com>
@dmtrKovalenko
Copy link
Member

@dmtrKovalenko dmtrKovalenko commented Nov 22, 2020

It is possible to run a native system hover event using CDP. Find the ready-to-use hover command in this package https://github.com/dmtrKovalenko/cypress-real-events.

Fire the native tab switching using

cy.realPress("Tab")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.