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

Basic cypress tests for focusing blocks in navigation and edit modes #3399

Closed
wants to merge 1 commit into from

Conversation

ephox-mogran
Copy link
Contributor

Description

Introducing cypress tests for the proposed navigation being discussed in #3195. Essentially, what they test are:

For every block that can be found in the Blocks tab (so perhaps not embed)

  • create the block
  • check that the focus has shifted into the block after being created
  • check that the focus is not on the outer wrapper of the block
  • remember what the focus is on ('previous-focus`)
  • press escape
  • now check that the focus is on the outer wrapper of the block
  • press enter
  • now check that the focus is back to what is was (previous-focus)

The goal is to ensure that switching between navigation and edit mode works for all blocks, and that keyboard focus is initially given to each block once created. At the moment, these tests fail due to:

  • Not all blocks have the inner and outer focusable wrapper required. Many blocks focus the outer wrapper on creation.
  • Navigation Mode vs Editing Mode has not been implemented in general.

How Has This Been Tested?

It is tests. They are all skipped though, because the navigation has not been implemented yet.

Screenshots (jpeg or gifs if applicable):

Types of changes

Adds to the number of tests.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows has proper inline documentation.

@ephox-mogran
Copy link
Contributor Author

So are we happy with how these tests will enforce keyboard navigation? @jasmussen @afercia

  1. That creating a block puts you inside the block?
  2. That pressing escape from there takes you to the outer wrapper of the block?
  3. That pressing enter from the outer wrapper takes you back inside the block?

The selectors being used by the tests were just based on current implementation details in #3195 --- they're not set in stone. These tests aren't prescribing exactly what gets focus. They are really just enforcing that there should be an outer wrapper, and an inner wrapper of some kind, and that escape and enter is used to go between them.

@ephox-mogran ephox-mogran changed the title Basic tests for focusing blocks Basic cypress tests for focusing blocks Nov 9, 2017
@ephox-mogran ephox-mogran changed the title Basic cypress tests for focusing blocks Basic cypress tests for focusing blocks in navigation and edit modes Nov 9, 2017
@jasmussen
Copy link
Contributor

That creating a block puts you inside the block?
That pressing escape from there takes you to the outer wrapper of the block?
That pressing enter from the outer wrapper takes you back inside the block?

This sounds like a good way to start this, yes. If we can get this in, and test, then we can probably do improvements from there. Nice work.

CC: @aduth @youknowriad mind taking a look? Thanks.

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this branch should target the other PR, since we can't merge one without the other right?

@@ -0,0 +1,34 @@
Cypress.Commands.add( 'auditBlockFocus', ( blockType ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this is a global command or would it be better if we just loop over an array of blocks and do this instead in the test directly? My thinking is that this is very specific to this test and no something we want to share across different tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was originally just a forEach in the test. Then, I spit it out into separate tests thinking that I'd use different files for each one. Then I decided to just use one file. Now, it should definitely just be in that one file.

@@ -0,0 +1,34 @@
Cypress.Commands.add( 'auditBlockFocus', ( blockType ) => {
// Open up the Insert Block Menu
cy.get( 'button.editor-inserter__toggle:first' ).click()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent with the way we do actions across tests. Use the same selectors: I'm using .editor-visual-editor [aria-label="Insert block"] because I think we should try to target text and labels instead of classnames as much as we can.

I wonder if something like cy.openInserter() would be a good Idea?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me promote using data attributes like data-test="editor-inserter" again. It would make tests much easier to maintain. In case of any change in the HTML code, you would move data attribute and tests should pass without any modification :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me.

// Type into the Search field for blocks
cy.focused().type( blockType );
// Click on the first result that matches. Note, be careful with things like Image vs Cover Image
cy.get( '.editor-inserter__menu .editor-inserter__block:contains("' + blockType + '"):first' ).click();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re selectors, Is it a good time to introduce data-test attributes? or at least using constants to avoid repeating the selectors over and over again across tests. For example this could be: FIRST_INSERTER_BLOCK

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad we are on the same page. I really need to start reading all comments before I comment anything :)

@youknowriad
Copy link
Contributor

They are really just enforcing that there should be an outer wrapper, and an inner wrapper of some kind,

This is probably not the right PR to ask this question but why do we need an outer/inner wrapper to switch between navigation/edit mode? I don't think we should enforce this on blocks authors (provide an inner focusable elemenet) but just rely on a state value saying that we're on navigation or edit mode to change the behavior of the tabs/arrows.

@ephox-mogran
Copy link
Contributor Author

This is probably not the right PR to ask this question but why do we need an outer/inner wrapper to switch between navigation/edit mode? I don't think we should enforce this on blocks authors (provide an inner focusable elemenet) but just rely on a state value saying that we're on navigation or edit mode to change the behavior of the tabs/arrows.

I've also been wondering about whether a mode state would help here when interpreting arrow keys. However, the inner and outer wrapper aren't just required for handling the differences in navigation and edit mode. I think the idea is that an inner and an outer wrapper are required at least for Editable-based components, because you either have focus in the content editable or you don't (Or in quote's case, multiple editable components). If you don't have focus in the content editable, then you have focus on the block. The requirement to have an inner and an outer wrapper for things like Image is more to do with consistency across different types of widgets. Although, I might have the wrong understanding there. @afercia , are you able to elaborate?

@ephox-mogran
Copy link
Contributor Author

Maybe this branch should target the other PR, since we can't merge one without the other right?

This branch is mostly just an experiment to see how to start making more substantial UI tests. It's the first time I've used cypress as well, so it's not polished. All of the tests here are skipped, so they can be merged at any time. The plan would be to remove each skip when a developer starts working on the focus for a particular block. We could use this test to see how many blocks still require focus management fixes.

If that's not how your preferred approach for using tests though, I understand.

@afercia
Copy link
Contributor

afercia commented Nov 9, 2017

enforcing that there should be an outer wrapper, and an inner wrapper of some kind, and that escape and enter is used to go between them.

This seems to me the most important thing, so 👍

The requirement to have an inner and an outer wrapper for things like Image is more to do with consistency across different types of widgets

I think the most important thing is to standardize the behavior. Editable and non-editable blocks are different in this and Gutenberg should provide some sort of standardization out of the box, without relying on what blocks authors do. About the technical details I don't have a strong opinion. I just think authors shouldn't worry about the navigation/edit mode interaction and Gutenberg should take care of that.

@youknowriad
Copy link
Contributor

About the technical details I don't have a strong opinion. I just think authors shouldn't worry about the navigation/edit mode interaction and Gutenberg should take care of that.

Exactly, that's why I was saying we should force block authors to add inner wrappers. The outer wrapper is "already" standardized and It's totally understandable for "Text" blocks to have an "inner" focusable. Granted, right now we do some "magic" in some of these blocks to focus this inner wrapper when we're in "edit" mode and this logic should be extracted out of the block if possible to make it consistent across all text blocks. One option here is to find "tabbables" in the block content and if the first one is an input/textarea or contenteditable (Maybe we can move the focus there if we find any "tabbable" element, not sure about this though) than we could move focus to this first tabbable element.

@afercia
Copy link
Contributor

afercia commented Nov 9, 2017

we should force block authors to add inner wrappers

Maybe an edge case, but what if a custom block doesn't have focusable elements at all? For example, it could have just settings in the sidebar.

And what about the latest posts widget and similar blocks? Where focus should land when entering edit mode? An inner wrapper provided by Gutenberg would be a standardized, predictable, place to move focus to.

@youknowriad
Copy link
Contributor

An inner wrapper provided by Gutenberg would be a standardized, predictable, place to move focus to.

It's not possible because for text blocks the inner wrapper is provided by the blocks, it's the editable or input or whatever.

For Blocks without any focusable, we can stay on the outer Wrapper and we have our state variable saying that we're on edit (or navigation) mode.

@ephox-mogran
Copy link
Contributor Author

The advantage of testing like this is as soon as decide what we want to do, we can enforce that it works for every block. For example, if we go with what @youknowriad is proposing, we could change these tests to:

  • if there is at least one tabbable inside the block, then the focus should move inside the wrapper to one of these tabbable elements
  • if there are no tabbables inside the block, then the focus should stay on the outer wrapper

Because we aren't being overly prescriptive about where the focus should go (just properties that should hold for the focused element), these types of tests can be relatively flexible. They are approaching the types of property tests made famous by libraries like quickcheck, without the random generation. What having these types of tests do is define the behaviour that we are expecting. Instead of it being a discussion which can get misinterpreted, there is a single place where every assumption is stated. That's why I'm advocating having tests like this. IMO, it makes it much easier to discuss what we actually want to happen, and this particular test is not going to be hard to change.

@ntwb ntwb added the [Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests. label Nov 9, 2017
@gziolo gziolo added the [Status] Stale Gives the original author opportunity to update before closing. Can be reopened as needed. label Mar 8, 2018
@gziolo
Copy link
Member

gziolo commented Mar 8, 2018

@youknowriad @ephox-mogran, what is the status of this one? Is it something that we still get into master or does it need more work? It hasn't been updated for some long time so it might not work with all the changes applied recently.

@youknowriad
Copy link
Contributor

Let's close as this staled for a long time now, fine to reopen if it gets any more activity

@ntwb ntwb deleted the try/cypress-focus-tests branch March 19, 2018 08:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Status] Stale Gives the original author opportunity to update before closing. Can be reopened as needed. [Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants