From 9ac4720b1cdc8dd7988d3273f2c65f93937660cb Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Wed, 23 Jan 2019 17:12:04 -0500 Subject: [PATCH 01/30] Adding an e2e test verifying simple keyboard navigation through blocks (Issue #12392) using bug resolved in #11773 as the basis for the steps --- .../specs/keyboard-navigable-blocks.test.js | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 packages/e2e-tests/specs/keyboard-navigable-blocks.test.js diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js new file mode 100644 index 00000000000000..bd232c3e11107f --- /dev/null +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -0,0 +1,165 @@ +/** + * WordPress dependencies + */ +import { + createNewPost, + insertBlock, +} from '@wordpress/e2e-test-utils'; + +describe( 'Order of block keyboard navigation', () => { + beforeEach( async () => { + await createNewPost(); + } ); + + it( 'permits tabbing through paragraph blocks in the expected order', async () => { + const paragraphBlocks = [ 'Paragraph 0', 'Paragraph 1', 'Paragraph 2' ]; + + const navigateToContentEditorTop = async () => { + // Use 'Ctrl+`' to return to the top of the editor + await page.keyboard.down( 'Control' ); + await page.keyboard.press( '`' ); + await page.keyboard.press( '`' ); + await page.keyboard.up( 'Control' ); + // Tab into the Title block + await page.keyboard.press( 'Tab' ); + }; + + const tabThroughParagraphBlock = async ( paragraphText ) => { + // Tab to the next paragraph block + await page.keyboard.press( 'Tab' ); + + // The block external focusable wrapper has focus + const isFocusedParagraphBlock = await page.evaluate( + () => document.activeElement.dataset.type + ); + await expect( isFocusedParagraphBlock ).toEqual( 'core/paragraph' ); + + // Tab causes 'add block' button to receive focus + await page.keyboard.press( 'Tab' ); + const isFocusedParagraphInserterToggle = await page.evaluate( () => + document.activeElement.classList.contains( 'editor-inserter__toggle' ) + ); + await expect( isFocusedParagraphInserterToggle ).toBe( true ); + + await tabThroughBlockMoverControl(); + await tabThroughBlockToolbar(); + + // Tab causes the paragraph content to receive focus + await page.keyboard.press( 'Tab' ); + const isFocusedParagraphContent = await page.evaluate( + () => document.activeElement.contentEditable + ); + // The value of 'contentEditable' should be the string 'true' + await expect( isFocusedParagraphContent ).toBe( 'true' ); + + const paragraphEditableContent = await page.evaluate( + () => document.activeElement.innerHTML + ); + await expect( paragraphEditableContent ).toBe( paragraphText ); + }; + + const tabThroughBlockMoverControl = async () => { + // Tab to focus on the 'move up' control + await page.keyboard.press( 'Tab' ); + const isFocusedMoveUpControl = await page.evaluate( () => + document.activeElement.classList.contains( 'editor-block-mover__control' ) + ); + await expect( isFocusedMoveUpControl ).toBe( true ); + + // Tab to focus on the 'move down' control + await page.keyboard.press( 'Tab' ); + const isFocusedMoveDownControl = await page.evaluate( () => + document.activeElement.classList.contains( 'editor-block-mover__control' ) + ); + await expect( isFocusedMoveDownControl ).toBe( true ); + }; + + const tabThroughBlockToolbar = async () => { + // Tab to focus on the 'block switcher' control + await page.keyboard.press( 'Tab' ); + const isFocusedBlockSwitcherControl = await page.evaluate( () => + document.activeElement.classList.contains( + 'editor-block-switcher__toggle' + ) + ); + await expect( isFocusedBlockSwitcherControl ).toBe( true ); + + // Tab to focus on the 'left paragraph alignment' dropdown control + await page.keyboard.press( 'Tab' ); + const isFocusedLeftAlignmentControl = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedLeftAlignmentControl ).toBe( true ); + + // Tab to focus on the 'center paragraph alignment' dropdown control + await page.keyboard.press( 'Tab' ); + const isFocusedCenterAlignmentControl = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedCenterAlignmentControl ).toBe( true ); + + // Tab to focus on the 'right paragraph alignment' dropdown control + await page.keyboard.press( 'Tab' ); + const isFocusedRightAlignmentControl = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedRightAlignmentControl ).toBe( true ); + + // Tab to focus on the 'Bold' formatting button + await page.keyboard.press( 'Tab' ); + const isFocusedBoldFormattingButton = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedBoldFormattingButton ).toBe( true ); + + // Tab to focus on the 'Italic' formatting button + await page.keyboard.press( 'Tab' ); + const isFocusedItalicFormattingButton = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedItalicFormattingButton ).toBe( true ); + + // Tab to focus on the 'Hyperlink' formatting button + await page.keyboard.press( 'Tab' ); + const isFocusedHyperlinkFormattingButton = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedHyperlinkFormattingButton ).toBe( true ); + + // Tab to focus on the 'Strikethrough' formatting button + await page.keyboard.press( 'Tab' ); + const isFocusedStrikethroughFormattingButton = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedStrikethroughFormattingButton ).toBe( true ); + + // Tab to focus on the 'More formatting' dropdown toggle + await page.keyboard.press( 'Tab' ); + const isFocusedMoreFormattingDropdown = await page.evaluate( () => + document.activeElement.classList.contains( + 'editor-block-settings-menu__toggle' + ) + ); + await expect( isFocusedMoreFormattingDropdown ).toBe( true ); + }; + + // create 3 paragraphs blocks with some content + for ( const paragraphBlock of paragraphBlocks ) { + await insertBlock( 'Paragraph' ); + await page.keyboard.type( paragraphBlock ); + await page.keyboard.press( 'Enter' ); + } + + await navigateToContentEditorTop(); + + for ( const paragraphBlock of paragraphBlocks ) { + await tabThroughParagraphBlock( paragraphBlock ); + } + + await navigateToContentEditorTop(); + + for ( const paragraphBlock of paragraphBlocks ) { + await tabThroughParagraphBlock( paragraphBlock ); + } + } ); +} ); From dbdf8fff8a573ca3a2dff1d1cb9a9c2911c7eeb1 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Sun, 24 Feb 2019 11:58:07 -0500 Subject: [PATCH 02/30] Moving `navigateToContentEditorTop`, `tabThroughParagraphBlock`, `tabThroughBlockMoverControl` and `tabThroughBlockToolbar` to the parent scope. Using pressKeyWithModifier within navigateToContentEditorTop. --- .../specs/keyboard-navigable-blocks.test.js | 260 +++++++++--------- 1 file changed, 131 insertions(+), 129 deletions(-) diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index bd232c3e11107f..a35afb34e522ba 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -4,8 +4,137 @@ import { createNewPost, insertBlock, + pressKeyWithModifier, } from '@wordpress/e2e-test-utils'; +const navigateToContentEditorTop = async () => { + // Use 'Ctrl+`' to return to the top of the editor + await pressKeyWithModifier( 'ctrl', '`' ); + await pressKeyWithModifier( 'ctrl', '`' ); + + // Tab into the Title block + await page.keyboard.press( 'Tab' ); +}; + +const tabThroughParagraphBlock = async ( paragraphText ) => { + // Tab to the next paragraph block + await page.keyboard.press( 'Tab' ); + + // The block external focusable wrapper has focus + const isFocusedParagraphBlock = await page.evaluate( + () => document.activeElement.dataset.type + ); + await expect( isFocusedParagraphBlock ).toEqual( 'core/paragraph' ); + + // Tab causes 'add block' button to receive focus + await page.keyboard.press( 'Tab' ); + const isFocusedParagraphInserterToggle = await page.evaluate( () => + document.activeElement.classList.contains( 'editor-inserter__toggle' ) + ); + await expect( isFocusedParagraphInserterToggle ).toBe( true ); + + await tabThroughBlockMoverControl(); + await tabThroughBlockToolbar(); + + // Tab causes the paragraph content to receive focus + await page.keyboard.press( 'Tab' ); + const isFocusedParagraphContent = await page.evaluate( + () => document.activeElement.contentEditable + ); + // The value of 'contentEditable' should be the string 'true' + await expect( isFocusedParagraphContent ).toBe( 'true' ); + + const paragraphEditableContent = await page.evaluate( + () => document.activeElement.innerHTML + ); + await expect( paragraphEditableContent ).toBe( paragraphText ); +}; + +const tabThroughBlockMoverControl = async () => { + // Tab to focus on the 'move up' control + await page.keyboard.press( 'Tab' ); + const isFocusedMoveUpControl = await page.evaluate( () => + document.activeElement.classList.contains( 'editor-block-mover__control' ) + ); + await expect( isFocusedMoveUpControl ).toBe( true ); + + // Tab to focus on the 'move down' control + await page.keyboard.press( 'Tab' ); + const isFocusedMoveDownControl = await page.evaluate( () => + document.activeElement.classList.contains( 'editor-block-mover__control' ) + ); + await expect( isFocusedMoveDownControl ).toBe( true ); +}; + +const tabThroughBlockToolbar = async () => { + // Tab to focus on the 'block switcher' control + await page.keyboard.press( 'Tab' ); + const isFocusedBlockSwitcherControl = await page.evaluate( () => + document.activeElement.classList.contains( + 'editor-block-switcher__toggle' + ) + ); + await expect( isFocusedBlockSwitcherControl ).toBe( true ); + + // Tab to focus on the 'left paragraph alignment' dropdown control + await page.keyboard.press( 'Tab' ); + const isFocusedLeftAlignmentControl = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedLeftAlignmentControl ).toBe( true ); + + // Tab to focus on the 'center paragraph alignment' dropdown control + await page.keyboard.press( 'Tab' ); + const isFocusedCenterAlignmentControl = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedCenterAlignmentControl ).toBe( true ); + + // Tab to focus on the 'right paragraph alignment' dropdown control + await page.keyboard.press( 'Tab' ); + const isFocusedRightAlignmentControl = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedRightAlignmentControl ).toBe( true ); + + // Tab to focus on the 'Bold' formatting button + await page.keyboard.press( 'Tab' ); + const isFocusedBoldFormattingButton = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedBoldFormattingButton ).toBe( true ); + + // Tab to focus on the 'Italic' formatting button + await page.keyboard.press( 'Tab' ); + const isFocusedItalicFormattingButton = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedItalicFormattingButton ).toBe( true ); + + // Tab to focus on the 'Hyperlink' formatting button + await page.keyboard.press( 'Tab' ); + const isFocusedHyperlinkFormattingButton = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedHyperlinkFormattingButton ).toBe( true ); + + // Tab to focus on the 'Strikethrough' formatting button + await page.keyboard.press( 'Tab' ); + const isFocusedStrikethroughFormattingButton = await page.evaluate( () => + document.activeElement.classList.contains( 'components-toolbar__control' ) + ); + await expect( isFocusedStrikethroughFormattingButton ).toBe( true ); + + // Tab to focus on the 'More formatting' dropdown toggle + await page.keyboard.press( 'Tab' ); + const isFocusedMoreFormattingDropdown = await page.evaluate( () => + document.activeElement.classList.contains( + 'editor-block-settings-menu__toggle' + ) + ); + await expect( isFocusedMoreFormattingDropdown ).toBe( true ); +}; + describe( 'Order of block keyboard navigation', () => { beforeEach( async () => { await createNewPost(); @@ -14,135 +143,6 @@ describe( 'Order of block keyboard navigation', () => { it( 'permits tabbing through paragraph blocks in the expected order', async () => { const paragraphBlocks = [ 'Paragraph 0', 'Paragraph 1', 'Paragraph 2' ]; - const navigateToContentEditorTop = async () => { - // Use 'Ctrl+`' to return to the top of the editor - await page.keyboard.down( 'Control' ); - await page.keyboard.press( '`' ); - await page.keyboard.press( '`' ); - await page.keyboard.up( 'Control' ); - // Tab into the Title block - await page.keyboard.press( 'Tab' ); - }; - - const tabThroughParagraphBlock = async ( paragraphText ) => { - // Tab to the next paragraph block - await page.keyboard.press( 'Tab' ); - - // The block external focusable wrapper has focus - const isFocusedParagraphBlock = await page.evaluate( - () => document.activeElement.dataset.type - ); - await expect( isFocusedParagraphBlock ).toEqual( 'core/paragraph' ); - - // Tab causes 'add block' button to receive focus - await page.keyboard.press( 'Tab' ); - const isFocusedParagraphInserterToggle = await page.evaluate( () => - document.activeElement.classList.contains( 'editor-inserter__toggle' ) - ); - await expect( isFocusedParagraphInserterToggle ).toBe( true ); - - await tabThroughBlockMoverControl(); - await tabThroughBlockToolbar(); - - // Tab causes the paragraph content to receive focus - await page.keyboard.press( 'Tab' ); - const isFocusedParagraphContent = await page.evaluate( - () => document.activeElement.contentEditable - ); - // The value of 'contentEditable' should be the string 'true' - await expect( isFocusedParagraphContent ).toBe( 'true' ); - - const paragraphEditableContent = await page.evaluate( - () => document.activeElement.innerHTML - ); - await expect( paragraphEditableContent ).toBe( paragraphText ); - }; - - const tabThroughBlockMoverControl = async () => { - // Tab to focus on the 'move up' control - await page.keyboard.press( 'Tab' ); - const isFocusedMoveUpControl = await page.evaluate( () => - document.activeElement.classList.contains( 'editor-block-mover__control' ) - ); - await expect( isFocusedMoveUpControl ).toBe( true ); - - // Tab to focus on the 'move down' control - await page.keyboard.press( 'Tab' ); - const isFocusedMoveDownControl = await page.evaluate( () => - document.activeElement.classList.contains( 'editor-block-mover__control' ) - ); - await expect( isFocusedMoveDownControl ).toBe( true ); - }; - - const tabThroughBlockToolbar = async () => { - // Tab to focus on the 'block switcher' control - await page.keyboard.press( 'Tab' ); - const isFocusedBlockSwitcherControl = await page.evaluate( () => - document.activeElement.classList.contains( - 'editor-block-switcher__toggle' - ) - ); - await expect( isFocusedBlockSwitcherControl ).toBe( true ); - - // Tab to focus on the 'left paragraph alignment' dropdown control - await page.keyboard.press( 'Tab' ); - const isFocusedLeftAlignmentControl = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedLeftAlignmentControl ).toBe( true ); - - // Tab to focus on the 'center paragraph alignment' dropdown control - await page.keyboard.press( 'Tab' ); - const isFocusedCenterAlignmentControl = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedCenterAlignmentControl ).toBe( true ); - - // Tab to focus on the 'right paragraph alignment' dropdown control - await page.keyboard.press( 'Tab' ); - const isFocusedRightAlignmentControl = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedRightAlignmentControl ).toBe( true ); - - // Tab to focus on the 'Bold' formatting button - await page.keyboard.press( 'Tab' ); - const isFocusedBoldFormattingButton = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedBoldFormattingButton ).toBe( true ); - - // Tab to focus on the 'Italic' formatting button - await page.keyboard.press( 'Tab' ); - const isFocusedItalicFormattingButton = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedItalicFormattingButton ).toBe( true ); - - // Tab to focus on the 'Hyperlink' formatting button - await page.keyboard.press( 'Tab' ); - const isFocusedHyperlinkFormattingButton = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedHyperlinkFormattingButton ).toBe( true ); - - // Tab to focus on the 'Strikethrough' formatting button - await page.keyboard.press( 'Tab' ); - const isFocusedStrikethroughFormattingButton = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedStrikethroughFormattingButton ).toBe( true ); - - // Tab to focus on the 'More formatting' dropdown toggle - await page.keyboard.press( 'Tab' ); - const isFocusedMoreFormattingDropdown = await page.evaluate( () => - document.activeElement.classList.contains( - 'editor-block-settings-menu__toggle' - ) - ); - await expect( isFocusedMoreFormattingDropdown ).toBe( true ); - }; - // create 3 paragraphs blocks with some content for ( const paragraphBlock of paragraphBlocks ) { await insertBlock( 'Paragraph' ); @@ -156,6 +156,8 @@ describe( 'Order of block keyboard navigation', () => { await tabThroughParagraphBlock( paragraphBlock ); } + // Repeat the same steps to ensure that there is no change introduced in how the focus is handled. + // This prevents the previous regression explained in: https://github.com/WordPress/gutenberg/issues/11773. await navigateToContentEditorTop(); for ( const paragraphBlock of paragraphBlocks ) { From 7246607bb3066db1fd3c2e27a611cb8cf09d586d Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Sun, 24 Feb 2019 12:41:07 -0500 Subject: [PATCH 03/30] Rewriting tabThroughBlockToolbar to allow it to tab through any block's toolbar buttons --- .../specs/keyboard-navigable-blocks.test.js | 78 ++++--------------- 1 file changed, 13 insertions(+), 65 deletions(-) diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index a35afb34e522ba..5756d86acfaf69 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -67,72 +67,20 @@ const tabThroughBlockMoverControl = async () => { }; const tabThroughBlockToolbar = async () => { - // Tab to focus on the 'block switcher' control - await page.keyboard.press( 'Tab' ); - const isFocusedBlockSwitcherControl = await page.evaluate( () => - document.activeElement.classList.contains( - 'editor-block-switcher__toggle' - ) - ); - await expect( isFocusedBlockSwitcherControl ).toBe( true ); - - // Tab to focus on the 'left paragraph alignment' dropdown control - await page.keyboard.press( 'Tab' ); - const isFocusedLeftAlignmentControl = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedLeftAlignmentControl ).toBe( true ); - - // Tab to focus on the 'center paragraph alignment' dropdown control - await page.keyboard.press( 'Tab' ); - const isFocusedCenterAlignmentControl = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedCenterAlignmentControl ).toBe( true ); - - // Tab to focus on the 'right paragraph alignment' dropdown control - await page.keyboard.press( 'Tab' ); - const isFocusedRightAlignmentControl = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedRightAlignmentControl ).toBe( true ); - - // Tab to focus on the 'Bold' formatting button - await page.keyboard.press( 'Tab' ); - const isFocusedBoldFormattingButton = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedBoldFormattingButton ).toBe( true ); - - // Tab to focus on the 'Italic' formatting button - await page.keyboard.press( 'Tab' ); - const isFocusedItalicFormattingButton = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedItalicFormattingButton ).toBe( true ); - - // Tab to focus on the 'Hyperlink' formatting button - await page.keyboard.press( 'Tab' ); - const isFocusedHyperlinkFormattingButton = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedHyperlinkFormattingButton ).toBe( true ); - - // Tab to focus on the 'Strikethrough' formatting button - await page.keyboard.press( 'Tab' ); - const isFocusedStrikethroughFormattingButton = await page.evaluate( () => - document.activeElement.classList.contains( 'components-toolbar__control' ) - ); - await expect( isFocusedStrikethroughFormattingButton ).toBe( true ); + const blockToolbarButtons = await page.evaluate( () => { + // return an array with the classNames of the block toolbar's buttons + return [].slice.call( + document.querySelectorAll( '.editor-block-contextual-toolbar button' ) + ).map( ( elem ) => elem.className ); + } ); - // Tab to focus on the 'More formatting' dropdown toggle - await page.keyboard.press( 'Tab' ); - const isFocusedMoreFormattingDropdown = await page.evaluate( () => - document.activeElement.classList.contains( - 'editor-block-settings-menu__toggle' - ) - ); - await expect( isFocusedMoreFormattingDropdown ).toBe( true ); + for ( const buttonClassName of blockToolbarButtons ) { + await page.keyboard.press( 'Tab' ); + const focusedBlockToolBarButton = await page.evaluate( () => + document.activeElement.className + ); + await expect( focusedBlockToolBarButton ).toEqual( buttonClassName ); + } }; describe( 'Order of block keyboard navigation', () => { From 267cb0ed2b6fcfa3659bd5ea5316e3b3a1041cb4 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Wed, 6 Mar 2019 22:28:33 -0500 Subject: [PATCH 04/30] Moving navigateToContentEditorTop, tabThroughBlockMoverControl, and tabThroughBlockToolbar to e2e-test-utils --- packages/e2e-test-utils/src/index.js | 3 ++ .../src/navigate-to-content-editor-top.js | 14 ++++++ .../src/tab-through-block-mover-control.js | 18 ++++++++ .../src/tab-through-block-toolbar.js | 20 ++++++++ .../specs/keyboard-navigable-blocks.test.js | 46 ++----------------- 5 files changed, 58 insertions(+), 43 deletions(-) create mode 100644 packages/e2e-test-utils/src/navigate-to-content-editor-top.js create mode 100644 packages/e2e-test-utils/src/tab-through-block-mover-control.js create mode 100644 packages/e2e-test-utils/src/tab-through-block-toolbar.js diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 5534c981f46a9e..a5f312fe146f95 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -21,6 +21,7 @@ export { insertBlock } from './insert-block'; export { installPlugin } from './install-plugin'; export { isCurrentURL } from './is-current-url'; export { loginUser } from './login-user'; +export { navigateToContentEditorTop } from './navigate-to-content-editor-top'; export { observeFocusLoss } from './observe-focus-loss'; export { openDocumentSettingsSidebar } from './open-document-settings-sidebar'; export { openPublishPanel } from './open-publish-panel'; @@ -36,6 +37,8 @@ export { setPostContent } from './set-post-content'; export { switchEditorModeTo } from './switch-editor-mode-to'; export { switchUserToAdmin } from './switch-user-to-admin'; export { switchUserToTest } from './switch-user-to-test'; +export { tabThroughBlockMoverControl } from './tab-through-block-mover-control'; +export { tabThroughBlockToolbar } from './tab-through-block-toolbar'; export { toggleScreenOption } from './toggle-screen-option'; export { transformBlockTo } from './transform-block-to'; export { uninstallPlugin } from './uninstall-plugin'; diff --git a/packages/e2e-test-utils/src/navigate-to-content-editor-top.js b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js new file mode 100644 index 00000000000000..e67889b7b6e116 --- /dev/null +++ b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js @@ -0,0 +1,14 @@ +/** + * Navigate to the top of the content editor using the keyboard + */ + +import { pressKeyWithModifier } from './press-key-with-modifier'; + +export async function navigateToContentEditorTop() { + // Use 'Ctrl+`' to return to the top of the editor + await pressKeyWithModifier( 'ctrl', '`' ); + await pressKeyWithModifier( 'ctrl', '`' ); + + // Tab into the Title block + await page.keyboard.press( 'Tab' ); +} diff --git a/packages/e2e-test-utils/src/tab-through-block-mover-control.js b/packages/e2e-test-utils/src/tab-through-block-mover-control.js new file mode 100644 index 00000000000000..b11d46a7beffc4 --- /dev/null +++ b/packages/e2e-test-utils/src/tab-through-block-mover-control.js @@ -0,0 +1,18 @@ +/** + * Navigate through the block mover control using the keyboard + */ +export async function tabThroughBlockMoverControl() { + // Tab to focus on the 'move up' control + await page.keyboard.press( 'Tab' ); + const isFocusedMoveUpControl = await page.evaluate( () => + document.activeElement.classList.contains( 'editor-block-mover__control' ) + ); + await expect( isFocusedMoveUpControl ).toBe( true ); + + // Tab to focus on the 'move down' control + await page.keyboard.press( 'Tab' ); + const isFocusedMoveDownControl = await page.evaluate( () => + document.activeElement.classList.contains( 'editor-block-mover__control' ) + ); + await expect( isFocusedMoveDownControl ).toBe( true ); +} diff --git a/packages/e2e-test-utils/src/tab-through-block-toolbar.js b/packages/e2e-test-utils/src/tab-through-block-toolbar.js new file mode 100644 index 00000000000000..c7daaa658267ba --- /dev/null +++ b/packages/e2e-test-utils/src/tab-through-block-toolbar.js @@ -0,0 +1,20 @@ +/** + * Navigate through a block's toolbar using the keyboard + */ + +export async function tabThroughBlockToolbar() { + const blockToolbarButtons = await page.evaluate( () => { + // return an array with the classNames of the block toolbar's buttons + return [].slice.call( + document.querySelectorAll( '.editor-block-contextual-toolbar button' ) + ).map( ( elem ) => elem.className ); + } ); + + for ( const buttonClassName of blockToolbarButtons ) { + await page.keyboard.press( 'Tab' ); + const focusedBlockToolBarButton = await page.evaluate( () => + document.activeElement.className + ); + await expect( focusedBlockToolBarButton ).toEqual( buttonClassName ); + } +} diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index 5756d86acfaf69..422e209cf37513 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -4,18 +4,11 @@ import { createNewPost, insertBlock, - pressKeyWithModifier, + navigateToContentEditorTop, + tabThroughBlockMoverControl, + tabThroughBlockToolbar, } from '@wordpress/e2e-test-utils'; -const navigateToContentEditorTop = async () => { - // Use 'Ctrl+`' to return to the top of the editor - await pressKeyWithModifier( 'ctrl', '`' ); - await pressKeyWithModifier( 'ctrl', '`' ); - - // Tab into the Title block - await page.keyboard.press( 'Tab' ); -}; - const tabThroughParagraphBlock = async ( paragraphText ) => { // Tab to the next paragraph block await page.keyboard.press( 'Tab' ); @@ -50,39 +43,6 @@ const tabThroughParagraphBlock = async ( paragraphText ) => { await expect( paragraphEditableContent ).toBe( paragraphText ); }; -const tabThroughBlockMoverControl = async () => { - // Tab to focus on the 'move up' control - await page.keyboard.press( 'Tab' ); - const isFocusedMoveUpControl = await page.evaluate( () => - document.activeElement.classList.contains( 'editor-block-mover__control' ) - ); - await expect( isFocusedMoveUpControl ).toBe( true ); - - // Tab to focus on the 'move down' control - await page.keyboard.press( 'Tab' ); - const isFocusedMoveDownControl = await page.evaluate( () => - document.activeElement.classList.contains( 'editor-block-mover__control' ) - ); - await expect( isFocusedMoveDownControl ).toBe( true ); -}; - -const tabThroughBlockToolbar = async () => { - const blockToolbarButtons = await page.evaluate( () => { - // return an array with the classNames of the block toolbar's buttons - return [].slice.call( - document.querySelectorAll( '.editor-block-contextual-toolbar button' ) - ).map( ( elem ) => elem.className ); - } ); - - for ( const buttonClassName of blockToolbarButtons ) { - await page.keyboard.press( 'Tab' ); - const focusedBlockToolBarButton = await page.evaluate( () => - document.activeElement.className - ); - await expect( focusedBlockToolBarButton ).toEqual( buttonClassName ); - } -}; - describe( 'Order of block keyboard navigation', () => { beforeEach( async () => { await createNewPost(); From f0da33de87cb0c410c8e22c5042cc4875153e246 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Thu, 23 May 2019 11:33:21 -0400 Subject: [PATCH 05/30] Updating block editor classNames to convention - tab-through-block-toolbar, tab-through-block-mover-control, keyboard-navigable-blocks-test. Add some detail to JSDocs --- packages/e2e-test-utils/README.md | 12 ++++++++++++ .../src/navigate-to-content-editor-top.js | 2 +- .../src/tab-through-block-mover-control.js | 6 +++--- .../e2e-test-utils/src/tab-through-block-toolbar.js | 4 ++-- .../specs/keyboard-navigable-blocks.test.js | 2 +- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 7cb439d46fc4eb..8180e554d4da69 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -300,6 +300,10 @@ _Returns_ - `Promise`: Promise that uses `mockCheck` to see if a request should be mocked with `mock`, and optionally transforms the response with `responseObjectTransform`. +# **navigateToContentEditorTop** + +Undocumented declaration. + # **observeFocusLoss** Binds to the document on page load which throws an error if a `focusout` @@ -454,6 +458,14 @@ running the test is not already the admin user). Switches the current user to whichever user we should be running the tests as (if we're not already that user). +# **tabThroughBlockMoverControl** + +Navigate through the block mover control using the keyboard + +# **tabThroughBlockToolbar** + +Navigate through a block's toolbar using the keyboard + # **toggleScreenOption** Toggles the screen option with the given label. diff --git a/packages/e2e-test-utils/src/navigate-to-content-editor-top.js b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js index 6ef8561a6ce3cd..3b74f1c840fdcd 100644 --- a/packages/e2e-test-utils/src/navigate-to-content-editor-top.js +++ b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js @@ -1,5 +1,5 @@ /** - * Navigate to the top of the content editor using the keyboard + * Navigates to the top of the content editor using the keyboard. */ /** diff --git a/packages/e2e-test-utils/src/tab-through-block-mover-control.js b/packages/e2e-test-utils/src/tab-through-block-mover-control.js index b11d46a7beffc4..6ddb983cb902c5 100644 --- a/packages/e2e-test-utils/src/tab-through-block-mover-control.js +++ b/packages/e2e-test-utils/src/tab-through-block-mover-control.js @@ -1,18 +1,18 @@ /** - * Navigate through the block mover control using the keyboard + * Navigates through the block mover control using the keyboard. Asserts that the 'move up' and 'move down' controls receive focus. */ export async function tabThroughBlockMoverControl() { // Tab to focus on the 'move up' control await page.keyboard.press( 'Tab' ); const isFocusedMoveUpControl = await page.evaluate( () => - document.activeElement.classList.contains( 'editor-block-mover__control' ) + document.activeElement.classList.contains( 'block-editor-block-mover__control' ) ); await expect( isFocusedMoveUpControl ).toBe( true ); // Tab to focus on the 'move down' control await page.keyboard.press( 'Tab' ); const isFocusedMoveDownControl = await page.evaluate( () => - document.activeElement.classList.contains( 'editor-block-mover__control' ) + document.activeElement.classList.contains( 'block-editor-block-mover__control' ) ); await expect( isFocusedMoveDownControl ).toBe( true ); } diff --git a/packages/e2e-test-utils/src/tab-through-block-toolbar.js b/packages/e2e-test-utils/src/tab-through-block-toolbar.js index c7daaa658267ba..bfb9331558e7c0 100644 --- a/packages/e2e-test-utils/src/tab-through-block-toolbar.js +++ b/packages/e2e-test-utils/src/tab-through-block-toolbar.js @@ -1,12 +1,12 @@ /** - * Navigate through a block's toolbar using the keyboard + * Navigate through a block's toolbar using the keyboard. Asserts that each button receives focus. */ export async function tabThroughBlockToolbar() { const blockToolbarButtons = await page.evaluate( () => { // return an array with the classNames of the block toolbar's buttons return [].slice.call( - document.querySelectorAll( '.editor-block-contextual-toolbar button' ) + document.querySelectorAll( '.block-editor-block-contextual-toolbar button' ) ).map( ( elem ) => elem.className ); } ); diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index 422e209cf37513..f21c6b9622821f 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -22,7 +22,7 @@ const tabThroughParagraphBlock = async ( paragraphText ) => { // Tab causes 'add block' button to receive focus await page.keyboard.press( 'Tab' ); const isFocusedParagraphInserterToggle = await page.evaluate( () => - document.activeElement.classList.contains( 'editor-inserter__toggle' ) + document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) ); await expect( isFocusedParagraphInserterToggle ).toBe( true ); From 2b62a21ae163c34cbe663c1cc99ef870534aa8bd Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Thu, 23 May 2019 11:34:28 -0400 Subject: [PATCH 06/30] Updating e2e-test-utils readme --- packages/e2e-test-utils/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 8180e554d4da69..3c1cd82ba6e9eb 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -460,11 +460,11 @@ running the tests as (if we're not already that user). # **tabThroughBlockMoverControl** -Navigate through the block mover control using the keyboard +Navigates through the block mover control using the keyboard. Asserts that the 'move up' and 'move down' controls receive focus. # **tabThroughBlockToolbar** -Navigate through a block's toolbar using the keyboard +Navigate through a block's toolbar using the keyboard. Asserts that each button receives focus. # **toggleScreenOption** From 0b3d0a4ce44bdc20cb766934e34550b3c31f3984 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Sun, 26 May 2019 09:05:50 -0400 Subject: [PATCH 07/30] WIP - refactoring keyboard navigability tests to handle all the default block types --- .../specs/keyboard-navigable-blocks.test.js | 103 ++++++++++++++---- 1 file changed, 79 insertions(+), 24 deletions(-) diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index f21c6b9622821f..99d4ed40fd9bfa 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -8,60 +8,115 @@ import { tabThroughBlockMoverControl, tabThroughBlockToolbar, } from '@wordpress/e2e-test-utils'; +/** + * External dependencies + */ -const tabThroughParagraphBlock = async ( paragraphText ) => { - // Tab to the next paragraph block - await page.keyboard.press( 'Tab' ); - +const externalWrapperHasFocus = async ( blockType ) => { // The block external focusable wrapper has focus - const isFocusedParagraphBlock = await page.evaluate( + const isFocusedBlock = await page.evaluate( () => document.activeElement.dataset.type ); - await expect( isFocusedParagraphBlock ).toEqual( 'core/paragraph' ); + await expect( isFocusedBlock ).toEqual( blockType ); +}; - // Tab causes 'add block' button to receive focus - await page.keyboard.press( 'Tab' ); - const isFocusedParagraphInserterToggle = await page.evaluate( () => +const inserterToggleHasFocus = async () => { + const isFocusedInserterToggle = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) ); - await expect( isFocusedParagraphInserterToggle ).toBe( true ); + await expect( isFocusedInserterToggle ).toBe( true ); +}; + +const blockContentAreas = async () => { + return await page.evaluate( () => { + // return an array with the classNames of the block toolbar's buttons + return [].slice + .call( + document.querySelectorAll( + '.wp-block.is-selected [contenteditable], .wp-block.is-typing [contenteditable]' + ) + ) + .map( ( elem ) => elem.className ); + } ); +}; +const blockContenAreasHaveFocus = async ( content ) => { + const blocks = await blockContentAreas(); + const isFocusedBlockContentArea = async () => { + return await page.evaluate( () => document.activeElement.contentEditable ); + }; + const blockContentAreaContent = async () => { + return await page.evaluate( () => document.activeElement.innerHTML ); + }; + for ( let i = 0; i < blocks.length; i++ ) { + if ( i > 0 ) { + await page.keyboard.press( 'Tab' ); + } + + // The value of 'contentEditable' should be the string 'true' + await expect( await isFocusedBlockContentArea() ).toBe( 'true' ); + await expect( await blockContentAreaContent() ).toContain( content ); + } +}; + +const tabThroughBlock = async ( content, blockType ) => { + // Tab to the next paragraph block + await page.keyboard.press( 'Tab' ); + await externalWrapperHasFocus( blockType ); + + // Tab causes 'add block' button to receive focus + await page.keyboard.press( 'Tab' ); + await inserterToggleHasFocus(); await tabThroughBlockMoverControl(); await tabThroughBlockToolbar(); // Tab causes the paragraph content to receive focus await page.keyboard.press( 'Tab' ); - const isFocusedParagraphContent = await page.evaluate( - () => document.activeElement.contentEditable - ); - // The value of 'contentEditable' should be the string 'true' - await expect( isFocusedParagraphContent ).toBe( 'true' ); + await blockContenAreasHaveFocus( content ); +}; - const paragraphEditableContent = await page.evaluate( - () => document.activeElement.innerHTML - ); - await expect( paragraphEditableContent ).toBe( paragraphText ); +const insertAndPopulateBlock = async ( blockName, content ) => { + await insertBlock( blockName ); + await page.keyboard.type( content ); + + const blocks = await blockContentAreas(); + for ( let i = 0; i < blocks.length - 1; i++ ) { + await page.keyboard.press( 'Tab' ); + await page.keyboard.type( content ); + } + await page.keyboard.press( 'Enter' ); }; describe( 'Order of block keyboard navigation', () => { beforeEach( async () => { await createNewPost(); } ); + it( 'permits tabbing through blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Heading', 'Heading Block Content' ); + await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block Content' ); + await insertAndPopulateBlock( 'Quote', 'Quote Block Content' ); + await insertAndPopulateBlock( 'List', 'List Block Content' ); + + await navigateToContentEditorTop(); + + await tabThroughBlock( 'Heading Block Content', 'core/heading' ); + await tabThroughBlock( 'Paragraph Block Content', 'core/paragraph' ); + await tabThroughBlock( 'Quote Block Content', 'core/quote' ); + await tabThroughBlock( 'List Block Content', 'core/list' ); + } ); it( 'permits tabbing through paragraph blocks in the expected order', async () => { const paragraphBlocks = [ 'Paragraph 0', 'Paragraph 1', 'Paragraph 2' ]; // create 3 paragraphs blocks with some content for ( const paragraphBlock of paragraphBlocks ) { - await insertBlock( 'Paragraph' ); - await page.keyboard.type( paragraphBlock ); - await page.keyboard.press( 'Enter' ); + await insertAndPopulateBlock( 'Paragraph', paragraphBlock ); } await navigateToContentEditorTop(); for ( const paragraphBlock of paragraphBlocks ) { - await tabThroughParagraphBlock( paragraphBlock ); + await tabThroughBlock( paragraphBlock, 'core/paragraph' ); } // Repeat the same steps to ensure that there is no change introduced in how the focus is handled. @@ -69,7 +124,7 @@ describe( 'Order of block keyboard navigation', () => { await navigateToContentEditorTop(); for ( const paragraphBlock of paragraphBlocks ) { - await tabThroughParagraphBlock( paragraphBlock ); + await tabThroughBlock( paragraphBlock, 'core/paragraph' ); } } ); } ); From 6365c7e21cc325dc23cf962463da509b88d76c60 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 27 May 2019 22:49:07 -0400 Subject: [PATCH 08/30] WIP - successfully tabbing through all core content block types --- .../src/tab-through-block-toolbar.js | 2 +- .../specs/keyboard-navigable-blocks.test.js | 76 ++++++++++++++----- 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/packages/e2e-test-utils/src/tab-through-block-toolbar.js b/packages/e2e-test-utils/src/tab-through-block-toolbar.js index bfb9331558e7c0..7ffb1dc694d225 100644 --- a/packages/e2e-test-utils/src/tab-through-block-toolbar.js +++ b/packages/e2e-test-utils/src/tab-through-block-toolbar.js @@ -6,7 +6,7 @@ export async function tabThroughBlockToolbar() { const blockToolbarButtons = await page.evaluate( () => { // return an array with the classNames of the block toolbar's buttons return [].slice.call( - document.querySelectorAll( '.block-editor-block-contextual-toolbar button' ) + document.querySelectorAll( '.block-editor-block-contextual-toolbar button:not([disabled])' ) ).map( ( elem ) => elem.className ); } ); diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index 99d4ed40fd9bfa..1396fb545e4d1e 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -8,6 +8,7 @@ import { tabThroughBlockMoverControl, tabThroughBlockToolbar, } from '@wordpress/e2e-test-utils'; + /** * External dependencies */ @@ -27,7 +28,7 @@ const inserterToggleHasFocus = async () => { await expect( isFocusedInserterToggle ).toBe( true ); }; -const blockContentAreas = async () => { +const textContentAreas = async () => { return await page.evaluate( () => { // return an array with the classNames of the block toolbar's buttons return [].slice @@ -39,12 +40,29 @@ const blockContentAreas = async () => { .map( ( elem ) => elem.className ); } ); }; -const blockContenAreasHaveFocus = async ( content ) => { - const blocks = await blockContentAreas(); - const isFocusedBlockContentArea = async () => { + +export async function tabThroughPlaceholderButtons() { + const placeholderButtons = await page.evaluate( () => { + // return an array with the classNames of the block toolbar's buttons + return [].slice.call( + document.querySelectorAll( '.wp-block.is-selected .block-editor-media-placeholder button:not([disabled])' ) + ).map( ( elem ) => elem.className ); + } ); + + for ( const buttonClassName of placeholderButtons ) { + await page.keyboard.press( 'Tab' ); + const focusePlaceholderButton = await page.evaluate( () => + document.activeElement.className + ); + await expect( focusePlaceholderButton ).toEqual( buttonClassName ); + } +} +const textContentAreasHaveFocus = async ( content ) => { + const blocks = await textContentAreas(); + const isFocusedTextContentArea = async () => { return await page.evaluate( () => document.activeElement.contentEditable ); }; - const blockContentAreaContent = async () => { + const textContentAreaContent = async () => { return await page.evaluate( () => document.activeElement.innerHTML ); }; for ( let i = 0; i < blocks.length; i++ ) { @@ -53,12 +71,12 @@ const blockContenAreasHaveFocus = async ( content ) => { } // The value of 'contentEditable' should be the string 'true' - await expect( await isFocusedBlockContentArea() ).toBe( 'true' ); - await expect( await blockContentAreaContent() ).toContain( content ); + await expect( await isFocusedTextContentArea() ).toBe( 'true' ); + await expect( await textContentAreaContent() ).toContain( content ); } }; -const tabThroughBlock = async ( content, blockType ) => { +const tabThroughTextBlock = async ( content, blockType ) => { // Tab to the next paragraph block await page.keyboard.press( 'Tab' ); await externalWrapperHasFocus( blockType ); @@ -72,14 +90,28 @@ const tabThroughBlock = async ( content, blockType ) => { // Tab causes the paragraph content to receive focus await page.keyboard.press( 'Tab' ); - await blockContenAreasHaveFocus( content ); + await textContentAreasHaveFocus( content ); +}; + +const tabThroughFileBlock = async ( content, blockType ) => { + // Tab to the next block + await page.keyboard.press( 'Tab' ); + await externalWrapperHasFocus( blockType ); + + // Tab causes 'add block' button to receive focus + await page.keyboard.press( 'Tab' ); + await inserterToggleHasFocus(); + + await tabThroughBlockMoverControl(); + await tabThroughBlockToolbar(); + await tabThroughPlaceholderButtons(); }; const insertAndPopulateBlock = async ( blockName, content ) => { await insertBlock( blockName ); await page.keyboard.type( content ); - const blocks = await blockContentAreas(); + const blocks = await textContentAreas(); for ( let i = 0; i < blocks.length - 1; i++ ) { await page.keyboard.press( 'Tab' ); await page.keyboard.type( content ); @@ -93,16 +125,26 @@ describe( 'Order of block keyboard navigation', () => { } ); it( 'permits tabbing through blocks in the expected order', async () => { await insertAndPopulateBlock( 'Heading', 'Heading Block Content' ); - await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block Content' ); await insertAndPopulateBlock( 'Quote', 'Quote Block Content' ); await insertAndPopulateBlock( 'List', 'List Block Content' ); + await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block Content' ); + await insertAndPopulateBlock( 'Image', 'Image Block Content' ); + await insertAndPopulateBlock( 'Gallery', 'Gallery Block Content' ); + await insertAndPopulateBlock( 'Audio', 'Audio Block Content' ); + await insertAndPopulateBlock( 'Cover', 'Cover Block Content' ); + await insertAndPopulateBlock( 'File', 'File Block Content' ); await navigateToContentEditorTop(); - await tabThroughBlock( 'Heading Block Content', 'core/heading' ); - await tabThroughBlock( 'Paragraph Block Content', 'core/paragraph' ); - await tabThroughBlock( 'Quote Block Content', 'core/quote' ); - await tabThroughBlock( 'List Block Content', 'core/list' ); + await tabThroughTextBlock( 'Heading Block Content', 'core/heading' ); + await tabThroughTextBlock( 'Quote Block Content', 'core/quote' ); + await tabThroughTextBlock( 'List Block Content', 'core/list' ); + await tabThroughTextBlock( 'Paragraph Block Content', 'core/paragraph' ); + await tabThroughFileBlock( 'Image Block Content', 'core/image' ); + await tabThroughFileBlock( 'Gallery Block Content', 'core/gallery' ); + await tabThroughFileBlock( 'Audio Block Content', 'core/audio' ); + await tabThroughFileBlock( 'Cover Block Content', 'core/cover' ); + await tabThroughFileBlock( 'File Block Content', 'core/file' ); } ); it( 'permits tabbing through paragraph blocks in the expected order', async () => { @@ -116,7 +158,7 @@ describe( 'Order of block keyboard navigation', () => { await navigateToContentEditorTop(); for ( const paragraphBlock of paragraphBlocks ) { - await tabThroughBlock( paragraphBlock, 'core/paragraph' ); + await tabThroughTextBlock( paragraphBlock, 'core/paragraph' ); } // Repeat the same steps to ensure that there is no change introduced in how the focus is handled. @@ -124,7 +166,7 @@ describe( 'Order of block keyboard navigation', () => { await navigateToContentEditorTop(); for ( const paragraphBlock of paragraphBlocks ) { - await tabThroughBlock( paragraphBlock, 'core/paragraph' ); + await tabThroughTextBlock( paragraphBlock, 'core/paragraph' ); } } ); } ); From 286060a68b27e2868c64723b6d390cbd5bbf9b7e Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Tue, 28 May 2019 10:44:55 -0400 Subject: [PATCH 09/30] WIP - continuing to refactor e2e test tabbing functions --- .../specs/keyboard-navigable-blocks.test.js | 81 ++++++++++--------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index 1396fb545e4d1e..6508cff9802f78 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -1,3 +1,5 @@ +/*eslint no-shadow: ["error", { "allow": ["className", "selector"] }]*/ + /** * WordPress dependencies */ @@ -13,41 +15,47 @@ import { * External dependencies */ -const externalWrapperHasFocus = async ( blockType ) => { - // The block external focusable wrapper has focus - const isFocusedBlock = await page.evaluate( +const activeElementDataType = async ( ) => { + return await page.evaluate( () => document.activeElement.dataset.type ); - await expect( isFocusedBlock ).toEqual( blockType ); +}; + +const activeElementClasslistContains = async ( className ) => { + return await page.evaluate( ( className ) => { + return document.activeElement.classList.contains( className ); + }, className ); +}; + +const externalWrapperHasFocus = async ( blockType ) => { + const result = await activeElementDataType(); + await expect( result ).toEqual( blockType ); }; const inserterToggleHasFocus = async () => { - const isFocusedInserterToggle = await page.evaluate( () => - document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) - ); + const isFocusedInserterToggle = await activeElementClasslistContains( 'block-editor-inserter__toggle' ); await expect( isFocusedInserterToggle ).toBe( true ); }; const textContentAreas = async () => { - return await page.evaluate( () => { + return await getElementList( '.wp-block.is-selected [contenteditable], .wp-block.is-typing [contenteditable]' ); +}; + +const getElementList = async ( selector ) => { + return await page.evaluate( ( selector ) => { // return an array with the classNames of the block toolbar's buttons return [].slice .call( document.querySelectorAll( - '.wp-block.is-selected [contenteditable], .wp-block.is-typing [contenteditable]' + selector ) ) .map( ( elem ) => elem.className ); - } ); + }, selector ); }; -export async function tabThroughPlaceholderButtons() { - const placeholderButtons = await page.evaluate( () => { - // return an array with the classNames of the block toolbar's buttons - return [].slice.call( - document.querySelectorAll( '.wp-block.is-selected .block-editor-media-placeholder button:not([disabled])' ) - ).map( ( elem ) => elem.className ); - } ); +const tabThroughPlaceholderButtons = async () => { + const placeholderButtons = await getElementList( '.wp-block.is-selected .block-editor-media-placeholder button:not([disabled])' ); for ( const buttonClassName of placeholderButtons ) { await page.keyboard.press( 'Tab' ); @@ -56,28 +64,26 @@ export async function tabThroughPlaceholderButtons() { ); await expect( focusePlaceholderButton ).toEqual( buttonClassName ); } -} +}; + const textContentAreasHaveFocus = async ( content ) => { const blocks = await textContentAreas(); - const isFocusedTextContentArea = async () => { - return await page.evaluate( () => document.activeElement.contentEditable ); - }; - const textContentAreaContent = async () => { - return await page.evaluate( () => document.activeElement.innerHTML ); - }; + const isFocusedTextContentArea = await page.evaluate( () => document.activeElement.contentEditable ); + const textContentAreaContent = await page.evaluate( () => document.activeElement.innerHTML ); + for ( let i = 0; i < blocks.length; i++ ) { if ( i > 0 ) { await page.keyboard.press( 'Tab' ); } // The value of 'contentEditable' should be the string 'true' - await expect( await isFocusedTextContentArea() ).toBe( 'true' ); - await expect( await textContentAreaContent() ).toContain( content ); + await expect( isFocusedTextContentArea ).toBe( 'true' ); + await expect( textContentAreaContent ).toContain( content ); } }; -const tabThroughTextBlock = async ( content, blockType ) => { - // Tab to the next paragraph block +const tabThroughBlock = async ( content, blockType ) => { + // Tab to the next block await page.keyboard.press( 'Tab' ); await externalWrapperHasFocus( blockType ); @@ -87,23 +93,18 @@ const tabThroughTextBlock = async ( content, blockType ) => { await tabThroughBlockMoverControl(); await tabThroughBlockToolbar(); +}; + +const tabThroughTextBlock = async ( content, blockType ) => { + await tabThroughBlock( content, blockType ); - // Tab causes the paragraph content to receive focus + // Tab causes the block text content to receive focus await page.keyboard.press( 'Tab' ); await textContentAreasHaveFocus( content ); }; const tabThroughFileBlock = async ( content, blockType ) => { - // Tab to the next block - await page.keyboard.press( 'Tab' ); - await externalWrapperHasFocus( blockType ); - - // Tab causes 'add block' button to receive focus - await page.keyboard.press( 'Tab' ); - await inserterToggleHasFocus(); - - await tabThroughBlockMoverControl(); - await tabThroughBlockToolbar(); + await tabThroughBlock( content, blockType ); await tabThroughPlaceholderButtons(); }; @@ -112,6 +113,8 @@ const insertAndPopulateBlock = async ( blockName, content ) => { await page.keyboard.type( content ); const blocks = await textContentAreas(); + + // the first contentEditable has focus - tab through and populate the rest: for ( let i = 0; i < blocks.length - 1; i++ ) { await page.keyboard.press( 'Tab' ); await page.keyboard.type( content ); From 1fd556fcd9c5d5c669bb63f2e8e569945469fd0e Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Sun, 21 Jul 2019 13:28:51 -0400 Subject: [PATCH 10/30] Extracting more keyboard navigation assertions / helpers into e2e-test-utils --- .../e2e-test-utils/src/get-element-list.js | 12 ++++ packages/e2e-test-utils/src/index.js | 4 ++ .../src/insert-and-populate-block.js | 21 ++++++ .../src/tab-through-placeholder-buttons.js | 18 +++++ .../e2e-test-utils/src/text-content-areas.js | 15 ++++ .../specs/keyboard-navigable-blocks.test.js | 69 ++----------------- 6 files changed, 77 insertions(+), 62 deletions(-) create mode 100644 packages/e2e-test-utils/src/get-element-list.js create mode 100644 packages/e2e-test-utils/src/insert-and-populate-block.js create mode 100644 packages/e2e-test-utils/src/tab-through-placeholder-buttons.js create mode 100644 packages/e2e-test-utils/src/text-content-areas.js diff --git a/packages/e2e-test-utils/src/get-element-list.js b/packages/e2e-test-utils/src/get-element-list.js new file mode 100644 index 00000000000000..8c0415513abef8 --- /dev/null +++ b/packages/e2e-test-utils/src/get-element-list.js @@ -0,0 +1,12 @@ +/*eslint no-shadow: ["error", { "allow": ["selector"] }]*/ + +export const getElementSelectorList = async ( selector ) => { + return await page.evaluate( ( selector ) => { + // return an array with the classNames of the block toolbar's buttons + return Array.from( + document.querySelectorAll( + selector + ) + ).map( ( elem ) => elem.className ); + }, selector ); +}; diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 8ef8f69cd52850..2f3ab5d1c0bf6c 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -20,7 +20,9 @@ export { getAllBlocks } from './get-all-blocks'; export { getAvailableBlockTransforms } from './get-available-block-transforms'; export { getBlockSetting } from './get-block-setting'; export { getEditedPostContent } from './get-edited-post-content'; +export { getElementSelectorList } from './get-element-list'; export { hasBlockSwitcher } from './has-block-switcher'; +export { insertAndPopulateBlock } from './insert-and-populate-block'; export { insertBlock } from './insert-block'; export { installPlugin } from './install-plugin'; export { isCurrentURL } from './is-current-url'; @@ -46,6 +48,8 @@ export { switchUserToAdmin } from './switch-user-to-admin'; export { switchUserToTest } from './switch-user-to-test'; export { tabThroughBlockMoverControl } from './tab-through-block-mover-control'; export { tabThroughBlockToolbar } from './tab-through-block-toolbar'; +export { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons'; +export { textContentAreas } from './text-content-areas'; export { toggleScreenOption } from './toggle-screen-option'; export { transformBlockTo } from './transform-block-to'; export { uninstallPlugin } from './uninstall-plugin'; diff --git a/packages/e2e-test-utils/src/insert-and-populate-block.js b/packages/e2e-test-utils/src/insert-and-populate-block.js new file mode 100644 index 00000000000000..0f83b0a30f86b9 --- /dev/null +++ b/packages/e2e-test-utils/src/insert-and-populate-block.js @@ -0,0 +1,21 @@ +/** + * WordPress dependencies + */ +import { + insertBlock, + textContentAreas, +} from '@wordpress/e2e-test-utils'; + +export async function insertAndPopulateBlock( blockName, content ) { + await insertBlock( blockName ); + await page.keyboard.type( content ); + + const blocks = await textContentAreas( { empty: true } ); + + // the first contentEditable has focus - tab through and populate the rest: + for ( let i = 0; i < blocks.length; i++ ) { + await page.keyboard.press( 'Tab' ); + await page.keyboard.type( content ); + } + await page.keyboard.press( 'Enter' ); +} diff --git a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js new file mode 100644 index 00000000000000..370ecd7b5bdf1c --- /dev/null +++ b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js @@ -0,0 +1,18 @@ +/** + * WordPress dependencies + */ +import { + getElementSelectorList, +} from '@wordpress/e2e-test-utils'; + +export const tabThroughPlaceholderButtons = async () => { + const placeholderButtons = await getElementSelectorList( '.wp-block.is-selected .block-editor-media-placeholder button:not([disabled])' ); + + for ( const buttonClassName of placeholderButtons ) { + await page.keyboard.press( 'Tab' ); + const focusePlaceholderButton = await page.evaluate( () => + document.activeElement.className + ); + await expect( focusePlaceholderButton ).toEqual( buttonClassName ); + } +}; diff --git a/packages/e2e-test-utils/src/text-content-areas.js b/packages/e2e-test-utils/src/text-content-areas.js new file mode 100644 index 00000000000000..0cd89f4558c777 --- /dev/null +++ b/packages/e2e-test-utils/src/text-content-areas.js @@ -0,0 +1,15 @@ +/** + * Internal dependencies + */ +import { getElementSelectorList } from './get-element-list'; + +export async function textContentAreas( { empty = false } ) { + const selectors = [ + '.wp-block.is-selected [contenteditable]', + '.wp-block.is-typing [contenteditable]', + ].map( ( selector ) => { + return empty ? selector + '[data-is-placeholder-visible="true"]' : selector; + }, empty ).join( ',' ); + + return await getElementSelectorList( selectors ); +} diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index 6508cff9802f78..0984703650661f 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -1,73 +1,32 @@ -/*eslint no-shadow: ["error", { "allow": ["className", "selector"] }]*/ - /** * WordPress dependencies */ import { createNewPost, - insertBlock, + insertAndPopulateBlock, navigateToContentEditorTop, tabThroughBlockMoverControl, tabThroughBlockToolbar, + tabThroughPlaceholderButtons, + textContentAreas, } from '@wordpress/e2e-test-utils'; /** * External dependencies */ -const activeElementDataType = async ( ) => { - return await page.evaluate( - () => document.activeElement.dataset.type - ); -}; - -const activeElementClasslistContains = async ( className ) => { - return await page.evaluate( ( className ) => { - return document.activeElement.classList.contains( className ); - }, className ); -}; - const externalWrapperHasFocus = async ( blockType ) => { - const result = await activeElementDataType(); - await expect( result ).toEqual( blockType ); + const activeElementDataType = await page.evaluate( () => document.activeElement.dataset.type ); + await expect( activeElementDataType ).toEqual( blockType ); }; const inserterToggleHasFocus = async () => { - const isFocusedInserterToggle = await activeElementClasslistContains( 'block-editor-inserter__toggle' ); + const isFocusedInserterToggle = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) ); await expect( isFocusedInserterToggle ).toBe( true ); }; -const textContentAreas = async () => { - return await getElementList( '.wp-block.is-selected [contenteditable], .wp-block.is-typing [contenteditable]' ); -}; - -const getElementList = async ( selector ) => { - return await page.evaluate( ( selector ) => { - // return an array with the classNames of the block toolbar's buttons - return [].slice - .call( - document.querySelectorAll( - selector - ) - ) - .map( ( elem ) => elem.className ); - }, selector ); -}; - -const tabThroughPlaceholderButtons = async () => { - const placeholderButtons = await getElementList( '.wp-block.is-selected .block-editor-media-placeholder button:not([disabled])' ); - - for ( const buttonClassName of placeholderButtons ) { - await page.keyboard.press( 'Tab' ); - const focusePlaceholderButton = await page.evaluate( () => - document.activeElement.className - ); - await expect( focusePlaceholderButton ).toEqual( buttonClassName ); - } -}; - const textContentAreasHaveFocus = async ( content ) => { - const blocks = await textContentAreas(); + const blocks = await textContentAreas( { empty: false } ); const isFocusedTextContentArea = await page.evaluate( () => document.activeElement.contentEditable ); const textContentAreaContent = await page.evaluate( () => document.activeElement.innerHTML ); @@ -108,20 +67,6 @@ const tabThroughFileBlock = async ( content, blockType ) => { await tabThroughPlaceholderButtons(); }; -const insertAndPopulateBlock = async ( blockName, content ) => { - await insertBlock( blockName ); - await page.keyboard.type( content ); - - const blocks = await textContentAreas(); - - // the first contentEditable has focus - tab through and populate the rest: - for ( let i = 0; i < blocks.length - 1; i++ ) { - await page.keyboard.press( 'Tab' ); - await page.keyboard.type( content ); - } - await page.keyboard.press( 'Enter' ); -}; - describe( 'Order of block keyboard navigation', () => { beforeEach( async () => { await createNewPost(); From 4e3feaf7aaefe2559a38d903a0eae479304f022d Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Sun, 21 Jul 2019 13:56:41 -0400 Subject: [PATCH 11/30] WIP - refactoring test dependencies for keyboard navigability tests --- .../src/external-wrapper-has-focus.js | 4 + packages/e2e-test-utils/src/index.js | 6 ++ .../src/inserter-toggle-has-focus.js | 4 + .../e2e-test-utils/src/tab-through-block.js | 22 +++++ .../src/tab-through-file-block.js | 10 +++ .../src/tab-through-text-block.js | 13 +++ .../src/text-content-areas-have-focus.js | 20 +++++ .../specs/keyboard-navigable-blocks.test.js | 81 +------------------ .../keyboard-navigable-content-editor.test.js | 42 ++++++++++ 9 files changed, 123 insertions(+), 79 deletions(-) create mode 100644 packages/e2e-test-utils/src/external-wrapper-has-focus.js create mode 100644 packages/e2e-test-utils/src/inserter-toggle-has-focus.js create mode 100644 packages/e2e-test-utils/src/tab-through-block.js create mode 100644 packages/e2e-test-utils/src/tab-through-file-block.js create mode 100644 packages/e2e-test-utils/src/tab-through-text-block.js create mode 100644 packages/e2e-test-utils/src/text-content-areas-have-focus.js create mode 100644 packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js diff --git a/packages/e2e-test-utils/src/external-wrapper-has-focus.js b/packages/e2e-test-utils/src/external-wrapper-has-focus.js new file mode 100644 index 00000000000000..8925b2cf46be84 --- /dev/null +++ b/packages/e2e-test-utils/src/external-wrapper-has-focus.js @@ -0,0 +1,4 @@ +export async function externalWrapperHasFocus( blockType ) { + const activeElementDataType = await page.evaluate( () => document.activeElement.dataset.type ); + await expect( activeElementDataType ).toEqual( blockType ); +} diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 2f3ab5d1c0bf6c..03d5836f0199e8 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -13,6 +13,7 @@ export { disablePrePublishChecks } from './disable-pre-publish-checks'; export { enablePageDialogAccept } from './enable-page-dialog-accept'; export { enablePrePublishChecks } from './enable-pre-publish-checks'; export { ensureSidebarOpened } from './ensure-sidebar-opened'; +export { externalWrapperHasFocus } from './external-wrapper-has-focus'; export { findSidebarPanelToggleButtonWithTitle } from './find-sidebar-panel-toggle-button-with-title'; export { findSidebarPanelWithTitle } from './find-sidebar-panel-with-title'; export { getAllBlockInserterItemTitles } from './get-all-block-inserter-item-titles'; @@ -24,6 +25,7 @@ export { getElementSelectorList } from './get-element-list'; export { hasBlockSwitcher } from './has-block-switcher'; export { insertAndPopulateBlock } from './insert-and-populate-block'; export { insertBlock } from './insert-block'; +export { inserterToggleHasFocus } from './inserter-toggle-has-focus'; export { installPlugin } from './install-plugin'; export { isCurrentURL } from './is-current-url'; export { isInDefaultBlock } from './is-in-default-block'; @@ -46,10 +48,14 @@ export { setPostContent } from './set-post-content'; export { switchEditorModeTo } from './switch-editor-mode-to'; export { switchUserToAdmin } from './switch-user-to-admin'; export { switchUserToTest } from './switch-user-to-test'; +export { tabThroughBlock } from './tab-through-block'; export { tabThroughBlockMoverControl } from './tab-through-block-mover-control'; export { tabThroughBlockToolbar } from './tab-through-block-toolbar'; +export { tabThroughFileBlock } from './tab-through-file-block'; export { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons'; +export { tabThroughTextBlock } from './tab-through-text-block'; export { textContentAreas } from './text-content-areas'; +export { textContentAreasHaveFocus } from './text-content-areas-have-focus'; export { toggleScreenOption } from './toggle-screen-option'; export { transformBlockTo } from './transform-block-to'; export { uninstallPlugin } from './uninstall-plugin'; diff --git a/packages/e2e-test-utils/src/inserter-toggle-has-focus.js b/packages/e2e-test-utils/src/inserter-toggle-has-focus.js new file mode 100644 index 00000000000000..02059ee1ae2ffa --- /dev/null +++ b/packages/e2e-test-utils/src/inserter-toggle-has-focus.js @@ -0,0 +1,4 @@ +export async function inserterToggleHasFocus() { + const isFocusedInserterToggle = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) ); + await expect( isFocusedInserterToggle ).toBe( true ); +} diff --git a/packages/e2e-test-utils/src/tab-through-block.js b/packages/e2e-test-utils/src/tab-through-block.js new file mode 100644 index 00000000000000..a8dfb278d5c265 --- /dev/null +++ b/packages/e2e-test-utils/src/tab-through-block.js @@ -0,0 +1,22 @@ +/** + * WordPress dependencies + */ +import { + externalWrapperHasFocus, + inserterToggleHasFocus, + tabThroughBlockMoverControl, + tabThroughBlockToolbar, +} from '@wordpress/e2e-test-utils'; + +export async function tabThroughBlock( content, blockType ) { + // Tab to the next block + await page.keyboard.press( 'Tab' ); + await externalWrapperHasFocus( blockType ); + + // Tab causes 'add block' button to receive focus + await page.keyboard.press( 'Tab' ); + await inserterToggleHasFocus(); + + await tabThroughBlockMoverControl(); + await tabThroughBlockToolbar(); +} diff --git a/packages/e2e-test-utils/src/tab-through-file-block.js b/packages/e2e-test-utils/src/tab-through-file-block.js new file mode 100644 index 00000000000000..6ed4abeabf6130 --- /dev/null +++ b/packages/e2e-test-utils/src/tab-through-file-block.js @@ -0,0 +1,10 @@ +/** + * Internal dependencies + */ +import { tabThroughBlock } from './tab-through-block'; +import { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons'; + +export async function tabThroughFileBlock( content, blockType ) { + await tabThroughBlock( content, blockType ); + await tabThroughPlaceholderButtons(); +} diff --git a/packages/e2e-test-utils/src/tab-through-text-block.js b/packages/e2e-test-utils/src/tab-through-text-block.js new file mode 100644 index 00000000000000..d1f40b9283a2e8 --- /dev/null +++ b/packages/e2e-test-utils/src/tab-through-text-block.js @@ -0,0 +1,13 @@ +/** + * Internal dependencies + */ +import { tabThroughBlock } from './tab-through-block'; +import { textContentAreasHaveFocus } from './text-content-areas-have-focus'; + +export async function tabThroughTextBlock( content, blockType ) { + await tabThroughBlock( content, blockType ); + + // Tab causes the block text content to receive focus + await page.keyboard.press( 'Tab' ); + await textContentAreasHaveFocus( content ); +} diff --git a/packages/e2e-test-utils/src/text-content-areas-have-focus.js b/packages/e2e-test-utils/src/text-content-areas-have-focus.js new file mode 100644 index 00000000000000..e62f6603edcd91 --- /dev/null +++ b/packages/e2e-test-utils/src/text-content-areas-have-focus.js @@ -0,0 +1,20 @@ +/** + * Internal dependencies + */ +import { textContentAreas } from './text-content-areas'; + +export async function textContentAreasHaveFocus( content ) { + const blocks = await textContentAreas( { empty: false } ); + const isFocusedTextContentArea = await page.evaluate( () => document.activeElement.contentEditable ); + const textContentAreaContent = await page.evaluate( () => document.activeElement.innerHTML ); + + for ( let i = 0; i < blocks.length; i++ ) { + if ( i > 0 ) { + await page.keyboard.press( 'Tab' ); + } + + // The value of 'contentEditable' should be the string 'true' + await expect( isFocusedTextContentArea ).toBe( 'true' ); + await expect( textContentAreaContent ).toContain( content ); + } +} diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index 0984703650661f..52b87d510e9c2c 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -5,68 +5,14 @@ import { createNewPost, insertAndPopulateBlock, navigateToContentEditorTop, - tabThroughBlockMoverControl, - tabThroughBlockToolbar, - tabThroughPlaceholderButtons, - textContentAreas, + tabThroughTextBlock, + tabThroughFileBlock, } from '@wordpress/e2e-test-utils'; /** * External dependencies */ -const externalWrapperHasFocus = async ( blockType ) => { - const activeElementDataType = await page.evaluate( () => document.activeElement.dataset.type ); - await expect( activeElementDataType ).toEqual( blockType ); -}; - -const inserterToggleHasFocus = async () => { - const isFocusedInserterToggle = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) ); - await expect( isFocusedInserterToggle ).toBe( true ); -}; - -const textContentAreasHaveFocus = async ( content ) => { - const blocks = await textContentAreas( { empty: false } ); - const isFocusedTextContentArea = await page.evaluate( () => document.activeElement.contentEditable ); - const textContentAreaContent = await page.evaluate( () => document.activeElement.innerHTML ); - - for ( let i = 0; i < blocks.length; i++ ) { - if ( i > 0 ) { - await page.keyboard.press( 'Tab' ); - } - - // The value of 'contentEditable' should be the string 'true' - await expect( isFocusedTextContentArea ).toBe( 'true' ); - await expect( textContentAreaContent ).toContain( content ); - } -}; - -const tabThroughBlock = async ( content, blockType ) => { - // Tab to the next block - await page.keyboard.press( 'Tab' ); - await externalWrapperHasFocus( blockType ); - - // Tab causes 'add block' button to receive focus - await page.keyboard.press( 'Tab' ); - await inserterToggleHasFocus(); - - await tabThroughBlockMoverControl(); - await tabThroughBlockToolbar(); -}; - -const tabThroughTextBlock = async ( content, blockType ) => { - await tabThroughBlock( content, blockType ); - - // Tab causes the block text content to receive focus - await page.keyboard.press( 'Tab' ); - await textContentAreasHaveFocus( content ); -}; - -const tabThroughFileBlock = async ( content, blockType ) => { - await tabThroughBlock( content, blockType ); - await tabThroughPlaceholderButtons(); -}; - describe( 'Order of block keyboard navigation', () => { beforeEach( async () => { await createNewPost(); @@ -94,27 +40,4 @@ describe( 'Order of block keyboard navigation', () => { await tabThroughFileBlock( 'Cover Block Content', 'core/cover' ); await tabThroughFileBlock( 'File Block Content', 'core/file' ); } ); - - it( 'permits tabbing through paragraph blocks in the expected order', async () => { - const paragraphBlocks = [ 'Paragraph 0', 'Paragraph 1', 'Paragraph 2' ]; - - // create 3 paragraphs blocks with some content - for ( const paragraphBlock of paragraphBlocks ) { - await insertAndPopulateBlock( 'Paragraph', paragraphBlock ); - } - - await navigateToContentEditorTop(); - - for ( const paragraphBlock of paragraphBlocks ) { - await tabThroughTextBlock( paragraphBlock, 'core/paragraph' ); - } - - // Repeat the same steps to ensure that there is no change introduced in how the focus is handled. - // This prevents the previous regression explained in: https://github.com/WordPress/gutenberg/issues/11773. - await navigateToContentEditorTop(); - - for ( const paragraphBlock of paragraphBlocks ) { - await tabThroughTextBlock( paragraphBlock, 'core/paragraph' ); - } - } ); } ); diff --git a/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js b/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js new file mode 100644 index 00000000000000..4b8c8a0b70d993 --- /dev/null +++ b/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js @@ -0,0 +1,42 @@ +/** + * WordPress dependencies + */ +import { + createNewPost, + insertAndPopulateBlock, + navigateToContentEditorTop, + tabThroughTextBlock, +} from '@wordpress/e2e-test-utils'; + +/** + * External dependencies + */ + +describe( 'Order of block keyboard navigation', () => { + beforeEach( async () => { + await createNewPost(); + } ); + + it( 'permits tabbing through paragraph blocks in the expected order', async () => { + const paragraphBlocks = [ 'Paragraph 0', 'Paragraph 1', 'Paragraph 2' ]; + + // create 3 paragraphs blocks with some content + for ( const paragraphBlock of paragraphBlocks ) { + await insertAndPopulateBlock( 'Paragraph', paragraphBlock ); + } + + await navigateToContentEditorTop(); + + for ( const paragraphBlock of paragraphBlocks ) { + await tabThroughTextBlock( paragraphBlock, 'core/paragraph' ); + } + + // Repeat the same steps to ensure that there is no change introduced in how the focus is handled. + // This prevents the previous regression explained in: https://github.com/WordPress/gutenberg/issues/11773. + await navigateToContentEditorTop(); + + for ( const paragraphBlock of paragraphBlocks ) { + await tabThroughTextBlock( paragraphBlock, 'core/paragraph' ); + } + } ); +} ); From 3dbbdd435a4c3fecbe7cbf144643e5391805530c Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 22 Jul 2019 10:07:21 -0400 Subject: [PATCH 12/30] WIP Better JSdocs for keyboard navigation e2e test utils --- .../e2e-test-utils/src/external-wrapper-has-focus.js | 6 ++++++ packages/e2e-test-utils/src/get-element-list.js | 6 +++++- packages/e2e-test-utils/src/insert-and-populate-block.js | 9 ++++++++- packages/e2e-test-utils/src/inserter-toggle-has-focus.js | 4 ++++ packages/e2e-test-utils/src/tab-through-block.js | 8 +++++++- packages/e2e-test-utils/src/tab-through-file-block.js | 8 ++++++++ .../src/tab-through-placeholder-buttons.js | 3 +++ packages/e2e-test-utils/src/tab-through-text-block.js | 7 +++++++ .../e2e-test-utils/src/text-content-areas-have-focus.js | 6 ++++++ packages/e2e-test-utils/src/text-content-areas.js | 6 ++++++ .../specs/keyboard-navigable-content-editor.test.js | 2 +- 11 files changed, 61 insertions(+), 4 deletions(-) diff --git a/packages/e2e-test-utils/src/external-wrapper-has-focus.js b/packages/e2e-test-utils/src/external-wrapper-has-focus.js index 8925b2cf46be84..ef7bb4adb39e31 100644 --- a/packages/e2e-test-utils/src/external-wrapper-has-focus.js +++ b/packages/e2e-test-utils/src/external-wrapper-has-focus.js @@ -1,3 +1,9 @@ +/** + * Asserts that the element with keyboard focus is a block's external wrapper + * + * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper + */ + export async function externalWrapperHasFocus( blockType ) { const activeElementDataType = await page.evaluate( () => document.activeElement.dataset.type ); await expect( activeElementDataType ).toEqual( blockType ); diff --git a/packages/e2e-test-utils/src/get-element-list.js b/packages/e2e-test-utils/src/get-element-list.js index 8c0415513abef8..9f5682649faecb 100644 --- a/packages/e2e-test-utils/src/get-element-list.js +++ b/packages/e2e-test-utils/src/get-element-list.js @@ -1,8 +1,12 @@ /*eslint no-shadow: ["error", { "allow": ["selector"] }]*/ +/** + * Returns an array of classnames that match a given selector on the current page + * + * @param {string} selector The selector to query on the page + */ export const getElementSelectorList = async ( selector ) => { return await page.evaluate( ( selector ) => { - // return an array with the classNames of the block toolbar's buttons return Array.from( document.querySelectorAll( selector diff --git a/packages/e2e-test-utils/src/insert-and-populate-block.js b/packages/e2e-test-utils/src/insert-and-populate-block.js index 0f83b0a30f86b9..65bd3e42c91b7f 100644 --- a/packages/e2e-test-utils/src/insert-and-populate-block.js +++ b/packages/e2e-test-utils/src/insert-and-populate-block.js @@ -6,13 +6,20 @@ import { textContentAreas, } from '@wordpress/e2e-test-utils'; +/** + * Inserts a content block and then, if it has text content areas, fills them with text + * + * @param {string} blockName The type of block to insert + * @param {string} content The text to enter into each contenteditable area + */ export async function insertAndPopulateBlock( blockName, content ) { await insertBlock( blockName ); + // typing populates the first content area await page.keyboard.type( content ); + // if there are more contenteditable elements, select and populate them too: const blocks = await textContentAreas( { empty: true } ); - // the first contentEditable has focus - tab through and populate the rest: for ( let i = 0; i < blocks.length; i++ ) { await page.keyboard.press( 'Tab' ); await page.keyboard.type( content ); diff --git a/packages/e2e-test-utils/src/inserter-toggle-has-focus.js b/packages/e2e-test-utils/src/inserter-toggle-has-focus.js index 02059ee1ae2ffa..77deaf219605aa 100644 --- a/packages/e2e-test-utils/src/inserter-toggle-has-focus.js +++ b/packages/e2e-test-utils/src/inserter-toggle-has-focus.js @@ -1,3 +1,7 @@ +/** + * Asserts that a content block's inserter toggle has keyboard focus + */ + export async function inserterToggleHasFocus() { const isFocusedInserterToggle = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) ); await expect( isFocusedInserterToggle ).toBe( true ); diff --git a/packages/e2e-test-utils/src/tab-through-block.js b/packages/e2e-test-utils/src/tab-through-block.js index a8dfb278d5c265..54a3962e867038 100644 --- a/packages/e2e-test-utils/src/tab-through-block.js +++ b/packages/e2e-test-utils/src/tab-through-block.js @@ -8,7 +8,13 @@ import { tabThroughBlockToolbar, } from '@wordpress/e2e-test-utils'; -export async function tabThroughBlock( content, blockType ) { +/** + * Tabs through a content block and asserts that the external wrapper, inserter toggle, mover controls, and toolbar buttons all receive keyboard focus. + * + * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper + */ + +export async function tabThroughBlock( blockType ) { // Tab to the next block await page.keyboard.press( 'Tab' ); await externalWrapperHasFocus( blockType ); diff --git a/packages/e2e-test-utils/src/tab-through-file-block.js b/packages/e2e-test-utils/src/tab-through-file-block.js index 6ed4abeabf6130..acb1412659d70e 100644 --- a/packages/e2e-test-utils/src/tab-through-file-block.js +++ b/packages/e2e-test-utils/src/tab-through-file-block.js @@ -1,9 +1,17 @@ + /** * Internal dependencies */ + import { tabThroughBlock } from './tab-through-block'; import { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons'; +/** + * Tabs through a content block with file upload buttons, such as an Image, Gallery, Audio, or Cover block + * + * @param {string} content The expected title of the block + * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper + */ export async function tabThroughFileBlock( content, blockType ) { await tabThroughBlock( content, blockType ); await tabThroughPlaceholderButtons(); diff --git a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js index 370ecd7b5bdf1c..14e1107b4f8b88 100644 --- a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js +++ b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js @@ -5,6 +5,9 @@ import { getElementSelectorList, } from '@wordpress/e2e-test-utils'; +/** + * Tabs through the file upload buttons that appear in a file content block's placeholder area + */ export const tabThroughPlaceholderButtons = async () => { const placeholderButtons = await getElementSelectorList( '.wp-block.is-selected .block-editor-media-placeholder button:not([disabled])' ); diff --git a/packages/e2e-test-utils/src/tab-through-text-block.js b/packages/e2e-test-utils/src/tab-through-text-block.js index d1f40b9283a2e8..c69dbe013244a7 100644 --- a/packages/e2e-test-utils/src/tab-through-text-block.js +++ b/packages/e2e-test-utils/src/tab-through-text-block.js @@ -4,6 +4,13 @@ import { tabThroughBlock } from './tab-through-block'; import { textContentAreasHaveFocus } from './text-content-areas-have-focus'; +/** + * Tabs through a content block with text content areas, such as a Heading, Quote, or Paragraph block. Asserts that the text content areas all receive focus. + * + * @param {string} content The expected title of the block + * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper + */ + export async function tabThroughTextBlock( content, blockType ) { await tabThroughBlock( content, blockType ); diff --git a/packages/e2e-test-utils/src/text-content-areas-have-focus.js b/packages/e2e-test-utils/src/text-content-areas-have-focus.js index e62f6603edcd91..1633f1d19d3a46 100644 --- a/packages/e2e-test-utils/src/text-content-areas-have-focus.js +++ b/packages/e2e-test-utils/src/text-content-areas-have-focus.js @@ -3,6 +3,12 @@ */ import { textContentAreas } from './text-content-areas'; +/** + * Tabs through the text content areas of a block and asserts the expected values + * + * @param {string} content The expected value of the block's contenteditable elements + */ + export async function textContentAreasHaveFocus( content ) { const blocks = await textContentAreas( { empty: false } ); const isFocusedTextContentArea = await page.evaluate( () => document.activeElement.contentEditable ); diff --git a/packages/e2e-test-utils/src/text-content-areas.js b/packages/e2e-test-utils/src/text-content-areas.js index 0cd89f4558c777..2aa83c6fad7fcd 100644 --- a/packages/e2e-test-utils/src/text-content-areas.js +++ b/packages/e2e-test-utils/src/text-content-areas.js @@ -3,6 +3,12 @@ */ import { getElementSelectorList } from './get-element-list'; +/** + * Returns a list of a block's contenteditable elements. + * + * @param {boolean} empty When true, restricts the list to contenteditable elements with no value + */ + export async function textContentAreas( { empty = false } ) { const selectors = [ '.wp-block.is-selected [contenteditable]', diff --git a/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js b/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js index 4b8c8a0b70d993..70a054c0866e49 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js @@ -17,7 +17,7 @@ describe( 'Order of block keyboard navigation', () => { await createNewPost(); } ); - it( 'permits tabbing through paragraph blocks in the expected order', async () => { + it( 'permits tabbing through paragraph blocks and the top of the content editor in the expected order', async () => { const paragraphBlocks = [ 'Paragraph 0', 'Paragraph 1', 'Paragraph 2' ]; // create 3 paragraphs blocks with some content From 40a2f3798abac2cafbc6226f2640bcdeb1b043ca Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 22 Jul 2019 10:10:23 -0400 Subject: [PATCH 13/30] JSDocs for keyboard navigability e2e test utils in readme --- packages/e2e-test-utils/README.md | 75 +++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 3c1cd82ba6e9eb..905ebc6eca62f0 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -158,6 +158,14 @@ _Returns_ - `Promise`: Promise resolving once the edit post sidebar is opened. +# **externalWrapperHasFocus** + +Asserts that the element with keyboard focus is a block's external wrapper + +_Parameters_ + +- _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper + # **findSidebarPanelToggleButtonWithTitle** Finds a sidebar panel with the provided title. @@ -228,6 +236,14 @@ _Returns_ - `Promise`: Promise resolving with post content markup. +# **getElementSelectorList** + +Returns an array of classnames that match a given selector on the current page + +_Parameters_ + +- _selector_ `string`: The selector to query on the page + # **hasBlockSwitcher** Returns a boolean indicating if the current selected block has a block switcher or not. @@ -236,6 +252,15 @@ _Returns_ - `Promise`: Promise resolving with a boolean. +# **insertAndPopulateBlock** + +Inserts a content block and then, if it has text content areas, fills them with text + +_Parameters_ + +- _blockName_ `string`: The type of block to insert +- _content_ `string`: The text to enter into each contenteditable area + # **insertBlock** Opens the inserter, searches for the given term, then selects the first @@ -246,6 +271,10 @@ _Parameters_ - _searchTerm_ `string`: The text to search the inserter for. - _panelName_ `string`: The inserter panel to open (if it's closed by default). +# **inserterToggleHasFocus** + +Asserts that a content block's inserter toggle has keyboard focus + # **installPlugin** Installs a plugin from the WP.org repository. @@ -458,6 +487,14 @@ running the test is not already the admin user). Switches the current user to whichever user we should be running the tests as (if we're not already that user). +# **tabThroughBlock** + +Tabs through a content block and asserts that the external wrapper, inserter toggle, mover controls, and toolbar buttons all receive keyboard focus. + +_Parameters_ + +- _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper + # **tabThroughBlockMoverControl** Navigates through the block mover control using the keyboard. Asserts that the 'move up' and 'move down' controls receive focus. @@ -466,6 +503,44 @@ Navigates through the block mover control using the keyboard. Asserts that the ' Navigate through a block's toolbar using the keyboard. Asserts that each button receives focus. +# **tabThroughFileBlock** + +Tabs through a content block with file upload buttons, such as an Image, Gallery, Audio, or Cover block + +_Parameters_ + +- _content_ `string`: The expected title of the block +- _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper + +# **tabThroughPlaceholderButtons** + +Tabs through the file upload buttons that appear in a file content block's placeholder area + +# **tabThroughTextBlock** + +Tabs through a content block with text content areas, such as a Heading, Quote, or Paragraph block. Asserts that the text content areas all receive focus. + +_Parameters_ + +- _content_ `string`: The expected title of the block +- _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper + +# **textContentAreas** + +Returns a list of a block's contenteditable elements. + +_Parameters_ + +- _empty_ `boolean`: When true, restricts the list to contenteditable elements with no value + +# **textContentAreasHaveFocus** + +Tabs through the text content areas of a block and asserts the expected values + +_Parameters_ + +- _content_ `string`: The expected value of the block's contenteditable elements + # **toggleScreenOption** Toggles the screen option with the given label. From 97c6ffd01b6a1cb8a7c7c7f5b33f0fb190a8f91c Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 22 Jul 2019 11:14:14 -0400 Subject: [PATCH 14/30] Fixing failing tests after merge from upstream --- .../src/tab-through-file-block.js | 5 ++--- .../src/tab-through-text-block.js | 6 +++--- .../specs/keyboard-navigable-blocks.test.js | 18 +++++++++--------- .../keyboard-navigable-content-editor.test.js | 6 +++--- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/e2e-test-utils/src/tab-through-file-block.js b/packages/e2e-test-utils/src/tab-through-file-block.js index acb1412659d70e..bd17b212895bf6 100644 --- a/packages/e2e-test-utils/src/tab-through-file-block.js +++ b/packages/e2e-test-utils/src/tab-through-file-block.js @@ -9,10 +9,9 @@ import { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons' /** * Tabs through a content block with file upload buttons, such as an Image, Gallery, Audio, or Cover block * - * @param {string} content The expected title of the block * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper */ -export async function tabThroughFileBlock( content, blockType ) { - await tabThroughBlock( content, blockType ); +export async function tabThroughFileBlock( blockType ) { + await tabThroughBlock( blockType ); await tabThroughPlaceholderButtons(); } diff --git a/packages/e2e-test-utils/src/tab-through-text-block.js b/packages/e2e-test-utils/src/tab-through-text-block.js index c69dbe013244a7..f7953051e2b469 100644 --- a/packages/e2e-test-utils/src/tab-through-text-block.js +++ b/packages/e2e-test-utils/src/tab-through-text-block.js @@ -7,12 +7,12 @@ import { textContentAreasHaveFocus } from './text-content-areas-have-focus'; /** * Tabs through a content block with text content areas, such as a Heading, Quote, or Paragraph block. Asserts that the text content areas all receive focus. * - * @param {string} content The expected title of the block * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper + * @param {string} content The expected title of the block */ -export async function tabThroughTextBlock( content, blockType ) { - await tabThroughBlock( content, blockType ); +export async function tabThroughTextBlock( blockType, content ) { + await tabThroughBlock( blockType ); // Tab causes the block text content to receive focus await page.keyboard.press( 'Tab' ); diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index 52b87d510e9c2c..fc69f63e52804d 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -30,14 +30,14 @@ describe( 'Order of block keyboard navigation', () => { await navigateToContentEditorTop(); - await tabThroughTextBlock( 'Heading Block Content', 'core/heading' ); - await tabThroughTextBlock( 'Quote Block Content', 'core/quote' ); - await tabThroughTextBlock( 'List Block Content', 'core/list' ); - await tabThroughTextBlock( 'Paragraph Block Content', 'core/paragraph' ); - await tabThroughFileBlock( 'Image Block Content', 'core/image' ); - await tabThroughFileBlock( 'Gallery Block Content', 'core/gallery' ); - await tabThroughFileBlock( 'Audio Block Content', 'core/audio' ); - await tabThroughFileBlock( 'Cover Block Content', 'core/cover' ); - await tabThroughFileBlock( 'File Block Content', 'core/file' ); + await tabThroughTextBlock( 'core/heading', 'Heading Block Content' ); + await tabThroughTextBlock( 'core/quote', 'Quote Block Content' ); + await tabThroughTextBlock( 'core/list', 'List Block Content' ); + await tabThroughTextBlock( 'core/paragraph', 'Paragraph Block Content' ); + await tabThroughFileBlock( 'core/image' ); + await tabThroughFileBlock( 'core/gallery' ); + await tabThroughFileBlock( 'core/audio' ); + await tabThroughFileBlock( 'core/cover' ); + await tabThroughFileBlock( 'core/file' ); } ); } ); diff --git a/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js b/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js index 70a054c0866e49..82e6ecfef19eed 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js @@ -17,7 +17,7 @@ describe( 'Order of block keyboard navigation', () => { await createNewPost(); } ); - it( 'permits tabbing through paragraph blocks and the top of the content editor in the expected order', async () => { + it( 'permits tabbing through paragraph blocks and the top of the content in the expected order', async () => { const paragraphBlocks = [ 'Paragraph 0', 'Paragraph 1', 'Paragraph 2' ]; // create 3 paragraphs blocks with some content @@ -28,7 +28,7 @@ describe( 'Order of block keyboard navigation', () => { await navigateToContentEditorTop(); for ( const paragraphBlock of paragraphBlocks ) { - await tabThroughTextBlock( paragraphBlock, 'core/paragraph' ); + await tabThroughTextBlock( 'core/paragraph', paragraphBlock ); } // Repeat the same steps to ensure that there is no change introduced in how the focus is handled. @@ -36,7 +36,7 @@ describe( 'Order of block keyboard navigation', () => { await navigateToContentEditorTop(); for ( const paragraphBlock of paragraphBlocks ) { - await tabThroughTextBlock( paragraphBlock, 'core/paragraph' ); + await tabThroughTextBlock( 'core/paragraph', paragraphBlock ); } } ); } ); From b8dd4b2f77d182b87cd1f69c109e48efd3e5f474 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 22 Jul 2019 12:48:25 -0400 Subject: [PATCH 15/30] Fixing docs build - PR #16707 --- packages/e2e-test-utils/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 6b386dc2a2f079..6bf7e5065b3d14 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -524,7 +524,6 @@ Tabs through a content block with file upload buttons, such as an Image, Gallery _Parameters_ -- _content_ `string`: The expected title of the block - _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper # **tabThroughPlaceholderButtons** @@ -537,8 +536,8 @@ Tabs through a content block with text content areas, such as a Heading, Quote, _Parameters_ -- _content_ `string`: The expected title of the block - _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper +- _content_ `string`: The expected title of the block # **textContentAreas** From 7c8c6663c9e2a10433447150e2add1eda44d4138 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 21:01:32 -0700 Subject: [PATCH 16/30] Assertion in externalWrapperHasFocus does not need to await --- packages/e2e-test-utils/src/external-wrapper-has-focus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-test-utils/src/external-wrapper-has-focus.js b/packages/e2e-test-utils/src/external-wrapper-has-focus.js index ef7bb4adb39e31..9425bfbb929e1a 100644 --- a/packages/e2e-test-utils/src/external-wrapper-has-focus.js +++ b/packages/e2e-test-utils/src/external-wrapper-has-focus.js @@ -6,5 +6,5 @@ export async function externalWrapperHasFocus( blockType ) { const activeElementDataType = await page.evaluate( () => document.activeElement.dataset.type ); - await expect( activeElementDataType ).toEqual( blockType ); + expect( activeElementDataType ).toEqual( blockType ); } From 42ea406d45f0116b6b2dadebe9cb1fad25854743 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 21:36:56 -0700 Subject: [PATCH 17/30] Improving JSDocs in some e2e-test-utils packages to make clear they are returning promise objects. Removing await from simple assertions that do not need it --- packages/e2e-test-utils/src/external-wrapper-has-focus.js | 1 + packages/e2e-test-utils/src/inserter-toggle-has-focus.js | 3 ++- .../e2e-test-utils/src/tab-through-block-mover-control.js | 5 +++-- packages/e2e-test-utils/src/tab-through-block-toolbar.js | 2 +- .../e2e-test-utils/src/tab-through-placeholder-buttons.js | 3 ++- packages/e2e-test-utils/src/text-content-areas-have-focus.js | 5 +++-- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/e2e-test-utils/src/external-wrapper-has-focus.js b/packages/e2e-test-utils/src/external-wrapper-has-focus.js index 9425bfbb929e1a..425571ac1d851a 100644 --- a/packages/e2e-test-utils/src/external-wrapper-has-focus.js +++ b/packages/e2e-test-utils/src/external-wrapper-has-focus.js @@ -2,6 +2,7 @@ * Asserts that the element with keyboard focus is a block's external wrapper * * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper + * @returns {Promise} */ export async function externalWrapperHasFocus( blockType ) { diff --git a/packages/e2e-test-utils/src/inserter-toggle-has-focus.js b/packages/e2e-test-utils/src/inserter-toggle-has-focus.js index 77deaf219605aa..72ffdf792c68aa 100644 --- a/packages/e2e-test-utils/src/inserter-toggle-has-focus.js +++ b/packages/e2e-test-utils/src/inserter-toggle-has-focus.js @@ -1,8 +1,9 @@ /** * Asserts that a content block's inserter toggle has keyboard focus + * @returns {Promise} A promise that's resolved when the active element is evaluated and asserted to have the inserter toggle's classname. */ export async function inserterToggleHasFocus() { const isFocusedInserterToggle = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) ); - await expect( isFocusedInserterToggle ).toBe( true ); + expect( isFocusedInserterToggle ).toBe( true ); } diff --git a/packages/e2e-test-utils/src/tab-through-block-mover-control.js b/packages/e2e-test-utils/src/tab-through-block-mover-control.js index 6ddb983cb902c5..cacb5107f4a11a 100644 --- a/packages/e2e-test-utils/src/tab-through-block-mover-control.js +++ b/packages/e2e-test-utils/src/tab-through-block-mover-control.js @@ -1,5 +1,6 @@ /** * Navigates through the block mover control using the keyboard. Asserts that the 'move up' and 'move down' controls receive focus. + * @return {Promise} A promise that's resolved when the browser has finished tabbing throught the block mover controls. */ export async function tabThroughBlockMoverControl() { // Tab to focus on the 'move up' control @@ -7,12 +8,12 @@ export async function tabThroughBlockMoverControl() { const isFocusedMoveUpControl = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-block-mover__control' ) ); - await expect( isFocusedMoveUpControl ).toBe( true ); + expect( isFocusedMoveUpControl ).toBe( true ); // Tab to focus on the 'move down' control await page.keyboard.press( 'Tab' ); const isFocusedMoveDownControl = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-block-mover__control' ) ); - await expect( isFocusedMoveDownControl ).toBe( true ); + expect( isFocusedMoveDownControl ).toBe( true ); } diff --git a/packages/e2e-test-utils/src/tab-through-block-toolbar.js b/packages/e2e-test-utils/src/tab-through-block-toolbar.js index 7ffb1dc694d225..1f545b4aeaa71a 100644 --- a/packages/e2e-test-utils/src/tab-through-block-toolbar.js +++ b/packages/e2e-test-utils/src/tab-through-block-toolbar.js @@ -15,6 +15,6 @@ export async function tabThroughBlockToolbar() { const focusedBlockToolBarButton = await page.evaluate( () => document.activeElement.className ); - await expect( focusedBlockToolBarButton ).toEqual( buttonClassName ); + expect( focusedBlockToolBarButton ).toEqual( buttonClassName ); } } diff --git a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js index 14e1107b4f8b88..a822a7d4494997 100644 --- a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js +++ b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js @@ -7,6 +7,7 @@ import { /** * Tabs through the file upload buttons that appear in a file content block's placeholder area + * @return {Promise} A promise that resolves when the browser has completed tabbing through the placeholder buttons that are unique to blocks with file-upload features. */ export const tabThroughPlaceholderButtons = async () => { const placeholderButtons = await getElementSelectorList( '.wp-block.is-selected .block-editor-media-placeholder button:not([disabled])' ); @@ -16,6 +17,6 @@ export const tabThroughPlaceholderButtons = async () => { const focusePlaceholderButton = await page.evaluate( () => document.activeElement.className ); - await expect( focusePlaceholderButton ).toEqual( buttonClassName ); + expect( focusePlaceholderButton ).toEqual( buttonClassName ); } }; diff --git a/packages/e2e-test-utils/src/text-content-areas-have-focus.js b/packages/e2e-test-utils/src/text-content-areas-have-focus.js index 1633f1d19d3a46..6ff856f795b80a 100644 --- a/packages/e2e-test-utils/src/text-content-areas-have-focus.js +++ b/packages/e2e-test-utils/src/text-content-areas-have-focus.js @@ -7,6 +7,7 @@ import { textContentAreas } from './text-content-areas'; * Tabs through the text content areas of a block and asserts the expected values * * @param {string} content The expected value of the block's contenteditable elements + * @return {Promise} A promise that's resolved when the browser has finished tabbing throught the contenteditable areas of a block, and asserting they have keyboard focus and the expected content. */ export async function textContentAreasHaveFocus( content ) { @@ -20,7 +21,7 @@ export async function textContentAreasHaveFocus( content ) { } // The value of 'contentEditable' should be the string 'true' - await expect( isFocusedTextContentArea ).toBe( 'true' ); - await expect( textContentAreaContent ).toContain( content ); + expect( isFocusedTextContentArea ).toBe( 'true' ); + expect( textContentAreaContent ).toContain( content ); } } From c6513e65000b03c3d6bca47c0b1404eac21e22e7 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 21:37:48 -0700 Subject: [PATCH 18/30] Improving JSDocs in some e2e-test-utils packages to make clear they are returning promise objects. --- packages/e2e-test-utils/src/external-wrapper-has-focus.js | 2 +- packages/e2e-test-utils/src/insert-and-populate-block.js | 1 + packages/e2e-test-utils/src/navigate-to-content-editor-top.js | 1 + packages/e2e-test-utils/src/tab-through-block.js | 1 + packages/e2e-test-utils/src/tab-through-file-block.js | 1 + packages/e2e-test-utils/src/tab-through-text-block.js | 1 + 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/e2e-test-utils/src/external-wrapper-has-focus.js b/packages/e2e-test-utils/src/external-wrapper-has-focus.js index 425571ac1d851a..2dcd1ce6a43ae1 100644 --- a/packages/e2e-test-utils/src/external-wrapper-has-focus.js +++ b/packages/e2e-test-utils/src/external-wrapper-has-focus.js @@ -2,7 +2,7 @@ * Asserts that the element with keyboard focus is a block's external wrapper * * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper - * @returns {Promise} + * @returns {Promise} A promise that's resolved when the active element is evaluated and asserted against the expected result. */ export async function externalWrapperHasFocus( blockType ) { diff --git a/packages/e2e-test-utils/src/insert-and-populate-block.js b/packages/e2e-test-utils/src/insert-and-populate-block.js index 65bd3e42c91b7f..2e1537ab4d2ebe 100644 --- a/packages/e2e-test-utils/src/insert-and-populate-block.js +++ b/packages/e2e-test-utils/src/insert-and-populate-block.js @@ -11,6 +11,7 @@ import { * * @param {string} blockName The type of block to insert * @param {string} content The text to enter into each contenteditable area + * @return {Promise} A promise that resolves when all the blocks are inserted and filled with content. */ export async function insertAndPopulateBlock( blockName, content ) { await insertBlock( blockName ); diff --git a/packages/e2e-test-utils/src/navigate-to-content-editor-top.js b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js index 3b74f1c840fdcd..5c2da9834e8e6f 100644 --- a/packages/e2e-test-utils/src/navigate-to-content-editor-top.js +++ b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js @@ -1,5 +1,6 @@ /** * Navigates to the top of the content editor using the keyboard. + * @returns {Promise} A promise that's resolved when the browser has finished emulating the keyboard shortcut for focusing the top of the editor, and tabbed to the next focusable element. */ /** diff --git a/packages/e2e-test-utils/src/tab-through-block.js b/packages/e2e-test-utils/src/tab-through-block.js index 54a3962e867038..526ac6d4215e0c 100644 --- a/packages/e2e-test-utils/src/tab-through-block.js +++ b/packages/e2e-test-utils/src/tab-through-block.js @@ -12,6 +12,7 @@ import { * Tabs through a content block and asserts that the external wrapper, inserter toggle, mover controls, and toolbar buttons all receive keyboard focus. * * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper + * @returns {Promise} A promise that's resolved when the browser has finished tabbing through the major components of a common block. */ export async function tabThroughBlock( blockType ) { diff --git a/packages/e2e-test-utils/src/tab-through-file-block.js b/packages/e2e-test-utils/src/tab-through-file-block.js index bd17b212895bf6..f391ace06869a2 100644 --- a/packages/e2e-test-utils/src/tab-through-file-block.js +++ b/packages/e2e-test-utils/src/tab-through-file-block.js @@ -10,6 +10,7 @@ import { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons' * Tabs through a content block with file upload buttons, such as an Image, Gallery, Audio, or Cover block * * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper + * @return {Promise} A promise that resolves when the browser has completed tabbing through the common block components, and the placeholder buttons that are unique to blocks with file-upload features. */ export async function tabThroughFileBlock( blockType ) { await tabThroughBlock( blockType ); diff --git a/packages/e2e-test-utils/src/tab-through-text-block.js b/packages/e2e-test-utils/src/tab-through-text-block.js index f7953051e2b469..74f194b6bdaf8b 100644 --- a/packages/e2e-test-utils/src/tab-through-text-block.js +++ b/packages/e2e-test-utils/src/tab-through-text-block.js @@ -9,6 +9,7 @@ import { textContentAreasHaveFocus } from './text-content-areas-have-focus'; * * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper * @param {string} content The expected title of the block + * @return {Promise} A promise that resolves when the browser has completed tabbing through the focusable elements of a common block, and through the contenteditbable areas unique to text blocks. */ export async function tabThroughTextBlock( blockType, content ) { From 9badfc1485c03dee7b8dd5d178a68ac7b2cbe405 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 21:40:48 -0700 Subject: [PATCH 19/30] Improving JSDocs in some e2e-test-utils packages to make clear they are returning promise objects. --- packages/e2e-test-utils/src/text-content-areas.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-test-utils/src/text-content-areas.js b/packages/e2e-test-utils/src/text-content-areas.js index 2aa83c6fad7fcd..e2c105cc7b2b2c 100644 --- a/packages/e2e-test-utils/src/text-content-areas.js +++ b/packages/e2e-test-utils/src/text-content-areas.js @@ -7,8 +7,8 @@ import { getElementSelectorList } from './get-element-list'; * Returns a list of a block's contenteditable elements. * * @param {boolean} empty When true, restricts the list to contenteditable elements with no value + * @return {Promise} A promise that resolves when it's returned an array of classes representing the contenteditable areas of a block with keyboard focus. */ - export async function textContentAreas( { empty = false } ) { const selectors = [ '.wp-block.is-selected [contenteditable]', From 8726c0f5856f012f2cbb00b42c475e7824658e8d Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 21:42:04 -0700 Subject: [PATCH 20/30] Fixing typo in tabThroughPlaceholderButtons --- .../e2e-test-utils/src/tab-through-placeholder-buttons.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js index a822a7d4494997..b9994eaeaa6735 100644 --- a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js +++ b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js @@ -14,9 +14,9 @@ export const tabThroughPlaceholderButtons = async () => { for ( const buttonClassName of placeholderButtons ) { await page.keyboard.press( 'Tab' ); - const focusePlaceholderButton = await page.evaluate( () => + const focusedPlaceholderButton = await page.evaluate( () => document.activeElement.className ); - expect( focusePlaceholderButton ).toEqual( buttonClassName ); + expect( focusedPlaceholderButton ).toEqual( buttonClassName ); } }; From f6e538c3574f713e3f8a5968d212f93c4f3ac300 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 21:43:52 -0700 Subject: [PATCH 21/30] Fixing undocumented declaration in e2e-test-utils/README. Updating for remainder of the new e2e-test-utils JSDocs --- packages/e2e-test-utils/README.md | 34 ++++++++++++++++++- .../src/navigate-to-content-editor-top.js | 9 +++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 6bf7e5065b3d14..5486a6e8270976 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -276,6 +276,10 @@ _Parameters_ - _blockName_ `string`: The type of block to insert - _content_ `string`: The text to enter into each contenteditable area +_Returns_ + +- `Promise`: A promise that resolves when all the blocks are inserted and filled with content. + # **insertBlock** Opens the inserter, searches for the given term, then selects the first @@ -346,7 +350,11 @@ _Returns_ # **navigateToContentEditorTop** -Undocumented declaration. +Navigates to the top of the content editor using the keyboard. + +_Returns_ + +- `Promise`: A promise that's resolved when the browser has finished emulating the keyboard shortcut for focusing the top of the editor, and tabbed to the next focusable element. # **observeFocusLoss** @@ -514,6 +522,10 @@ _Parameters_ Navigates through the block mover control using the keyboard. Asserts that the 'move up' and 'move down' controls receive focus. +_Returns_ + +- `Promise`: A promise that's resolved when the browser has finished tabbing throught the block mover controls. + # **tabThroughBlockToolbar** Navigate through a block's toolbar using the keyboard. Asserts that each button receives focus. @@ -526,10 +538,18 @@ _Parameters_ - _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper +_Returns_ + +- `Promise`: A promise that resolves when the browser has completed tabbing through the common block components, and the placeholder buttons that are unique to blocks with file-upload features. + # **tabThroughPlaceholderButtons** Tabs through the file upload buttons that appear in a file content block's placeholder area +_Returns_ + +- `Promise`: A promise that resolves when the browser has completed tabbing through the placeholder buttons that are unique to blocks with file-upload features. + # **tabThroughTextBlock** Tabs through a content block with text content areas, such as a Heading, Quote, or Paragraph block. Asserts that the text content areas all receive focus. @@ -539,6 +559,10 @@ _Parameters_ - _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper - _content_ `string`: The expected title of the block +_Returns_ + +- `Promise`: A promise that resolves when the browser has completed tabbing through the focusable elements of a common block, and through the contenteditbable areas unique to text blocks. + # **textContentAreas** Returns a list of a block's contenteditable elements. @@ -547,6 +571,10 @@ _Parameters_ - _empty_ `boolean`: When true, restricts the list to contenteditable elements with no value +_Returns_ + +- `Promise`: A promise that resolves when it's returned an array of classes representing the contenteditable areas of a block with keyboard focus. + # **textContentAreasHaveFocus** Tabs through the text content areas of a block and asserts the expected values @@ -555,6 +583,10 @@ _Parameters_ - _content_ `string`: The expected value of the block's contenteditable elements +_Returns_ + +- `Promise`: A promise that's resolved when the browser has finished tabbing throught the contenteditable areas of a block, and asserting they have keyboard focus and the expected content. + # **toggleScreenOption** Toggles the screen option with the given label. diff --git a/packages/e2e-test-utils/src/navigate-to-content-editor-top.js b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js index 5c2da9834e8e6f..04b0e59a4c8013 100644 --- a/packages/e2e-test-utils/src/navigate-to-content-editor-top.js +++ b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js @@ -1,13 +1,12 @@ -/** - * Navigates to the top of the content editor using the keyboard. - * @returns {Promise} A promise that's resolved when the browser has finished emulating the keyboard shortcut for focusing the top of the editor, and tabbed to the next focusable element. - */ - /** * Internal dependencies */ import { pressKeyWithModifier } from './press-key-with-modifier'; +/** + * Navigates to the top of the content editor using the keyboard. + * @return {Promise} A promise that's resolved when the browser has finished emulating the keyboard shortcut for focusing the top of the editor, and tabbed to the next focusable element. + */ export async function navigateToContentEditorTop() { // Use 'Ctrl+`' to return to the top of the editor await pressKeyWithModifier( 'ctrl', '`' ); From 7848c4bcd4d8906c03b9663ce3ffadaf125bb8f6 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 22:35:55 -0700 Subject: [PATCH 22/30] Using page.$$eval instead of getElementList --- packages/e2e-test-utils/src/get-element-list.js | 16 ---------------- packages/e2e-test-utils/src/index.js | 1 - .../src/tab-through-block-toolbar.js | 9 +++------ .../src/tab-through-placeholder-buttons.js | 10 ++-------- .../e2e-test-utils/src/text-content-areas.js | 8 ++------ 5 files changed, 7 insertions(+), 37 deletions(-) delete mode 100644 packages/e2e-test-utils/src/get-element-list.js diff --git a/packages/e2e-test-utils/src/get-element-list.js b/packages/e2e-test-utils/src/get-element-list.js deleted file mode 100644 index 9f5682649faecb..00000000000000 --- a/packages/e2e-test-utils/src/get-element-list.js +++ /dev/null @@ -1,16 +0,0 @@ -/*eslint no-shadow: ["error", { "allow": ["selector"] }]*/ - -/** - * Returns an array of classnames that match a given selector on the current page - * - * @param {string} selector The selector to query on the page - */ -export const getElementSelectorList = async ( selector ) => { - return await page.evaluate( ( selector ) => { - return Array.from( - document.querySelectorAll( - selector - ) - ).map( ( elem ) => elem.className ); - }, selector ); -}; diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 83be1a81a4ee38..cb05b860cbb608 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -22,7 +22,6 @@ export { getAllBlocks } from './get-all-blocks'; export { getAvailableBlockTransforms } from './get-available-block-transforms'; export { getBlockSetting } from './get-block-setting'; export { getEditedPostContent } from './get-edited-post-content'; -export { getElementSelectorList } from './get-element-list'; export { hasBlockSwitcher } from './has-block-switcher'; export { insertAndPopulateBlock } from './insert-and-populate-block'; export { insertBlock } from './insert-block'; diff --git a/packages/e2e-test-utils/src/tab-through-block-toolbar.js b/packages/e2e-test-utils/src/tab-through-block-toolbar.js index 1f545b4aeaa71a..489d39bb1dbe2d 100644 --- a/packages/e2e-test-utils/src/tab-through-block-toolbar.js +++ b/packages/e2e-test-utils/src/tab-through-block-toolbar.js @@ -1,14 +1,11 @@ /** * Navigate through a block's toolbar using the keyboard. Asserts that each button receives focus. + * @return {Promise} A promise that resolves when it's finished tabbing through the buttons in a block's toolbar, asserting that each one received focus. */ export async function tabThroughBlockToolbar() { - const blockToolbarButtons = await page.evaluate( () => { - // return an array with the classNames of the block toolbar's buttons - return [].slice.call( - document.querySelectorAll( '.block-editor-block-contextual-toolbar button:not([disabled])' ) - ).map( ( elem ) => elem.className ); - } ); + const blockToolbarButtons = await page.$$eval( '.block-editor-block-contextual-toolbar button:not([disabled])', + ( elements ) => elements.map( ( elem ) => elem.className ) ); for ( const buttonClassName of blockToolbarButtons ) { await page.keyboard.press( 'Tab' ); diff --git a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js index b9994eaeaa6735..a9cc24f30e8226 100644 --- a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js +++ b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js @@ -1,16 +1,10 @@ -/** - * WordPress dependencies - */ -import { - getElementSelectorList, -} from '@wordpress/e2e-test-utils'; - /** * Tabs through the file upload buttons that appear in a file content block's placeholder area * @return {Promise} A promise that resolves when the browser has completed tabbing through the placeholder buttons that are unique to blocks with file-upload features. */ export const tabThroughPlaceholderButtons = async () => { - const placeholderButtons = await getElementSelectorList( '.wp-block.is-selected .block-editor-media-placeholder button:not([disabled])' ); + const placeholderButtons = await page.$$eval( '.wp-block.is-selected .block-editor-media-placeholder button:not([disabled])', + ( elements ) => elements.map( ( elem ) => elem.className ) ); for ( const buttonClassName of placeholderButtons ) { await page.keyboard.press( 'Tab' ); diff --git a/packages/e2e-test-utils/src/text-content-areas.js b/packages/e2e-test-utils/src/text-content-areas.js index e2c105cc7b2b2c..0be764ca3226ff 100644 --- a/packages/e2e-test-utils/src/text-content-areas.js +++ b/packages/e2e-test-utils/src/text-content-areas.js @@ -1,8 +1,3 @@ -/** - * Internal dependencies - */ -import { getElementSelectorList } from './get-element-list'; - /** * Returns a list of a block's contenteditable elements. * @@ -17,5 +12,6 @@ export async function textContentAreas( { empty = false } ) { return empty ? selector + '[data-is-placeholder-visible="true"]' : selector; }, empty ).join( ',' ); - return await getElementSelectorList( selectors ); + return await page.$$eval( selectors, + ( elements ) => elements.map( ( elem ) => elem.className ) ); } From c5889d18f245ac97c2faf40beea0dfba951c6c21 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 22:37:00 -0700 Subject: [PATCH 23/30] Updating JSDoc in e2e-test-utils/README --- packages/e2e-test-utils/README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 5486a6e8270976..af38e240c687f6 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -251,14 +251,6 @@ _Returns_ - `Promise`: Promise resolving with post content markup. -# **getElementSelectorList** - -Returns an array of classnames that match a given selector on the current page - -_Parameters_ - -- _selector_ `string`: The selector to query on the page - # **hasBlockSwitcher** Returns a boolean indicating if the current selected block has a block switcher or not. @@ -530,6 +522,10 @@ _Returns_ Navigate through a block's toolbar using the keyboard. Asserts that each button receives focus. +_Returns_ + +- `Promise`: A promise that resolves when it's finished tabbing through the buttons in a block's toolbar, asserting that each one received focus. + # **tabThroughFileBlock** Tabs through a content block with file upload buttons, such as an Image, Gallery, Audio, or Cover block From c66437947f4480e7646db61f020496191c18ca90 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 23:29:30 -0700 Subject: [PATCH 24/30] Re-evaluate isFocusedTextContentArea and textContentAreaContent within each for block to verify the assertions are being made about the expected elements. --- packages/e2e-test-utils/src/text-content-areas-have-focus.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/e2e-test-utils/src/text-content-areas-have-focus.js b/packages/e2e-test-utils/src/text-content-areas-have-focus.js index 6ff856f795b80a..c16bda54a4e3c5 100644 --- a/packages/e2e-test-utils/src/text-content-areas-have-focus.js +++ b/packages/e2e-test-utils/src/text-content-areas-have-focus.js @@ -12,13 +12,13 @@ import { textContentAreas } from './text-content-areas'; export async function textContentAreasHaveFocus( content ) { const blocks = await textContentAreas( { empty: false } ); - const isFocusedTextContentArea = await page.evaluate( () => document.activeElement.contentEditable ); - const textContentAreaContent = await page.evaluate( () => document.activeElement.innerHTML ); for ( let i = 0; i < blocks.length; i++ ) { if ( i > 0 ) { await page.keyboard.press( 'Tab' ); } + const isFocusedTextContentArea = await page.evaluate( () => document.activeElement.contentEditable ); + const textContentAreaContent = await page.evaluate( () => document.activeElement.innerHTML ); // The value of 'contentEditable' should be the string 'true' expect( isFocusedTextContentArea ).toBe( 'true' ); From 71dea07a9e4e430516a1170b0c70b7159401cd6c Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Mon, 26 Aug 2019 23:41:27 -0700 Subject: [PATCH 25/30] Refactoring 'Order of block keyboard navigation' to a series of more isolated 'describe' / 'it' tests --- .../specs/keyboard-navigable-blocks.test.js | 131 ++++++++++++++---- 1 file changed, 105 insertions(+), 26 deletions(-) diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index fc69f63e52804d..2bc8c1a39a2497 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -9,35 +9,114 @@ import { tabThroughFileBlock, } from '@wordpress/e2e-test-utils'; -/** - * External dependencies - */ - describe( 'Order of block keyboard navigation', () => { beforeEach( async () => { await createNewPost(); } ); - it( 'permits tabbing through blocks in the expected order', async () => { - await insertAndPopulateBlock( 'Heading', 'Heading Block Content' ); - await insertAndPopulateBlock( 'Quote', 'Quote Block Content' ); - await insertAndPopulateBlock( 'List', 'List Block Content' ); - await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block Content' ); - await insertAndPopulateBlock( 'Image', 'Image Block Content' ); - await insertAndPopulateBlock( 'Gallery', 'Gallery Block Content' ); - await insertAndPopulateBlock( 'Audio', 'Audio Block Content' ); - await insertAndPopulateBlock( 'Cover', 'Cover Block Content' ); - await insertAndPopulateBlock( 'File', 'File Block Content' ); - - await navigateToContentEditorTop(); - - await tabThroughTextBlock( 'core/heading', 'Heading Block Content' ); - await tabThroughTextBlock( 'core/quote', 'Quote Block Content' ); - await tabThroughTextBlock( 'core/list', 'List Block Content' ); - await tabThroughTextBlock( 'core/paragraph', 'Paragraph Block Content' ); - await tabThroughFileBlock( 'core/image' ); - await tabThroughFileBlock( 'core/gallery' ); - await tabThroughFileBlock( 'core/audio' ); - await tabThroughFileBlock( 'core/cover' ); - await tabThroughFileBlock( 'core/file' ); + + describe( 'Order of heading block keyboard navigation', () => { + it( 'permits tabbing through heading blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Heading', 'Heading Block Content' ); + + await navigateToContentEditorTop(); + + await tabThroughTextBlock( 'core/heading', 'Heading Block Content' ); + } ); + } ); + + describe( 'Order of quote block keyboard navigation', () => { + it( 'permits tabbing through quote blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Quote', 'Quote Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Quote', 'Quote Block 2 Content' ); + + await navigateToContentEditorTop(); + + await tabThroughTextBlock( 'core/quote', 'Quote Block Content' ); + } ); + } ); + + describe( 'Order of list block keyboard navigation', () => { + it( 'permits tabbing through list blocks in the expected order', async () => { + await insertAndPopulateBlock( 'List', 'List Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'List', 'List Block 2 Content' ); + + await navigateToContentEditorTop(); + + await tabThroughTextBlock( 'core/list', 'List Block Content' ); + } ); + } ); + + describe( 'Order of paragraph block keyboard navigation', () => { + it( 'permits tabbing through paragraph blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block 2 Content' ); + + await navigateToContentEditorTop(); + + await tabThroughTextBlock( 'core/paragraph', 'Paragraph Block Content' ); + } ); + } ); + + describe( 'Order of image block keyboard navigation', () => { + it( 'permits tabbing through image blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Image', 'Image Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Image', 'Image Block 2 Content' ); + + await navigateToContentEditorTop(); + + await tabThroughFileBlock( 'core/image' ); + } ); + } ); + + describe( 'Order of gallery block keyboard navigation', () => { + it( 'permits tabbing through gallery blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Gallery', 'Gallery Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Gallery', 'Gallery Block 2 Content' ); + + await navigateToContentEditorTop(); + + await tabThroughFileBlock( 'core/gallery' ); + } ); + } ); + + describe( 'Order of audio block keyboard navigation', () => { + it( 'permits tabbing through audio blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Audio', 'Audio Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Audio', 'Audio Block 2 Content' ); + + await navigateToContentEditorTop(); + + await tabThroughFileBlock( 'core/audio' ); + } ); + } ); + + describe( 'Order of cover block keyboard navigation', () => { + it( 'permits tabbing through cover blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Cover', 'Cover Block 2 Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Cover', 'Cover Block Content' ); + + await navigateToContentEditorTop(); + + await tabThroughFileBlock( 'core/cover' ); + } ); + } ); + + describe( 'Order of file block keyboard navigation', () => { + it( 'permits tabbing through file blocks in the expected order', async () => { + await insertAndPopulateBlock( 'File', 'File Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'File', 'File Block 2 Content' ); + + await navigateToContentEditorTop(); + + await tabThroughFileBlock( 'core/file' ); + } ); } ); } ); From b56bfe03ab1172181ca0db6ad75a65d598c44ce9 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Tue, 27 Aug 2019 00:38:16 -0700 Subject: [PATCH 26/30] Renaming tabThroughBlock to tabThroughBlockControls, tabThroughBlockMoverControls to tabThroughBlockMovers. Changing the name of one describe block, and removing unnecessary nesting added to keyboard-navigable-blocks.test.js --- packages/e2e-test-utils/README.md | 12 +- packages/e2e-test-utils/src/index.js | 5 +- .../src/inserter-toggle-has-focus.js | 9 -- .../src/tab-through-block-controls.js | 37 ++++++ ...control.js => tab-through-block-movers.js} | 4 +- .../e2e-test-utils/src/tab-through-block.js | 29 ----- .../src/tab-through-file-block.js | 4 +- .../src/tab-through-text-block.js | 4 +- .../specs/keyboard-navigable-blocks.test.js | 122 ++++++++---------- .../keyboard-navigable-content-editor.test.js | 2 +- 10 files changed, 105 insertions(+), 123 deletions(-) delete mode 100644 packages/e2e-test-utils/src/inserter-toggle-has-focus.js create mode 100644 packages/e2e-test-utils/src/tab-through-block-controls.js rename packages/e2e-test-utils/src/{tab-through-block-mover-control.js => tab-through-block-movers.js} (93%) delete mode 100644 packages/e2e-test-utils/src/tab-through-block.js diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 2c9ecb7567259e..910419336caa85 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -290,10 +290,6 @@ _Parameters_ - _searchTerm_ `string`: The text to search the inserter for. - _panelName_ `string`: The inserter panel to open (if it's closed by default). -# **inserterToggleHasFocus** - -Asserts that a content block's inserter toggle has keyboard focus - # **installPlugin** Installs a plugin from the WP.org repository. @@ -506,7 +502,7 @@ running the test is not already the admin user). Switches the current user to whichever user we should be running the tests as (if we're not already that user). -# **tabThroughBlock** +# **tabThroughBlockControls** Tabs through a content block and asserts that the external wrapper, inserter toggle, mover controls, and toolbar buttons all receive keyboard focus. @@ -514,7 +510,11 @@ _Parameters_ - _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper -# **tabThroughBlockMoverControl** +_Returns_ + +- `Promise`: A promise that's resolved when the browser has finished tabbing through the major components of a common block. + +# **tabThroughBlockMovers** Navigates through the block mover control using the keyboard. Asserts that the 'move up' and 'move down' controls receive focus. diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 6f072e308b2969..5e98beaabf7ce2 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -26,7 +26,6 @@ export { getEditedPostContent } from './get-edited-post-content'; export { hasBlockSwitcher } from './has-block-switcher'; export { insertAndPopulateBlock } from './insert-and-populate-block'; export { insertBlock } from './insert-block'; -export { inserterToggleHasFocus } from './inserter-toggle-has-focus'; export { installPlugin } from './install-plugin'; export { isCurrentURL } from './is-current-url'; export { isInDefaultBlock } from './is-in-default-block'; @@ -50,8 +49,8 @@ export { switchEditorModeTo } from './switch-editor-mode-to'; export { disableNavigationMode } from './keyboard-mode'; export { switchUserToAdmin } from './switch-user-to-admin'; export { switchUserToTest } from './switch-user-to-test'; -export { tabThroughBlock } from './tab-through-block'; -export { tabThroughBlockMoverControl } from './tab-through-block-mover-control'; +export { tabThroughBlockControls } from './tab-through-block-controls'; +export { tabThroughBlockMovers } from './tab-through-block-movers'; export { tabThroughBlockToolbar } from './tab-through-block-toolbar'; export { tabThroughFileBlock } from './tab-through-file-block'; export { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons'; diff --git a/packages/e2e-test-utils/src/inserter-toggle-has-focus.js b/packages/e2e-test-utils/src/inserter-toggle-has-focus.js deleted file mode 100644 index 72ffdf792c68aa..00000000000000 --- a/packages/e2e-test-utils/src/inserter-toggle-has-focus.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Asserts that a content block's inserter toggle has keyboard focus - * @returns {Promise} A promise that's resolved when the active element is evaluated and asserted to have the inserter toggle's classname. - */ - -export async function inserterToggleHasFocus() { - const isFocusedInserterToggle = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) ); - expect( isFocusedInserterToggle ).toBe( true ); -} diff --git a/packages/e2e-test-utils/src/tab-through-block-controls.js b/packages/e2e-test-utils/src/tab-through-block-controls.js new file mode 100644 index 00000000000000..6117c764e7f4dc --- /dev/null +++ b/packages/e2e-test-utils/src/tab-through-block-controls.js @@ -0,0 +1,37 @@ +/** + * Internal dependencies + */ +import { externalWrapperHasFocus } from './external-wrapper-has-focus'; +import { tabThroughBlockMovers } from './tab-through-block-movers'; +import { tabThroughBlockToolbar } from './tab-through-block-toolbar'; + +/** + * Asserts that a content block's inserter toggle has keyboard focus + * + * @return {Promise} A promise that's resolved when the active element is evaluated and asserted to have the inserter toggle's classname. + */ + +const inserterToggleHasFocus = async function() { + const isFocusedInserterToggle = await page.evaluate( () => document.activeElement.classList.contains( 'block-editor-inserter__toggle' ) ); + expect( isFocusedInserterToggle ).toBe( true ); +}; + +/** + * Tabs through a content block and asserts that the external wrapper, inserter toggle, mover controls, and toolbar buttons all receive keyboard focus. + * + * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper + * @return {Promise} A promise that's resolved when the browser has finished tabbing through the major components of a common block. + */ + +export async function tabThroughBlockControls( blockType ) { + // Tab to the next block + await page.keyboard.press( 'Tab' ); + await externalWrapperHasFocus( blockType ); + + // Tab causes 'add block' button to receive focus + await page.keyboard.press( 'Tab' ); + await inserterToggleHasFocus(); + + await tabThroughBlockMovers(); + await tabThroughBlockToolbar(); +} diff --git a/packages/e2e-test-utils/src/tab-through-block-mover-control.js b/packages/e2e-test-utils/src/tab-through-block-movers.js similarity index 93% rename from packages/e2e-test-utils/src/tab-through-block-mover-control.js rename to packages/e2e-test-utils/src/tab-through-block-movers.js index cacb5107f4a11a..1000dc372a94b2 100644 --- a/packages/e2e-test-utils/src/tab-through-block-mover-control.js +++ b/packages/e2e-test-utils/src/tab-through-block-movers.js @@ -1,8 +1,10 @@ /** * Navigates through the block mover control using the keyboard. Asserts that the 'move up' and 'move down' controls receive focus. + * * @return {Promise} A promise that's resolved when the browser has finished tabbing throught the block mover controls. */ -export async function tabThroughBlockMoverControl() { + +export async function tabThroughBlockMovers() { // Tab to focus on the 'move up' control await page.keyboard.press( 'Tab' ); const isFocusedMoveUpControl = await page.evaluate( () => diff --git a/packages/e2e-test-utils/src/tab-through-block.js b/packages/e2e-test-utils/src/tab-through-block.js deleted file mode 100644 index 526ac6d4215e0c..00000000000000 --- a/packages/e2e-test-utils/src/tab-through-block.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * WordPress dependencies - */ -import { - externalWrapperHasFocus, - inserterToggleHasFocus, - tabThroughBlockMoverControl, - tabThroughBlockToolbar, -} from '@wordpress/e2e-test-utils'; - -/** - * Tabs through a content block and asserts that the external wrapper, inserter toggle, mover controls, and toolbar buttons all receive keyboard focus. - * - * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper - * @returns {Promise} A promise that's resolved when the browser has finished tabbing through the major components of a common block. - */ - -export async function tabThroughBlock( blockType ) { - // Tab to the next block - await page.keyboard.press( 'Tab' ); - await externalWrapperHasFocus( blockType ); - - // Tab causes 'add block' button to receive focus - await page.keyboard.press( 'Tab' ); - await inserterToggleHasFocus(); - - await tabThroughBlockMoverControl(); - await tabThroughBlockToolbar(); -} diff --git a/packages/e2e-test-utils/src/tab-through-file-block.js b/packages/e2e-test-utils/src/tab-through-file-block.js index f391ace06869a2..1f309e019643dc 100644 --- a/packages/e2e-test-utils/src/tab-through-file-block.js +++ b/packages/e2e-test-utils/src/tab-through-file-block.js @@ -3,7 +3,7 @@ * Internal dependencies */ -import { tabThroughBlock } from './tab-through-block'; +import { tabThroughBlockControls } from './tab-through-block-controls'; import { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons'; /** @@ -13,6 +13,6 @@ import { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons' * @return {Promise} A promise that resolves when the browser has completed tabbing through the common block components, and the placeholder buttons that are unique to blocks with file-upload features. */ export async function tabThroughFileBlock( blockType ) { - await tabThroughBlock( blockType ); + await tabThroughBlockControls( blockType ); await tabThroughPlaceholderButtons(); } diff --git a/packages/e2e-test-utils/src/tab-through-text-block.js b/packages/e2e-test-utils/src/tab-through-text-block.js index 74f194b6bdaf8b..9635da39f44fb3 100644 --- a/packages/e2e-test-utils/src/tab-through-text-block.js +++ b/packages/e2e-test-utils/src/tab-through-text-block.js @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { tabThroughBlock } from './tab-through-block'; +import { tabThroughBlockControls } from './tab-through-block-controls'; import { textContentAreasHaveFocus } from './text-content-areas-have-focus'; /** @@ -13,7 +13,7 @@ import { textContentAreasHaveFocus } from './text-content-areas-have-focus'; */ export async function tabThroughTextBlock( blockType, content ) { - await tabThroughBlock( blockType ); + await tabThroughBlockControls( blockType ); // Tab causes the block text content to receive focus await page.keyboard.press( 'Tab' ); diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js index 2bc8c1a39a2497..01fb5f19a0cd33 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js @@ -14,109 +14,91 @@ describe( 'Order of block keyboard navigation', () => { await createNewPost(); } ); - describe( 'Order of heading block keyboard navigation', () => { - it( 'permits tabbing through heading blocks in the expected order', async () => { - await insertAndPopulateBlock( 'Heading', 'Heading Block Content' ); + it( 'permits tabbing through heading blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Heading', 'Heading Block Content' ); - await navigateToContentEditorTop(); + await navigateToContentEditorTop(); - await tabThroughTextBlock( 'core/heading', 'Heading Block Content' ); - } ); + await tabThroughTextBlock( 'core/heading', 'Heading Block Content' ); } ); - describe( 'Order of quote block keyboard navigation', () => { - it( 'permits tabbing through quote blocks in the expected order', async () => { - await insertAndPopulateBlock( 'Quote', 'Quote Block Content' ); - // in order to see the block mover controls, we must insert more than one of these blocks: - await insertAndPopulateBlock( 'Quote', 'Quote Block 2 Content' ); + it( 'permits tabbing through quote blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Quote', 'Quote Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Quote', 'Quote Block 2 Content' ); - await navigateToContentEditorTop(); + await navigateToContentEditorTop(); - await tabThroughTextBlock( 'core/quote', 'Quote Block Content' ); - } ); + await tabThroughTextBlock( 'core/quote', 'Quote Block Content' ); } ); - describe( 'Order of list block keyboard navigation', () => { - it( 'permits tabbing through list blocks in the expected order', async () => { - await insertAndPopulateBlock( 'List', 'List Block Content' ); - // in order to see the block mover controls, we must insert more than one of these blocks: - await insertAndPopulateBlock( 'List', 'List Block 2 Content' ); + it( 'permits tabbing through list blocks in the expected order', async () => { + await insertAndPopulateBlock( 'List', 'List Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'List', 'List Block 2 Content' ); - await navigateToContentEditorTop(); + await navigateToContentEditorTop(); - await tabThroughTextBlock( 'core/list', 'List Block Content' ); - } ); + await tabThroughTextBlock( 'core/list', 'List Block Content' ); } ); - describe( 'Order of paragraph block keyboard navigation', () => { - it( 'permits tabbing through paragraph blocks in the expected order', async () => { - await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block Content' ); - // in order to see the block mover controls, we must insert more than one of these blocks: - await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block 2 Content' ); + it( 'permits tabbing through paragraph blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Paragraph', 'Paragraph Block 2 Content' ); - await navigateToContentEditorTop(); + await navigateToContentEditorTop(); - await tabThroughTextBlock( 'core/paragraph', 'Paragraph Block Content' ); - } ); + await tabThroughTextBlock( 'core/paragraph', 'Paragraph Block Content' ); } ); - describe( 'Order of image block keyboard navigation', () => { - it( 'permits tabbing through image blocks in the expected order', async () => { - await insertAndPopulateBlock( 'Image', 'Image Block Content' ); - // in order to see the block mover controls, we must insert more than one of these blocks: - await insertAndPopulateBlock( 'Image', 'Image Block 2 Content' ); + it( 'permits tabbing through image blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Image', 'Image Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Image', 'Image Block 2 Content' ); - await navigateToContentEditorTop(); + await navigateToContentEditorTop(); - await tabThroughFileBlock( 'core/image' ); - } ); + await tabThroughFileBlock( 'core/image' ); } ); - describe( 'Order of gallery block keyboard navigation', () => { - it( 'permits tabbing through gallery blocks in the expected order', async () => { - await insertAndPopulateBlock( 'Gallery', 'Gallery Block Content' ); - // in order to see the block mover controls, we must insert more than one of these blocks: - await insertAndPopulateBlock( 'Gallery', 'Gallery Block 2 Content' ); + it( 'permits tabbing through gallery blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Gallery', 'Gallery Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Gallery', 'Gallery Block 2 Content' ); - await navigateToContentEditorTop(); + await navigateToContentEditorTop(); - await tabThroughFileBlock( 'core/gallery' ); - } ); + await tabThroughFileBlock( 'core/gallery' ); } ); - describe( 'Order of audio block keyboard navigation', () => { - it( 'permits tabbing through audio blocks in the expected order', async () => { - await insertAndPopulateBlock( 'Audio', 'Audio Block Content' ); - // in order to see the block mover controls, we must insert more than one of these blocks: - await insertAndPopulateBlock( 'Audio', 'Audio Block 2 Content' ); + it( 'permits tabbing through audio blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Audio', 'Audio Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Audio', 'Audio Block 2 Content' ); - await navigateToContentEditorTop(); + await navigateToContentEditorTop(); - await tabThroughFileBlock( 'core/audio' ); - } ); + await tabThroughFileBlock( 'core/audio' ); } ); - describe( 'Order of cover block keyboard navigation', () => { - it( 'permits tabbing through cover blocks in the expected order', async () => { - await insertAndPopulateBlock( 'Cover', 'Cover Block 2 Content' ); - // in order to see the block mover controls, we must insert more than one of these blocks: - await insertAndPopulateBlock( 'Cover', 'Cover Block Content' ); + it( 'permits tabbing through cover blocks in the expected order', async () => { + await insertAndPopulateBlock( 'Cover', 'Cover Block 2 Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'Cover', 'Cover Block Content' ); - await navigateToContentEditorTop(); + await navigateToContentEditorTop(); - await tabThroughFileBlock( 'core/cover' ); - } ); + await tabThroughFileBlock( 'core/cover' ); } ); - describe( 'Order of file block keyboard navigation', () => { - it( 'permits tabbing through file blocks in the expected order', async () => { - await insertAndPopulateBlock( 'File', 'File Block Content' ); - // in order to see the block mover controls, we must insert more than one of these blocks: - await insertAndPopulateBlock( 'File', 'File Block 2 Content' ); + it( 'permits tabbing through file blocks in the expected order', async () => { + await insertAndPopulateBlock( 'File', 'File Block Content' ); + // in order to see the block mover controls, we must insert more than one of these blocks: + await insertAndPopulateBlock( 'File', 'File Block 2 Content' ); - await navigateToContentEditorTop(); + await navigateToContentEditorTop(); - await tabThroughFileBlock( 'core/file' ); - } ); + await tabThroughFileBlock( 'core/file' ); } ); } ); diff --git a/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js b/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js index 82e6ecfef19eed..d1003634417b0f 100644 --- a/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js +++ b/packages/e2e-tests/specs/keyboard-navigable-content-editor.test.js @@ -12,7 +12,7 @@ import { * External dependencies */ -describe( 'Order of block keyboard navigation', () => { +describe( 'Order of the block editor keyboard navigation', () => { beforeEach( async () => { await createNewPost(); } ); From bdf6a8f7e38262a3d0581b3d61916857f40a3fce Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Tue, 27 Aug 2019 00:41:37 -0700 Subject: [PATCH 27/30] Improving confusing variable name in insert-and-populate-block --- .../e2e-test-utils/src/insert-and-populate-block.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/e2e-test-utils/src/insert-and-populate-block.js b/packages/e2e-test-utils/src/insert-and-populate-block.js index 2e1537ab4d2ebe..606544c4fb8d1d 100644 --- a/packages/e2e-test-utils/src/insert-and-populate-block.js +++ b/packages/e2e-test-utils/src/insert-and-populate-block.js @@ -1,10 +1,8 @@ /** - * WordPress dependencies + * Internal dependencies */ -import { - insertBlock, - textContentAreas, -} from '@wordpress/e2e-test-utils'; +import { insertBlock } from './insert-block'; +import { textContentAreas } from './text-content-areas'; /** * Inserts a content block and then, if it has text content areas, fills them with text @@ -19,9 +17,9 @@ export async function insertAndPopulateBlock( blockName, content ) { await page.keyboard.type( content ); // if there are more contenteditable elements, select and populate them too: - const blocks = await textContentAreas( { empty: true } ); + const blockContentAreas = await textContentAreas( { empty: true } ); - for ( let i = 0; i < blocks.length; i++ ) { + for ( let i = 0; i < blockContentAreas.length; i++ ) { await page.keyboard.press( 'Tab' ); await page.keyboard.type( content ); } From 2a5a9cef650f8f6e97a7cf524b36ea45ab87f6fc Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Tue, 27 Aug 2019 00:50:27 -0700 Subject: [PATCH 28/30] Renaming helper function from textContentAreasHaveFocus to tabThroughTextContentAreas. Updating e2e-test-utils/README --- packages/e2e-test-utils/README.md | 16 ++++++++-------- packages/e2e-test-utils/src/index.js | 2 +- .../e2e-test-utils/src/tab-through-text-block.js | 4 ++-- ...ocus.js => tab-through-text-content-areas.js} | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) rename packages/e2e-test-utils/src/{text-content-areas-have-focus.js => tab-through-text-content-areas.js} (94%) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 910419336caa85..decd3fad5d470a 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -563,29 +563,29 @@ _Returns_ - `Promise`: A promise that resolves when the browser has completed tabbing through the focusable elements of a common block, and through the contenteditbable areas unique to text blocks. -# **textContentAreas** +# **tabThroughTextContentAreas** -Returns a list of a block's contenteditable elements. +Tabs through the text content areas of a block and asserts the expected values _Parameters_ -- _empty_ `boolean`: When true, restricts the list to contenteditable elements with no value +- _content_ `string`: The expected value of the block's contenteditable elements _Returns_ -- `Promise`: A promise that resolves when it's returned an array of classes representing the contenteditable areas of a block with keyboard focus. +- `Promise`: A promise that's resolved when the browser has finished tabbing throught the contenteditable areas of a block, and asserting they have keyboard focus and the expected content. -# **textContentAreasHaveFocus** +# **textContentAreas** -Tabs through the text content areas of a block and asserts the expected values +Returns a list of a block's contenteditable elements. _Parameters_ -- _content_ `string`: The expected value of the block's contenteditable elements +- _empty_ `boolean`: When true, restricts the list to contenteditable elements with no value _Returns_ -- `Promise`: A promise that's resolved when the browser has finished tabbing throught the contenteditable areas of a block, and asserting they have keyboard focus and the expected content. +- `Promise`: A promise that resolves when it's returned an array of classes representing the contenteditable areas of a block with keyboard focus. # **toggleScreenOption** diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 5e98beaabf7ce2..add0a0130b8d38 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -55,8 +55,8 @@ export { tabThroughBlockToolbar } from './tab-through-block-toolbar'; export { tabThroughFileBlock } from './tab-through-file-block'; export { tabThroughPlaceholderButtons } from './tab-through-placeholder-buttons'; export { tabThroughTextBlock } from './tab-through-text-block'; +export { tabThroughTextContentAreas } from './tab-through-text-content-areas'; export { textContentAreas } from './text-content-areas'; -export { textContentAreasHaveFocus } from './text-content-areas-have-focus'; export { toggleScreenOption } from './toggle-screen-option'; export { transformBlockTo } from './transform-block-to'; export { uninstallPlugin } from './uninstall-plugin'; diff --git a/packages/e2e-test-utils/src/tab-through-text-block.js b/packages/e2e-test-utils/src/tab-through-text-block.js index 9635da39f44fb3..97f7ab84bc584f 100644 --- a/packages/e2e-test-utils/src/tab-through-text-block.js +++ b/packages/e2e-test-utils/src/tab-through-text-block.js @@ -2,7 +2,7 @@ * Internal dependencies */ import { tabThroughBlockControls } from './tab-through-block-controls'; -import { textContentAreasHaveFocus } from './text-content-areas-have-focus'; +import { tabThroughTextContentAreas } from './tab-through-text-content-areas'; /** * Tabs through a content block with text content areas, such as a Heading, Quote, or Paragraph block. Asserts that the text content areas all receive focus. @@ -17,5 +17,5 @@ export async function tabThroughTextBlock( blockType, content ) { // Tab causes the block text content to receive focus await page.keyboard.press( 'Tab' ); - await textContentAreasHaveFocus( content ); + await tabThroughTextContentAreas( content ); } diff --git a/packages/e2e-test-utils/src/text-content-areas-have-focus.js b/packages/e2e-test-utils/src/tab-through-text-content-areas.js similarity index 94% rename from packages/e2e-test-utils/src/text-content-areas-have-focus.js rename to packages/e2e-test-utils/src/tab-through-text-content-areas.js index c16bda54a4e3c5..b7c59a8ea6e3a2 100644 --- a/packages/e2e-test-utils/src/text-content-areas-have-focus.js +++ b/packages/e2e-test-utils/src/tab-through-text-content-areas.js @@ -10,7 +10,7 @@ import { textContentAreas } from './text-content-areas'; * @return {Promise} A promise that's resolved when the browser has finished tabbing throught the contenteditable areas of a block, and asserting they have keyboard focus and the expected content. */ -export async function textContentAreasHaveFocus( content ) { +export async function tabThroughTextContentAreas( content ) { const blocks = await textContentAreas( { empty: false } ); for ( let i = 0; i < blocks.length; i++ ) { From 56fd018be413cfa963a2c64b669ae7ccee9f2495 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Sat, 28 Sep 2019 13:24:19 -0400 Subject: [PATCH 29/30] Linter fixes for /e2e-test-utils changes --- .../src/external-wrapper-has-focus.js | 2 +- packages/e2e-test-utils/src/index.js | 142 +++++++++--------- .../src/navigate-to-content-editor-top.js | 1 + .../src/tab-through-block-toolbar.js | 1 + .../src/tab-through-placeholder-buttons.js | 1 + 5 files changed, 75 insertions(+), 72 deletions(-) diff --git a/packages/e2e-test-utils/src/external-wrapper-has-focus.js b/packages/e2e-test-utils/src/external-wrapper-has-focus.js index 2dcd1ce6a43ae1..9660b3affc3f91 100644 --- a/packages/e2e-test-utils/src/external-wrapper-has-focus.js +++ b/packages/e2e-test-utils/src/external-wrapper-has-focus.js @@ -2,7 +2,7 @@ * Asserts that the element with keyboard focus is a block's external wrapper * * @param {string} blockType The expected value of the data-type attribute of the block's external wrapper - * @returns {Promise} A promise that's resolved when the active element is evaluated and asserted against the expected result. + * @return {Promise} A promise that's resolved when the active element is evaluated and asserted against the expected result. */ export async function externalWrapperHasFocus( blockType ) { diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 8c26878227d65e..1acb883650d879 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -1,77 +1,77 @@ -export { activatePlugin } from "./activate-plugin"; -export { arePrePublishChecksEnabled } from "./are-pre-publish-checks-enabled"; -export { clearLocalStorage } from "./clear-local-storage"; -export { clickBlockAppender } from "./click-block-appender"; -export { clickBlockToolbarButton } from "./click-block-toolbar-button"; -export { clickButton } from "./click-button"; -export { clickOnCloseModalButton } from "./click-on-close-modal-button"; -export { clickOnMoreMenuItem } from "./click-on-more-menu-item"; -export { createNewPost } from "./create-new-post"; -export { createURL } from "./create-url"; -export { deactivatePlugin } from "./deactivate-plugin"; -export { disablePrePublishChecks } from "./disable-pre-publish-checks"; -export { dragAndResize } from "./drag-and-resize"; -export { enableExperimentalFeatures } from "./enable-experimental-features"; -export { enablePageDialogAccept } from "./enable-page-dialog-accept"; -export { enablePrePublishChecks } from "./enable-pre-publish-checks"; -export { ensureSidebarOpened } from "./ensure-sidebar-opened"; -export { externalWrapperHasFocus } from "./external-wrapper-has-focus"; +export { activatePlugin } from './activate-plugin'; +export { arePrePublishChecksEnabled } from './are-pre-publish-checks-enabled'; +export { clearLocalStorage } from './clear-local-storage'; +export { clickBlockAppender } from './click-block-appender'; +export { clickBlockToolbarButton } from './click-block-toolbar-button'; +export { clickButton } from './click-button'; +export { clickOnCloseModalButton } from './click-on-close-modal-button'; +export { clickOnMoreMenuItem } from './click-on-more-menu-item'; +export { createNewPost } from './create-new-post'; +export { createURL } from './create-url'; +export { deactivatePlugin } from './deactivate-plugin'; +export { disablePrePublishChecks } from './disable-pre-publish-checks'; +export { dragAndResize } from './drag-and-resize'; +export { enableExperimentalFeatures } from './enable-experimental-features'; +export { enablePageDialogAccept } from './enable-page-dialog-accept'; +export { enablePrePublishChecks } from './enable-pre-publish-checks'; +export { ensureSidebarOpened } from './ensure-sidebar-opened'; +export { externalWrapperHasFocus } from './external-wrapper-has-focus'; export { - findSidebarPanelToggleButtonWithTitle -} from "./find-sidebar-panel-toggle-button-with-title"; -export { findSidebarPanelWithTitle } from "./find-sidebar-panel-with-title"; + findSidebarPanelToggleButtonWithTitle, +} from './find-sidebar-panel-toggle-button-with-title'; +export { findSidebarPanelWithTitle } from './find-sidebar-panel-with-title'; export { - getAllBlockInserterItemTitles -} from "./get-all-block-inserter-item-titles"; -export { getAllBlocks } from "./get-all-blocks"; -export { getAvailableBlockTransforms } from "./get-available-block-transforms"; -export { getBlockSetting } from "./get-block-setting"; -export { getEditedPostContent } from "./get-edited-post-content"; -export { hasBlockSwitcher } from "./has-block-switcher"; -export { insertAndPopulateBlock } from "./insert-and-populate-block"; -export { insertBlock } from "./insert-block"; -export { installPlugin } from "./install-plugin"; -export { isCurrentURL } from "./is-current-url"; -export { isInDefaultBlock } from "./is-in-default-block"; -export { loginUser } from "./login-user"; -export { navigateToContentEditorTop } from "./navigate-to-content-editor-top"; -export { observeFocusLoss } from "./observe-focus-loss"; + getAllBlockInserterItemTitles, +} from './get-all-block-inserter-item-titles'; +export { getAllBlocks } from './get-all-blocks'; +export { getAvailableBlockTransforms } from './get-available-block-transforms'; +export { getBlockSetting } from './get-block-setting'; +export { getEditedPostContent } from './get-edited-post-content'; +export { hasBlockSwitcher } from './has-block-switcher'; +export { insertAndPopulateBlock } from './insert-and-populate-block'; +export { insertBlock } from './insert-block'; +export { installPlugin } from './install-plugin'; +export { isCurrentURL } from './is-current-url'; +export { isInDefaultBlock } from './is-in-default-block'; +export { loginUser } from './login-user'; +export { navigateToContentEditorTop } from './navigate-to-content-editor-top'; +export { observeFocusLoss } from './observe-focus-loss'; export { - openAllBlockInserterCategories -} from "./open-all-block-inserter-categories"; -export { openDocumentSettingsSidebar } from "./open-document-settings-sidebar"; -export { openGlobalBlockInserter } from "./open-global-block-inserter"; -export { openPublishPanel } from "./open-publish-panel"; -export { pressKeyTimes } from "./press-key-times"; -export { pressKeyWithModifier } from "./press-key-with-modifier"; -export { publishPost } from "./publish-post"; + openAllBlockInserterCategories, +} from './open-all-block-inserter-categories'; +export { openDocumentSettingsSidebar } from './open-document-settings-sidebar'; +export { openGlobalBlockInserter } from './open-global-block-inserter'; +export { openPublishPanel } from './open-publish-panel'; +export { pressKeyTimes } from './press-key-times'; +export { pressKeyWithModifier } from './press-key-with-modifier'; +export { publishPost } from './publish-post'; export { - publishPostWithPrePublishChecksDisabled -} from "./publish-post-with-pre-publish-checks-disabled"; -export { saveDraft } from "./save-draft"; -export { searchForBlock } from "./search-for-block"; -export { selectBlockByClientId } from "./select-block-by-client-id"; -export { setBrowserViewport } from "./set-browser-viewport"; -export { setPostContent } from "./set-post-content"; -export { switchEditorModeTo } from "./switch-editor-mode-to"; -export { disableNavigationMode } from "./keyboard-mode"; -export { switchUserToAdmin } from "./switch-user-to-admin"; -export { switchUserToTest } from "./switch-user-to-test"; -export { tabThroughBlockControls } from "./tab-through-block-controls"; -export { tabThroughBlockMovers } from "./tab-through-block-movers"; -export { tabThroughBlockToolbar } from "./tab-through-block-toolbar"; -export { tabThroughFileBlock } from "./tab-through-file-block"; + publishPostWithPrePublishChecksDisabled, +} from './publish-post-with-pre-publish-checks-disabled'; +export { saveDraft } from './save-draft'; +export { searchForBlock } from './search-for-block'; +export { selectBlockByClientId } from './select-block-by-client-id'; +export { setBrowserViewport } from './set-browser-viewport'; +export { setPostContent } from './set-post-content'; +export { switchEditorModeTo } from './switch-editor-mode-to'; +export { disableNavigationMode } from './keyboard-mode'; +export { switchUserToAdmin } from './switch-user-to-admin'; +export { switchUserToTest } from './switch-user-to-test'; +export { tabThroughBlockControls } from './tab-through-block-controls'; +export { tabThroughBlockMovers } from './tab-through-block-movers'; +export { tabThroughBlockToolbar } from './tab-through-block-toolbar'; +export { tabThroughFileBlock } from './tab-through-file-block'; export { - tabThroughPlaceholderButtons -} from "./tab-through-placeholder-buttons"; -export { tabThroughTextBlock } from "./tab-through-text-block"; -export { tabThroughTextContentAreas } from "./tab-through-text-content-areas"; -export { textContentAreas } from "./text-content-areas"; -export { toggleMoreMenu } from "./toggle-more-menu"; -export { toggleScreenOption } from "./toggle-screen-option"; -export { transformBlockTo } from "./transform-block-to"; -export { uninstallPlugin } from "./uninstall-plugin"; -export { visitAdminPage } from "./visit-admin-page"; -export { waitForWindowDimensions } from "./wait-for-window-dimensions"; + tabThroughPlaceholderButtons, +} from './tab-through-placeholder-buttons'; +export { tabThroughTextBlock } from './tab-through-text-block'; +export { tabThroughTextContentAreas } from './tab-through-text-content-areas'; +export { textContentAreas } from './text-content-areas'; +export { toggleMoreMenu } from './toggle-more-menu'; +export { toggleScreenOption } from './toggle-screen-option'; +export { transformBlockTo } from './transform-block-to'; +export { uninstallPlugin } from './uninstall-plugin'; +export { visitAdminPage } from './visit-admin-page'; +export { waitForWindowDimensions } from './wait-for-window-dimensions'; -export * from "./mocks"; +export * from './mocks'; diff --git a/packages/e2e-test-utils/src/navigate-to-content-editor-top.js b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js index 04b0e59a4c8013..e5c94707c9c16d 100644 --- a/packages/e2e-test-utils/src/navigate-to-content-editor-top.js +++ b/packages/e2e-test-utils/src/navigate-to-content-editor-top.js @@ -5,6 +5,7 @@ import { pressKeyWithModifier } from './press-key-with-modifier'; /** * Navigates to the top of the content editor using the keyboard. + * * @return {Promise} A promise that's resolved when the browser has finished emulating the keyboard shortcut for focusing the top of the editor, and tabbed to the next focusable element. */ export async function navigateToContentEditorTop() { diff --git a/packages/e2e-test-utils/src/tab-through-block-toolbar.js b/packages/e2e-test-utils/src/tab-through-block-toolbar.js index 489d39bb1dbe2d..85a811745a5ff5 100644 --- a/packages/e2e-test-utils/src/tab-through-block-toolbar.js +++ b/packages/e2e-test-utils/src/tab-through-block-toolbar.js @@ -1,5 +1,6 @@ /** * Navigate through a block's toolbar using the keyboard. Asserts that each button receives focus. + * * @return {Promise} A promise that resolves when it's finished tabbing through the buttons in a block's toolbar, asserting that each one received focus. */ diff --git a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js index a9cc24f30e8226..59894cd3a75230 100644 --- a/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js +++ b/packages/e2e-test-utils/src/tab-through-placeholder-buttons.js @@ -1,5 +1,6 @@ /** * Tabs through the file upload buttons that appear in a file content block's placeholder area + * * @return {Promise} A promise that resolves when the browser has completed tabbing through the placeholder buttons that are unique to blocks with file-upload features. */ export const tabThroughPlaceholderButtons = async () => { From 4c82b7b153236a416c54959a18942eb39e673262 Mon Sep 17 00:00:00 2001 From: TJ Nicolaides Date: Sat, 28 Sep 2019 13:24:50 -0400 Subject: [PATCH 30/30] JSDoc fix for e2e-test-utils changes --- packages/e2e-test-utils/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index decd3fad5d470a..98d2271aed0356 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -189,6 +189,10 @@ _Parameters_ - _blockType_ `string`: The expected value of the data-type attribute of the block's external wrapper +_Returns_ + +- `Promise`: A promise that's resolved when the active element is evaluated and asserted against the expected result. + # **findSidebarPanelToggleButtonWithTitle** Finds a sidebar panel with the provided title. @@ -587,6 +591,10 @@ _Returns_ - `Promise`: A promise that resolves when it's returned an array of classes representing the contenteditable areas of a block with keyboard focus. +# **toggleMoreMenu** + +Toggles the More Menu. + # **toggleScreenOption** Toggles the screen option with the given label.