diff --git a/README.md b/README.md index b704d05..08e9685 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,27 @@ Reads a file and returns its contents as a string. Global setup function for Playwright tests. Ensures fixtures are deleted and global context is set up properly. +#### 👤 User Utilities + +##### `createTranslator( langSlugs, userName = '' )` + +Creates a translator user, based on the `editor` role. + +- **Parameters:** + - `langSlugs`: List of language slugs. + - `userName`: Optional. A user name. Defaults to `XX-YY-translator`, where `XX` and `YY` are language slugs. +- **Returns:** Promise resolving to a user object containing ID, user name, and password. + +##### `switchToUser( user, admin, requestUtils )` + +Switches to the given user. + +- **Parameters:** + - `user`: The user to switch to (an object containing a user name and a password). + - `admin`: Instance of `Admin`. + - `requestUtils`: Gutenberg request utils object. +- **Returns:** Promise resolving to the `Page` object. + #### 💡 Usage Example ```javascript diff --git a/src/index.js b/src/index.js index 77cb858..602fbb8 100644 --- a/src/index.js +++ b/src/index.js @@ -14,6 +14,7 @@ import { createTerm, } from './taxonomies/index.js'; import { fillInXliffExportForm, getXliffRegex } from './xliff/index.js'; +import { createTranslator, switchToUser } from './users/index.js'; import { getDownload, getStringFromFile } from './downloads/index.js'; import { getPlaywrightConfig } from './config/index.js'; import globalSetup from './setup/global.setup.js'; @@ -35,6 +36,8 @@ export { fillInXliffExportForm, getDownload, getXliffRegex, + createTranslator, + switchToUser, getStringFromFile, getPlaywrightConfig, globalSetup, diff --git a/src/users/index.js b/src/users/index.js new file mode 100644 index 0000000..c96bd61 --- /dev/null +++ b/src/users/index.js @@ -0,0 +1,86 @@ +// @ts-check +import { + expect, + Admin, + RequestUtils, +} from '@wordpress/e2e-test-utils-playwright'; +import { execSync } from 'child_process'; + +/** + * @typedef {import('@playwright/test').Page} Page + * @typedef {Object} User + * @property {string} username The user name. + * @property {string} password The user's password. + */ + +/** + * Creates a translator user. + * + * @param {Array} langSlugs Language slugs. + * @param {string} userName Optional. User name. + * Defaults to `XX-YY-translator`, where `XX` and `YY` are language slugs. + * @return {Promise} Promise resolving to a user object containing ID, user name, and password. + */ +export async function createTranslator( langSlugs, userName = '' ) { + userName = + '' === userName + ? `${ langSlugs.join( '-' ).toUpperCase() }-translator` + : userName; + const email = `${ userName.toLowerCase() }@example.com`; + const userId = parseInt( + execSync( + `npx wp-env run tests-cli wp user create ${ userName } ${ email } --role=editor --user_pass=password --porcelain`, + { encoding: 'utf8' } + ).trim(), + 10 + ); + + langSlugs.forEach( ( langSlug ) => { + execSync( + `npx wp-env run tests-cli wp user add-cap ${ userId } translate_${ langSlug }`, + { encoding: 'utf8' } + ); + } ); + + return { id: userId, username: userName, password: 'password' }; +} + +/** + * Switches to the given user. + * Inspired from https://github.com/WordPress/gutenberg/blob/9ee534a42cd546fc2da23ce0f31607467c78c94c/test/e2e/specs/editor/collaboration/fixtures/collaboration-utils.ts#L104. + * + * @param {User} user The user to switch to. + * @param {Admin} admin Instance of `Admin`. + * @param {RequestUtils} requestUtils Gutenberg request utils object. + * @return {Promise} Promise resolving to the `Page` object. + */ +export async function switchToUser( user, admin, requestUtils ) { + const translatorContext = await admin.browser.newContext( { + baseURL: requestUtils.baseURL, + } ); + const page = await translatorContext.newPage(); + + await page.goto( '/wp-login.php' ); + await page.locator( '#user_login' ).fill( user.username ); + await page.locator( '#user_pass' ).fill( user.password ); + await page.getByRole( 'button', { name: 'Log In' } ).click(); + await page.waitForURL( '**/wp-admin/**' ); + + expect( + page.getByRole( 'menuitem', { + name: `Howdy, ${ user.username }`, + } ) + ).toBeVisible(); + + await page.waitForFunction( () => window?.wp?.data && window?.wp?.blocks ); + await page.evaluate( () => { + window.wp.data + .dispatch( 'core/preferences' ) + .set( 'core/edit-post', 'welcomeGuide', false ); + window.wp.data + .dispatch( 'core/preferences' ) + .set( 'core/edit-post', 'fullscreenMode', false ); + } ); + + return page; +}