From 81d58d2cf0fbecadf5f7bebb21de2a0c5d186163 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 11 Mar 2019 17:07:31 -0400 Subject: [PATCH] Testing: Create new selectAll, selectAllBlocks utilities --- packages/e2e-test-utils/README.md | 8 ++++++++ packages/e2e-test-utils/src/index.js | 2 ++ packages/e2e-test-utils/src/login-user.js | 17 +++++++---------- .../e2e-test-utils/src/select-all-blocks.js | 19 +++++++++++++++++++ packages/e2e-test-utils/src/select-all.js | 15 +++++++++++++++ .../specs/block-hierarchy-navigation.test.js | 8 +++----- .../specs/multi-block-selection.test.js | 13 ++++++++----- .../e2e-tests/specs/reusable-blocks.test.js | 5 ++--- packages/e2e-tests/specs/rich-text.test.js | 5 +++-- 9 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 packages/e2e-test-utils/src/select-all-blocks.js create mode 100644 packages/e2e-test-utils/src/select-all.js diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 8cfd7554eb782..35cd91fd6c14b 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -377,6 +377,14 @@ _Parameters_ - _searchTerm_ `string`: The text to search the inserter for. +# **selectAllBlocks** + +Selects all blocks present in the block editor. + +_Returns_ + +- `Promise`: Promise resolving once active element selected. + # **selectBlockByClientId** Given the clientId of a block, selects the block on the editor. diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index e984658a99f6d..e0832b1d9a5e4 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -1,3 +1,4 @@ +export { __unstableSelectAll } from './select-all'; export { activatePlugin } from './activate-plugin'; export { arePrePublishChecksEnabled } from './are-pre-publish-checks-enabled'; export { clearLocalStorage } from './clear-local-storage'; @@ -37,6 +38,7 @@ 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 { selectAllBlocks } from './select-all-blocks'; export { selectBlockByClientId } from './select-block-by-client-id'; export { setBrowserViewport } from './set-browser-viewport'; export { setPostContent } from './set-post-content'; diff --git a/packages/e2e-test-utils/src/login-user.js b/packages/e2e-test-utils/src/login-user.js index 8ec49b80bc0c7..63465582efb81 100644 --- a/packages/e2e-test-utils/src/login-user.js +++ b/packages/e2e-test-utils/src/login-user.js @@ -4,6 +4,7 @@ import { WP_USERNAME, WP_PASSWORD } from './shared/config'; import { createURL } from './create-url'; import { isCurrentURL } from './is-current-url'; +import { __unstableSelectAll } from './select-all'; /** * Performs log in with specified username and password. @@ -18,16 +19,12 @@ export async function loginUser( username = WP_USERNAME, password = WP_PASSWORD ); } - // Explicitly assign values of form, since the username is prefilled if - // already logged in. This could be done by keyboard interactions as well, - // but as of Puppeteer 1.6.1, Cmd+A does not work as expected in Mac, - // making it difficult to erase the contents of the field. - // - // See: https://github.com/GoogleChrome/puppeteer/issues/1313 - await page.evaluate( ( _username, _password ) => { - document.getElementById( 'user_login' ).value = _username; - document.getElementById( 'user_pass' ).value = _password; - }, username, password ); + await page.focus( '#user_login' ); + await __unstableSelectAll(); + await page.type( '#user_login', username ); + await page.focus( '#user_pass' ); + await __unstableSelectAll(); + await page.type( '#user_pass', password ); await Promise.all( [ page.waitForNavigation(), page.click( '#wp-submit' ) ] ); } diff --git a/packages/e2e-test-utils/src/select-all-blocks.js b/packages/e2e-test-utils/src/select-all-blocks.js new file mode 100644 index 0000000000000..adfe905c63188 --- /dev/null +++ b/packages/e2e-test-utils/src/select-all-blocks.js @@ -0,0 +1,19 @@ +/** + * Internal dependencies + */ +import { pressKeyWithModifier } from './press-key-with-modifier'; +import { __unstableSelectAll } from './select-all'; + +/** + * Selects all blocks present in the block editor. + * + * @return {Promise} Promise resolving once active element selected. + */ +export async function selectAllBlocks() { + // NOTE: `__unstableSelectAll` is used for cross-platform compatibility + // alternative to Cmd+A. The second issuance of the key combination is + // handled internerally by the block editor's KeyboardShortcuts utility, + // and is not subject to the same buggy browser/OS emulation. + await __unstableSelectAll(); + await pressKeyWithModifier( 'primary', 'a' ); +} diff --git a/packages/e2e-test-utils/src/select-all.js b/packages/e2e-test-utils/src/select-all.js new file mode 100644 index 0000000000000..1f670bb865bf3 --- /dev/null +++ b/packages/e2e-test-utils/src/select-all.js @@ -0,0 +1,15 @@ +/** + * Selects all text within the current active element field. Throws if there is + * no active element. + * + * This serves as a temporary solution to a bug present as of Puppeteer 1.6.1 + * in which the Cmd+A keyboard combination does not work correctly in macOS + * environments. Once the bug is resolved, the utility will be removed. + * + * @link https://github.com/GoogleChrome/puppeteer/issues/1313 + * + * @return {Promise} Promise resolving once active element selected. + */ +export async function __unstableSelectAll() { + await page.evaluate( () => document.execCommand( 'selectall', false, null ) ); +} diff --git a/packages/e2e-tests/specs/block-hierarchy-navigation.test.js b/packages/e2e-tests/specs/block-hierarchy-navigation.test.js index eb23d8fba8c26..63ea25ca8b88a 100644 --- a/packages/e2e-tests/specs/block-hierarchy-navigation.test.js +++ b/packages/e2e-tests/specs/block-hierarchy-navigation.test.js @@ -7,6 +7,7 @@ import { getEditedPostContent, pressKeyTimes, pressKeyWithModifier, + __unstableSelectAll, } from '@wordpress/e2e-test-utils'; async function openBlockNavigator() { @@ -98,11 +99,8 @@ describe( 'Navigating the block hierarchy', () => { await openBlockNavigator(); await page.keyboard.press( 'Space' ); - // Replace its content - // note Cmd/Ctrl + A doesn't work on Mac with Pupetter right now - // https://github.com/GoogleChrome/puppeteer/issues/1313 - await pressKeyTimes( 'ArrowRight', textString.length ); - await pressKeyTimes( 'Backspace', textString.length ); + // Replace its content. + await __unstableSelectAll(); await page.keyboard.type( 'and I say hello' ); expect( await getEditedPostContent() ).toMatchSnapshot(); diff --git a/packages/e2e-tests/specs/multi-block-selection.test.js b/packages/e2e-tests/specs/multi-block-selection.test.js index 6bf7a62bf7789..44701ca1e0ce2 100644 --- a/packages/e2e-tests/specs/multi-block-selection.test.js +++ b/packages/e2e-tests/specs/multi-block-selection.test.js @@ -8,6 +8,8 @@ import { pressKeyWithModifier, pressKeyTimes, getEditedPostContent, + selectAllBlocks, + __unstableSelectAll, } from '@wordpress/e2e-test-utils'; describe( 'Multi-block selection', () => { @@ -74,7 +76,11 @@ describe( 'Multi-block selection', () => { // Select all via double shortcut. await page.click( firstBlockSelector ); - await pressKeyWithModifier( 'primary', 'a' ); + // NOTE: `__unstableSelectAll` is used for cross-platform compatibility + // alternative to Cmd+A. The second issuance of the key combination is + // handled internerally by the block editor's KeyboardShortcuts utility + // and is not subject to the same buggy emulation. + await __unstableSelectAll(); await pressKeyWithModifier( 'primary', 'a' ); await expectMultiSelected( blocks, true ); } ); @@ -126,10 +132,7 @@ describe( 'Multi-block selection', () => { await page.keyboard.type( 'Second Paragraph' ); await insertBlock( 'Paragraph' ); await page.keyboard.type( 'Third Paragraph' ); - - // Multiselect via keyboard. - await pressKeyWithModifier( 'primary', 'a' ); - await pressKeyWithModifier( 'primary', 'a' ); + await selectAllBlocks(); // TODO: It would be great to do this test by spying on `wp.a11y.speak`, // but it's very difficult to do that because `wp.a11y` has diff --git a/packages/e2e-tests/specs/reusable-blocks.test.js b/packages/e2e-tests/specs/reusable-blocks.test.js index 73d7b9117bf43..7e25f743f0c82 100644 --- a/packages/e2e-tests/specs/reusable-blocks.test.js +++ b/packages/e2e-tests/specs/reusable-blocks.test.js @@ -5,9 +5,9 @@ import { insertBlock, createNewPost, clickBlockToolbarButton, - pressKeyWithModifier, searchForBlock, getEditedPostContent, + selectAllBlocks, } from '@wordpress/e2e-test-utils'; function waitForAndAcceptDialog() { @@ -210,8 +210,7 @@ describe( 'Reusable Blocks', () => { await page.keyboard.type( 'Second paragraph' ); // Select all the blocks - await pressKeyWithModifier( 'primary', 'a' ); - await pressKeyWithModifier( 'primary', 'a' ); + await selectAllBlocks(); // Convert block to a reusable block await page.waitForSelector( 'button[aria-label="More options"]' ); diff --git a/packages/e2e-tests/specs/rich-text.test.js b/packages/e2e-tests/specs/rich-text.test.js index 5153032953899..2d3d13d3bc6df 100644 --- a/packages/e2e-tests/specs/rich-text.test.js +++ b/packages/e2e-tests/specs/rich-text.test.js @@ -7,6 +7,7 @@ import { insertBlock, clickBlockAppender, pressKeyWithModifier, + __unstableSelectAll, } from '@wordpress/e2e-test-utils'; describe( 'RichText', () => { @@ -30,7 +31,7 @@ describe( 'RichText', () => { it( 'should apply formatting with access shortcut', async () => { await clickBlockAppender(); await page.keyboard.type( 'test' ); - await pressKeyWithModifier( 'primary', 'a' ); + await __unstableSelectAll(); await pressKeyWithModifier( 'access', 'd' ); expect( await getEditedPostContent() ).toMatchSnapshot(); @@ -39,7 +40,7 @@ describe( 'RichText', () => { it( 'should apply formatting with primary shortcut', async () => { await clickBlockAppender(); await page.keyboard.type( 'test' ); - await pressKeyWithModifier( 'primary', 'a' ); + await __unstableSelectAll(); await pressKeyWithModifier( 'primary', 'b' ); expect( await getEditedPostContent() ).toMatchSnapshot();