diff --git a/.eslintrc.js b/.eslintrc.js index b8012f2686cbb8..d5deabd83e0c52 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -350,7 +350,12 @@ module.exports = { }, }, { - files: [ 'packages/components/src/**/*.[tj]s?(x)' ], + files: [ + // Components package. + 'packages/components/src/**/*.[tj]s?(x)', + // Navigation block. + 'packages/block-library/src/navigation/**/*.[tj]s?(x)', + ], excludedFiles: [ ...developmentFiles ], rules: { 'react-hooks/exhaustive-deps': 'error', diff --git a/.github/setup-node/action.yml b/.github/setup-node/action.yml new file mode 100644 index 00000000000000..22cb81618a1efb --- /dev/null +++ b/.github/setup-node/action.yml @@ -0,0 +1,46 @@ +name: 'Setup Node.js and install npm dependencies' +description: 'Configure Node.js and install npm dependencies while managing all aspects of caching.' +inputs: + node-version: + description: 'Optional. The Node.js version to use. When not specified, the version specified in .nvmrc will be used.' + required: false + type: string + +runs: + using: 'composite' + steps: + - name: Use desired version of Node.js + uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + with: + node-version-file: '.nvmrc' + node-version: ${{ inputs.node-version }} + cache: npm + + - name: Get Node.js and npm version + id: node-version + run: | + echo "NODE_VERSION=$(node -v)" >> $GITHUB_OUTPUT + shell: bash + + - name: Cache node_modules + id: cache-node_modules + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + with: + path: '**/node_modules' + key: node_modules-${{ runner.os }}-${{ steps.node-version.outputs.NODE_VERSION }}-${{ hashFiles('package-lock.json') }} + + - name: Install npm dependencies + if: ${{ steps.cache-node_modules.outputs.cache-hit != 'true' }} + run: npm ci + shell: bash + + # On cache hit, we run the post-install script to match the native `npm ci` behavior. + # An example of this is to patch `node_modules` using patch-package. + - name: Post-install + if: ${{ steps.cache-node_modules.outputs.cache-hit == 'true' }} + run: | + # Run the post-install script for the root project. + npm run postinstall + # Run the post-install scripts for workspaces. + npx lerna run postinstall + shell: bash diff --git a/.github/workflows/build-plugin-zip.yml b/.github/workflows/build-plugin-zip.yml index 6e915d0ffddd27..9e30cc1c1cfc67 100644 --- a/.github/workflows/build-plugin-zip.yml +++ b/.github/workflows/build-plugin-zip.yml @@ -168,7 +168,7 @@ jobs: with: ref: ${{ needs.bump-version.outputs.release_branch || github.ref }} - - name: Use desired version of NodeJS + - name: Use desired version of Node.js uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: node-version-file: '.nvmrc' @@ -326,7 +326,7 @@ jobs: git config user.name "Gutenberg Repository Automation" git config user.email gutenberg@wordpress.org - - name: Setup Node (for CLI) + - name: Setup Node.js uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: node-version-file: 'main/.nvmrc' diff --git a/.github/workflows/bundle-size.yml b/.github/workflows/bundle-size.yml index 9ae0116ef1c79b..ea1facacdf236a 100644 --- a/.github/workflows/bundle-size.yml +++ b/.github/workflows/bundle-size.yml @@ -41,7 +41,7 @@ jobs: with: fetch-depth: 1 - - name: Use desired version of NodeJS + - name: Use desired version of Node.js uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: node-version-file: '.nvmrc' diff --git a/.github/workflows/create-block.yml b/.github/workflows/create-block.yml index 304052d4297b87..d0eae662c90978 100644 --- a/.github/workflows/create-block.yml +++ b/.github/workflows/create-block.yml @@ -20,20 +20,17 @@ jobs: strategy: fail-fast: false matrix: - node: [14] + node: ['14'] os: [macos-latest, ubuntu-latest, windows-latest] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Use desired version of NodeJS - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node with: node-version: ${{ matrix.node }} - cache: npm - - name: npm install, build, format and lint + - name: Create block shell: bash - run: | - npm ci - bash ./bin/test-create-block.sh + run: bash ./bin/test-create-block.sh diff --git a/.github/workflows/end2end-test.yml b/.github/workflows/end2end-test.yml index 24256e4266a46e..9bc1224fa11e7c 100644 --- a/.github/workflows/end2end-test.yml +++ b/.github/workflows/end2end-test.yml @@ -29,16 +29,11 @@ jobs: steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Use desired version of NodeJS - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version-file: '.nvmrc' - cache: npm + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node - - name: Npm install and build - run: | - npm ci - npm run build + - name: Npm build + run: npm run build - name: Install WordPress run: | @@ -78,16 +73,11 @@ jobs: steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Use desired version of NodeJS - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version-file: '.nvmrc' - cache: npm + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node - - name: Npm install and build - run: | - npm ci - npm run build + - name: Npm build + run: npm run build - name: Install Playwright dependencies run: | @@ -137,19 +127,14 @@ jobs: name: flaky-tests-report path: flaky-tests - - name: Use desired version of NodeJS + - name: Setup Node.js and install dependencies if: ${{ steps.download_artifact.outcome == 'success' }} - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version-file: '.nvmrc' - cache: npm + uses: ./.github/setup-node - - name: Npm install and build + - name: Npm build if: ${{ steps.download_artifact.outcome == 'success' }} # TODO: We don't have to build the entire project, just the action itself. - run: | - npm ci - npm run build:packages + run: npm run build:packages - name: Report flaky tests if: ${{ steps.download_artifact.outcome == 'success' }} diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index bab6f3d8af5a68..18f11e55b3de88 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -32,22 +32,8 @@ jobs: steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Use desired version of NodeJS - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version-file: '.nvmrc' - cache: npm - - - name: Npm install - run: | - npm ci - - - name: Install specific versions of the themes used in tests - run: | - npm run wp-env start - npm run wp-env -- run tests-cli "wp theme update twentytwentyone --version=1.7" - npm run wp-env -- run tests-cli "wp theme update twentytwentythree --version=1.0" - npm run wp-env stop + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node - name: Compare performance with trunk if: github.event_name == 'pull_request' @@ -94,22 +80,13 @@ jobs: run: | ./bin/plugin/cli.js perf $(echo $BRANCHES | tr ',' ' ') --tests-branch $GITHUB_SHA --wp-version "$WP_VERSION" - - name: Get commit timestamp - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 # v6.4.0 - if: github.event_name == 'push' - id: commit-timestamp - with: - github-token: ${{secrets.GITHUB_TOKEN}} - script: | - const commit_details = await github.rest.git.getCommit({owner: context.repo.owner, repo: context.repo.repo, commit_sha: context.sha}); - return parseInt((new Date( commit_details.data.author.date ).getTime() / 1000).toFixed(0)) - - name: Publish performance results if: github.event_name == 'push' env: - COMMITTED_AT: ${{ steps.commit-timestamp.outputs.result }} CODEHEALTH_PROJECT_TOKEN: ${{ secrets.CODEHEALTH_PROJECT_TOKEN }} - run: ./bin/log-performance-results.js $CODEHEALTH_PROJECT_TOKEN trunk $GITHUB_SHA debd225d007f4e441ceec80fbd6fa96653f94737 $COMMITTED_AT + run: | + COMMITTED_AT=$(git show -s $GITHUB_SHA --format="%ct") + ./bin/log-performance-results.js $CODEHEALTH_PROJECT_TOKEN trunk $GITHUB_SHA debd225d007f4e441ceec80fbd6fa96653f94737 $COMMITTED_AT - name: Archive debug artifacts (screenshots, HTML snapshots) uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 diff --git a/.github/workflows/publish-npm-packages.yml b/.github/workflows/publish-npm-packages.yml index 6568d46989fe65..bc6782ae3ed8f9 100644 --- a/.github/workflows/publish-npm-packages.yml +++ b/.github/workflows/publish-npm-packages.yml @@ -49,7 +49,7 @@ jobs: git config user.name "Gutenberg Repository Automation" git config user.email gutenberg@wordpress.org - - name: Setup Node (for CLI) + - name: Setup Node.js uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: node-version-file: 'main/.nvmrc' diff --git a/.github/workflows/pull-request-automation.yml b/.github/workflows/pull-request-automation.yml index 5163ae3f0ea0cb..b39a54f084c602 100644 --- a/.github/workflows/pull-request-automation.yml +++ b/.github/workflows/pull-request-automation.yml @@ -19,13 +19,13 @@ jobs: with: ref: trunk - - name: Use desired version of NodeJS + - name: Use desired version of Node.js uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: node-version: ${{ matrix.node }} - name: Cache NPM packages - uses: actions/cache@6998d139ddd3e68c71e9e398d8e40b71a2f39812 # v3.2.5 + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 with: # npm cache files are stored in `~/.npm` on Linux/macOS path: ~/.npm diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml index 033789ee30a92d..55d29accbcb8fb 100644 --- a/.github/workflows/rnmobile-android-runner.yml +++ b/.github/workflows/rnmobile-android-runner.yml @@ -31,19 +31,14 @@ jobs: distribution: 'temurin' java-version: '11' - - name: Use desired version of NodeJS - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version-file: '.nvmrc' - cache: npm - - - run: npm ci + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node - name: Gradle cache - uses: gradle/gradle-build-action@3fbe033aaae657f011f88f29be9e65ed26bd29ef # v2.3.3 + uses: gradle/gradle-build-action@6095a76664413da4c8c134ee32e8a8ae900f0f1f # v2.4.0 - name: AVD cache - uses: actions/cache@6998d139ddd3e68c71e9e398d8e40b71a2f39812 # v3.2.5 + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 id: avd-cache with: path: | diff --git a/.github/workflows/rnmobile-ios-runner.yml b/.github/workflows/rnmobile-ios-runner.yml index 52fab007b19173..1a4b1db788371b 100644 --- a/.github/workflows/rnmobile-ios-runner.yml +++ b/.github/workflows/rnmobile-ios-runner.yml @@ -25,19 +25,14 @@ jobs: steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Use desired version of NodeJS - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version-file: '.nvmrc' - cache: npm - - - run: npm ci + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node - name: Prepare build cache key run: find package-lock.json packages/react-native-editor/ios packages/react-native-aztec/ios packages/react-native-bridge/ios -type f -print0 | sort -z | xargs -0 shasum | tee ios-checksums.txt - name: Restore build cache - uses: actions/cache@6998d139ddd3e68c71e9e398d8e40b71a2f39812 # v3.2.5 + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 with: path: | packages/react-native-editor/ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app @@ -45,7 +40,7 @@ jobs: key: ${{ runner.os }}-ios-build-${{ matrix.xcode }}-${{ matrix.device }}-${{ hashFiles('ios-checksums.txt') }} - name: Restore pods cache - uses: actions/cache@6998d139ddd3e68c71e9e398d8e40b71a2f39812 # v3.2.5 + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 with: path: | packages/react-native-editor/ios/Pods diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index 00002aaf52f191..8935ef5e393258 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Use desired version of NodeJS + - name: Use desired version of Node.js uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: node-version-file: '.nvmrc' diff --git a/.github/workflows/storybook-pages.yml b/.github/workflows/storybook-pages.yml index 616fad4e55b5aa..ad49e3274f9ba8 100644 --- a/.github/workflows/storybook-pages.yml +++ b/.github/workflows/storybook-pages.yml @@ -16,14 +16,8 @@ jobs: with: ref: trunk - - name: Use desired version of NodeJS - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version-file: '.nvmrc' - cache: npm - - - name: Install Dependencies - run: npm ci + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node - name: Build Storybook run: npm run storybook:build diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 6552f2ecf6a2b0..a78440bf5ef52e 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -33,19 +33,16 @@ jobs: steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Use desired version of NodeJS - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node with: node-version: ${{ matrix.node }} - cache: npm - - name: Npm install and build + - name: Npm build # It's not necessary to run the full build, since Jest can interpret # source files with `babel-jest`. Some packages have their own custom # build tasks, however. These must be run. - run: | - npm ci - npx lerna run build + run: npx lerna run build - name: Running the tests run: npm run test:unit -- --ci --maxWorkers=2 --cacheDirectory="$HOME/.jest-cache" @@ -79,11 +76,8 @@ jobs: steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Set up Node.js - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version-file: '.nvmrc' - cache: npm + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node ## # This allows Composer dependencies to be installed using a single step. @@ -116,10 +110,8 @@ jobs: with: custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F") - - name: Install npm dependencies - run: | - npm ci - npm run build + - name: Npm build + run: npm run build - name: Docker debug information run: | @@ -182,7 +174,7 @@ jobs: run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> $GITHUB_OUTPUT - name: Cache PHPCS scan cache - uses: actions/cache@6998d139ddd3e68c71e9e398d8e40b71a2f39812 # v3.0.11 + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 with: path: .cache/phpcs.json key: ${{ runner.os }}-date-${{ steps.get-date.outputs.date }}-phpcs-cache-${{ hashFiles('**/composer.json', 'phpcs.xml.dist') }} @@ -235,19 +227,14 @@ jobs: steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Use desired version of NodeJS - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 - with: - node-version-file: '.nvmrc' - cache: npm + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node - - name: Npm install and build + - name: Npm build # It's not necessary to run the full build, since Jest can interpret # source files with `babel-jest`. Some packages have their own custom # build tasks, however. These must be run. - run: | - npm ci - npx lerna run build + run: npx lerna run build - name: Running the tests run: npm run native test -- --ci --maxWorkers=2 --cacheDirectory="$HOME/.jest-cache" diff --git a/bin/plugin/commands/performance.js b/bin/plugin/commands/performance.js index 75ab95a4cc4a10..0d91947da80212 100644 --- a/bin/plugin/commands/performance.js +++ b/bin/plugin/commands/performance.js @@ -3,7 +3,7 @@ */ const fs = require( 'fs' ); const path = require( 'path' ); -const { mapValues, kebabCase } = require( 'lodash' ); +const { mapValues } = require( 'lodash' ); const SimpleGit = require( 'simple-git' ); /** @@ -83,6 +83,17 @@ const config = require( '../config' ); * @property {number=} maxListViewOpen Max time to open list view. */ +/** + * Sanitizes branch name to be used in a path or a filename. + * + * @param {string} branch + * + * @return {string} Sanitized branch name. + */ +function sanitizeBranchName( branch ) { + return branch.replace( /[^a-zA-Z0-9-]/g, '-' ); +} + /** * Computes the average number from an array numbers. * @@ -299,8 +310,8 @@ async function runPerformanceTests( branches, options ) { const branchDirectories = {}; for ( const branch of branches ) { log( ` >> Branch: ${ branch }` ); - const environmentDirectory = - rootDirectory + '/envs/' + kebabCase( branch ); + const sanitizedBranch = sanitizeBranchName( branch ); + const environmentDirectory = rootDirectory + '/envs/' + sanitizedBranch; // @ts-ignore branchDirectories[ branch ] = environmentDirectory; const buildPath = `${ environmentDirectory }/plugin`; @@ -401,7 +412,8 @@ async function runPerformanceTests( branches, options ) { for ( let i = 0; i < TEST_ROUNDS; i++ ) { rawResults[ i ] = {}; for ( const branch of branches ) { - const runKey = `${ branch }_${ testSuite }_run-${ i }`; + const sanitizedBranch = sanitizeBranchName( branch ); + const runKey = `${ sanitizedBranch }_${ testSuite }_run-${ i }`; // @ts-ignore const environmentDirectory = branchDirectories[ branch ]; log( ` >> Branch: ${ branch }, Suite: ${ testSuite }` ); diff --git a/bin/plugin/lib/utils.js b/bin/plugin/lib/utils.js index 4a75437a60694e..c50094321710ca 100644 --- a/bin/plugin/lib/utils.js +++ b/bin/plugin/lib/utils.js @@ -33,6 +33,7 @@ function runShellScript( script, cwd, env = {} ) { NO_CHECKS: 'true', PATH: process.env.PATH, HOME: process.env.HOME, + USER: process.env.USER, ...env, }, }, diff --git a/bin/plugin/utils/.wp-env.performance.json b/bin/plugin/utils/.wp-env.performance.json index 112c2684f64a48..3f80b794ddddd6 100644 --- a/bin/plugin/utils/.wp-env.performance.json +++ b/bin/plugin/utils/.wp-env.performance.json @@ -1,7 +1,11 @@ { "core": "WordPress/WordPress", "plugins": [ "./plugin" ], - "themes": [ "../../tests/test/emptytheme" ], + "themes": [ + "../../tests/test/emptytheme", + "https://downloads.wordpress.org/theme/twentytwentyone.1.7.zip", + "https://downloads.wordpress.org/theme/twentytwentythree.1.0.zip" + ], "env": { "tests": { "mappings": { diff --git a/changelog.txt b/changelog.txt index b0fb1ebb8e463f..8c018ec7f9d05f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,32 +1,774 @@ == Changelog == -= 15.3.0-rc.2 = += 15.4.0-rc.1 = + +## Changelog + +### Enhancements + +#### Site Editor + +- Adjust whileHover effect to be a bit subtler and less pronounced. ([48928](https://github.com/WordPress/gutenberg/pull/48928)) +- Go direct to edit from manage all templates list. ([48764](https://github.com/WordPress/gutenberg/pull/48764)) +- Move "Add Template"'s descriptions to tooltips. ([48710](https://github.com/WordPress/gutenberg/pull/48710)) +- Add descriptions to all panels in the Site Editor's dark side. ([48739](https://github.com/WordPress/gutenberg/pull/48739)) +- Add hover animation to site editor canvas. ([48575](https://github.com/WordPress/gutenberg/pull/48575)) +- Fix non-us spelling in sidebar. ([48976](https://github.com/WordPress/gutenberg/pull/48976)) +- Prevent the saving button from showing when renaming templates. ([48399](https://github.com/WordPress/gutenberg/pull/48399)) +- Navigation Sidebar: Change the logic about which navigation gets selected for the sidebar. ([48689](https://github.com/WordPress/gutenberg/pull/48689)) +- Add "Added by" description to template part navigation sidebar. ([48732](https://github.com/WordPress/gutenberg/pull/48732)) +- Add border radius to off canvas navigation menu items. ([48798](https://github.com/WordPress/gutenberg/pull/48798)) +- Add page details when viewing a specific page. ([48650](https://github.com/WordPress/gutenberg/pull/48650)) +- Duotone: Limit SVG filter output to used filters. ([48995](https://github.com/WordPress/gutenberg/pull/48995)) +- Hide navigation screen in site editor. ([49043](https://github.com/WordPress/gutenberg/pull/49043)) + +#### Block Library + +- Open convert to links modal on select of a page item. ([48723](https://github.com/WordPress/gutenberg/pull/48723)) +- Query Block: Add tests for `getValueFromObjectPath()` util. ([48956](https://github.com/WordPress/gutenberg/pull/48956)) +- Post Featured Image: Remove 16:10. ([48969](https://github.com/WordPress/gutenberg/pull/48969)) +- Cover: Add constrained/flow layout. ([45326](https://github.com/WordPress/gutenberg/pull/45326)) + +#### Components + +- FontSizePicker: Allow custom units. ([48468](https://github.com/WordPress/gutenberg/pull/48468)) +- `Navigator`: Disable initial animation. ([49062](https://github.com/WordPress/gutenberg/pull/49062)) +- Try: Update Tertiary Button appearance. ([48888](https://github.com/WordPress/gutenberg/pull/48888)) +- FormTokenField: Hide suggestions list on blur event if input value is invalid. ([48785](https://github.com/WordPress/gutenberg/pull/48785)) + +#### Design Tools + +- Block Supports: Add text columns (column count) to typography block supports. ([33587](https://github.com/WordPress/gutenberg/pull/33587)) +- Cover: Add text color block support. ([41572](https://github.com/WordPress/gutenberg/pull/41572)) + +#### Global Styles + +- Move the global styles provider to the app level component. ([49011](https://github.com/WordPress/gutenberg/pull/49011)) +- Add support for `:link` and `:Any-link` in `theme.json`. ([48634](https://github.com/WordPress/gutenberg/pull/48634)) +- Add compound class to layout wrapper for global spacing styles. ([47952](https://github.com/WordPress/gutenberg/pull/47952)) + +#### Block API + +- Block Deprecations: Provide extra data for isEligible check. ([48815](https://github.com/WordPress/gutenberg/pull/48815)) + +#### Post Editor + +- Provide static native editor help article slugs. ([48802](https://github.com/WordPress/gutenberg/pull/48802)) +- Try getting Post Content layout on server before editor loads. ([45299](https://github.com/WordPress/gutenberg/pull/45299)) + +#### Packages + +- Introduce prependHTTPS URL util. ([47648](https://github.com/WordPress/gutenberg/pull/47648)) + +### Bug Fixes + +#### Block Library + +- Embed Block: Fix Aspect Ratio Classes #29641. ([41141](https://github.com/WordPress/gutenberg/pull/41141)) +- Ensure aspect ratio is applied when Post Featured Image block is linked. ([48495](https://github.com/WordPress/gutenberg/pull/48495)) +- Fix PostContent initial render by waiting for the canEdit request. ([48642](https://github.com/WordPress/gutenberg/pull/48642)) +- Fix classic menu fallback race condition. ([48811](https://github.com/WordPress/gutenberg/pull/48811)) +- Fix navigation block off-canvas appender for empty menus. ([48907](https://github.com/WordPress/gutenberg/pull/48907)) +- Fixes extra UI in navigation block inspector. ([48679](https://github.com/WordPress/gutenberg/pull/48679)) +- Import Classic Menu using the menu name as the block menu title. ([48771](https://github.com/WordPress/gutenberg/pull/48771)) +- Navigation Link: Remove color generation code. ([48927](https://github.com/WordPress/gutenberg/pull/48927)) +- Navigation: Fix missing state for MenuControls. ([48921](https://github.com/WordPress/gutenberg/pull/48921)) +- Update missing translation from label. ([48760](https://github.com/WordPress/gutenberg/pull/48760)) +- Widget Importer: Fix Widget Group block imports. ([48669](https://github.com/WordPress/gutenberg/pull/48669)) +- Query Loop: Show variant patterns even if there are no patterns for the Query Loop block. ([48793](https://github.com/WordPress/gutenberg/pull/48793)) +- Comments: Fix 'sprintf requires more than 1 params' error. ([49054](https://github.com/WordPress/gutenberg/pull/49054)) +- Adjust Post Featured Image PanelBody label to "Settings". ([49076](https://github.com/WordPress/gutenberg/pull/49076)) +- Add help text to Gallery Image Size control. ([49074](https://github.com/WordPress/gutenberg/pull/49074)) +- Comments Block (Legacy): Update missing translation. ([48820](https://github.com/WordPress/gutenberg/pull/48820)) +- I18n of created Navigation menu title. ([48773](https://github.com/WordPress/gutenberg/pull/48773)) +- Make sure the directly inserted block in the Nav block is a Page link. ([48740](https://github.com/WordPress/gutenberg/pull/48740)) +- Navigation Link: Don't remove 'block_core_navigation_link_build_css_colors'. ([49064](https://github.com/WordPress/gutenberg/pull/49064)) +- Navigation: Don't save the level of the link in an attribute. ([48219](https://github.com/WordPress/gutenberg/pull/48219)) +- Refactor away state in Nav menu selector. ([45464](https://github.com/WordPress/gutenberg/pull/45464)) +- Revert: Navigation: Always create a fallback menu. ([48602](https://github.com/WordPress/gutenberg/pull/48602)) +- Tweak Latest Posts block PanelBody labels. ([49079](https://github.com/WordPress/gutenberg/pull/49079)) +- Tweak label for Latest Posts excerpt control. ([49077](https://github.com/WordPress/gutenberg/pull/49077)) +- [Page list Block] Show untitled pages on page list on the editor. ([48772](https://github.com/WordPress/gutenberg/pull/48772)) + +#### Site Editor + +- Don't offer Classic block as a recovery action when not registered. ([49051](https://github.com/WordPress/gutenberg/pull/49051)) +- Fix browser history when synchronising state with urls. ([48731](https://github.com/WordPress/gutenberg/pull/48731)) +- Fix lingering insertion point within template parts. ([48913](https://github.com/WordPress/gutenberg/pull/48913)) +- Fix template part actions in List View. ([48905](https://github.com/WordPress/gutenberg/pull/48905)) +- Fix text alignment in the Site Editor sidebar. ([48959](https://github.com/WordPress/gutenberg/pull/48959)) +- Fix typo in template parts description. ([48781](https://github.com/WordPress/gutenberg/pull/48781)) +- Fix browse mode descriptions margin. ([48778](https://github.com/WordPress/gutenberg/pull/48778)) +- Fix scrollbar in site editor. ([48822](https://github.com/WordPress/gutenberg/pull/48822)) +- Site Editor Navigation panel: Update appearance of non-link blocks. ([48933](https://github.com/WordPress/gutenberg/pull/48933)) +- Navigation sidebar shows a wrong submenu popover. ([48941](https://github.com/WordPress/gutenberg/pull/48941)) +- Show creation popover on empty page links in the navigation sidebar. ([48746](https://github.com/WordPress/gutenberg/pull/48746)) +- Site button metrics. ([48918](https://github.com/WordPress/gutenberg/pull/48918)) +- Remove actions from SidebarNavigationScreenWrapper. ([48935](https://github.com/WordPress/gutenberg/pull/48935)) +- Update template descriptions with more detail. ([48934](https://github.com/WordPress/gutenberg/pull/48934)) + +#### Global Styles + +- Fix typo: Use WP_Theme_JSON_Gutenberg instead of WP_Theme_JSON class name. ([48648](https://github.com/WordPress/gutenberg/pull/48648)) +- Fix: Crashes on getNodesWithSettings and getNodesWithStyles. ([49023](https://github.com/WordPress/gutenberg/pull/49023)) +- Fix: Global Styles crash in updateConfigWithSeparator when not block styles are passed. ([49045](https://github.com/WordPress/gutenberg/pull/49045)) +- Fix: Global Styles getNodesWithStyles expects an object with elements. ([49044](https://github.com/WordPress/gutenberg/pull/49044)) +- Fix: Global Styles getPresetsClasses crashes if no selector is passed. ([49024](https://github.com/WordPress/gutenberg/pull/49024)) +- Fix: Global styles forces a white background. ([49042](https://github.com/WordPress/gutenberg/pull/49042)) +- Style Book: Move iframe to root of content area to support styles that overflow block previews. ([48664](https://github.com/WordPress/gutenberg/pull/48664)) +- `WP_Theme_JSON`: Sync indirect properties changes from core. ([48646](https://github.com/WordPress/gutenberg/pull/48646)) + +#### Components + +- Fix HStack and VStack alignment prop. ([47914](https://github.com/WordPress/gutenberg/pull/47914)) +- ResizeTooltip: Use default.fontFamily on tooltip. ([48805](https://github.com/WordPress/gutenberg/pull/48805)) +- ResponsiveWrapper: Use aspect-ratio CSS prop and support SVG elements. ([48573](https://github.com/WordPress/gutenberg/pull/48573)) + +#### Accessibility + +- Make sure useFocusOnMount runs when all the children tabbable elements have mounted. ([42187](https://github.com/WordPress/gutenberg/pull/42187)) +- Manage selection on block sync. ([48979](https://github.com/WordPress/gutenberg/pull/48979)) + +#### Post Editor + +- Distraction Free Mode: Don't show the metaboxes. ([48947](https://github.com/WordPress/gutenberg/pull/48947)) +- Don't add Post Content layout styles to title in the post editor. ([48663](https://github.com/WordPress/gutenberg/pull/48663)) +- Fix animation and browser console error when returning from template edit mode. ([48930](https://github.com/WordPress/gutenberg/pull/48930)) + +#### Block Editor + +- LinkControl: Remove HTML from suggestion title before passing it to TextHighlight component. ([48685](https://github.com/WordPress/gutenberg/pull/48685)) +- Order initial block items in Navigation with PrivateInserter. ([48752](https://github.com/WordPress/gutenberg/pull/48752)) +- BlockInvalidWarning: Prefer `canInsertBlockType` and refactor to hooks. ([49052](https://github.com/WordPress/gutenberg/pull/49052)) +- Fix grouping actions in List View. ([48910](https://github.com/WordPress/gutenberg/pull/48910)) +- Fix typo in the media-categories component. ([49047](https://github.com/WordPress/gutenberg/pull/49047)) +- Custom link UI does appears outside canvas on the sidebar navigation. ([48633](https://github.com/WordPress/gutenberg/pull/48633)) +- Use proper color for block styles control. ([46684](https://github.com/WordPress/gutenberg/pull/46684)) +- Update Welcome Guide article links to avoid redirect. ([48582](https://github.com/WordPress/gutenberg/pull/48582)) +- Columns Block: Don't show the column count change UI when `templateLock` is `all`. ([48691](https://github.com/WordPress/gutenberg/pull/48691)) +- Remove border from quick inserter child elements. ([48794](https://github.com/WordPress/gutenberg/pull/48794)) + +#### Inspector Controls +- Fix settings tab active state border in block inspector. ([48945](https://github.com/WordPress/gutenberg/pull/48945)) + +#### Testing + +- Playwright Utils: Fix the 'publishPost' address locator. ([48729](https://github.com/WordPress/gutenberg/pull/48729)) + +#### CSS & Styling +- Fix duplication of block classname in feature selectors for style variations. ([48662](https://github.com/WordPress/gutenberg/pull/48662)) + +#### Experimental + +- Fix KSES filter for un-prettified filters. ([49004](https://github.com/WordPress/gutenberg/pull/49004)) + +#### Packages + +- Rich text: Fix range equality checks for Safari. ([48733](https://github.com/WordPress/gutenberg/pull/48733)) +- Preferences Modal: Fix double focus outline in tab item. ([48996](https://github.com/WordPress/gutenberg/pull/48996)) + +#### Tools + +- Scripts: Fix `render.php` isn't copied in Windows OS. ([48735](https://github.com/WordPress/gutenberg/pull/48735)) + +#### Mobile + +- Mobile - Fix parsing of CSS units for null matched values. ([48484](https://github.com/WordPress/gutenberg/pull/48484)) + +### Performance + +#### Block Editor + +- Rich text: useAnchor: Remove value dependency. ([48715](https://github.com/WordPress/gutenberg/pull/48715)) + +#### Post Editor + +- Lodash: Refactor away from `_.kebabCase()` in `EditorHelpTopics`. ([48776](https://github.com/WordPress/gutenberg/pull/48776)) +- Lodash: Refactor away from `edit-post` package. ([48786](https://github.com/WordPress/gutenberg/pull/48786)) + +#### Site Editor + +- Improve the Navigation panel's menu query. ([48908](https://github.com/WordPress/gutenberg/pull/48908)) +- Improve Site Editor performance tests. ([48138](https://github.com/WordPress/gutenberg/pull/48138)) + +#### Testing + +- Lodash: Remove from e2e-tests package. ([48775](https://github.com/WordPress/gutenberg/pull/48775)) + +#### Themes + +- Fix: Incorrect selector generated by `append_to_selector` method. ([48759](https://github.com/WordPress/gutenberg/pull/48759)) + +#### Block Library + +- Lodash: Remove `_.get()` from various blocks. ([48491](https://github.com/WordPress/gutenberg/pull/48491)) + +#### Data Layer + +- Lodash: Refactor away from `_.set()` in core-data. ([48784](https://github.com/WordPress/gutenberg/pull/48784)) + +#### GitHub Actions + +- Prefer committer over author date for perf results timestamp. ([48673](https://github.com/WordPress/gutenberg/pull/48673)) + +### Documentation + +- Add links to hook documentation in curation doc. ([48653](https://github.com/WordPress/gutenberg/pull/48653)) +- Add missing playwright end-to-end documentation to toc.json. ([48447](https://github.com/WordPress/gutenberg/pull/48447)) +- Adding examples of how to programmatically remove the panels in Document sidebar. ([48895](https://github.com/WordPress/gutenberg/pull/48895)) +- Adds link to post on the developer blog to the deprecation page. ([49069](https://github.com/WordPress/gutenberg/pull/49069)) +- Add position: Sticky to the Opt-in into UI controls appearanceTools section. ([48763](https://github.com/WordPress/gutenberg/pull/48763)) +- Fix broken Lerna documentation link. ([48890](https://github.com/WordPress/gutenberg/pull/48890)) +- Table of styles keys with since versions. ([48265](https://github.com/WordPress/gutenberg/pull/48265)) +- Fix URL mismatch. ([48931](https://github.com/WordPress/gutenberg/pull/48931)) +- Theme JSON schema: Add sticky position to settings, minHeight to styles. ([48948](https://github.com/WordPress/gutenberg/pull/48948)) +- Update the end-to-end tests documentation. ([48951](https://github.com/WordPress/gutenberg/pull/48951)) +- jest-preset-default: Update README to reflect current status. ([48925](https://github.com/WordPress/gutenberg/pull/48925)) + +### Code Quality + +#### Components + +- Autocomplete: Refactor to TypeScript. ([47751](https://github.com/WordPress/gutenberg/pull/47751)) +- Navigation: Refactor to TypeScript. ([48742](https://github.com/WordPress/gutenberg/pull/48742)) +- SelectControl: Improve prop types for single vs multiple selection. ([47390](https://github.com/WordPress/gutenberg/pull/47390)) +- `DimensionControl(Experimental)`: Refactor to TypeScript. ([47351](https://github.com/WordPress/gutenberg/pull/47351)) +- `Guide`: Refactor to TypeScript. ([47493](https://github.com/WordPress/gutenberg/pull/47493)) +- `Icon`: Refactor tests to TypeScript. ([49066](https://github.com/WordPress/gutenberg/pull/49066)) +- `PaletteEdit`: Refactor away from `lodash.kebabCase`. ([48637](https://github.com/WordPress/gutenberg/pull/48637)) +- `QueryControls`: Refactor away from `lodash.groupBy`. ([48779](https://github.com/WordPress/gutenberg/pull/48779)) +- components/utils/font: Refactor away from lodash `.get`. ([48629](https://github.com/WordPress/gutenberg/pull/48629)) +- remove lodash from `context/getStyledClassName`:. ([48688](https://github.com/WordPress/gutenberg/pull/48688)) +- withSpokenMessages: Change js files to typescript. ([48163](https://github.com/WordPress/gutenberg/pull/48163)) + +#### Block Library + +- Add Nav block files to those triggering error for exhaustive deps. ([48821](https://github.com/WordPress/gutenberg/pull/48821)) +- Fix Nav block exhaustive deps warnings. ([48680](https://github.com/WordPress/gutenberg/pull/48680)) +- Media Text: Refactored constants to it's designated file. ([48480](https://github.com/WordPress/gutenberg/pull/48480)) +- Navigation: Simplify the method for finding the fallback menu. ([48916](https://github.com/WordPress/gutenberg/pull/48916)) +- Duotone.php code cleanup. ([48607](https://github.com/WordPress/gutenberg/pull/48607)) +- Revert "Duotone: Limit SVG filter output to used filters". ([49102](https://github.com/WordPress/gutenberg/pull/49102)) + +#### Block Editor + +- Inserter: Remove outer scope values dependencies. ([48961](https://github.com/WordPress/gutenberg/pull/48961)) +- Inserter: Remove unnecessary dependency 'delayedFilterValue'. ([48960](https://github.com/WordPress/gutenberg/pull/48960)) +- Remove unused CSS from LinkControl Apply button. ([48431](https://github.com/WordPress/gutenberg/pull/48431)) +- Custom Classname block support: Update code comments to remove reference to anchor id. ([48709](https://github.com/WordPress/gutenberg/pull/48709)) +- List View: Remove unused selector from the 'useBlockSelection' hook. ([48984](https://github.com/WordPress/gutenberg/pull/48984)) +- Renames parent selection boolean param and improves documentation. ([48677](https://github.com/WordPress/gutenberg/pull/48677)) +- Tests: Cleanup unnecessary jest timers setup. ([49030](https://github.com/WordPress/gutenberg/pull/49030)) +- Avoid declaring a function inside another function. ([49049](https://github.com/WordPress/gutenberg/pull/49049)) + +#### Global Styles + +- Theme JSON: Clarify status of fixed position opt-in in appearance tools. ([48660](https://github.com/WordPress/gutenberg/pull/48660)) +- Extract a BorderPanel component as a reusable component between Global Styles and Block Inspector. ([48636](https://github.com/WordPress/gutenberg/pull/48636)) + +#### Data Layer + +- Data: Use real timers for private APIs tests. ([49029](https://github.com/WordPress/gutenberg/pull/49029)) + +#### Packages + +- Preferences: Remove `types` field from `package.json`. ([49053](https://github.com/WordPress/gutenberg/pull/49053)) +- Upgrade `typescript` to 4.9.5. ([48299](https://github.com/WordPress/gutenberg/pull/48299)) +- Compose: Remove useAsyncList from mobile exports. ([48241](https://github.com/WordPress/gutenberg/pull/48241)) +- Animation: Refactor to TypeScript. ([47042](https://github.com/WordPress/gutenberg/pull/47042)) +- PanelBody: Convert to TypeScript. ([47702](https://github.com/WordPress/gutenberg/pull/47702)) +- Refactor ToolbarContext to TS. ([49002](https://github.com/WordPress/gutenberg/pull/49002)) +- Refactor/toolbar button component to typescript. ([47750](https://github.com/WordPress/gutenberg/pull/47750)) +- `PaletteEdit`: Convert to TypeScript. ([47764](https://github.com/WordPress/gutenberg/pull/47764)) +- navigateRegions: Convert to TypeScript. ([48632](https://github.com/WordPress/gutenberg/pull/48632)) +- withFallbackStyles: Convert to TypeScript. ([48720](https://github.com/WordPress/gutenberg/pull/48720)) +- withFilters: Convert to TypeScript. ([48721](https://github.com/WordPress/gutenberg/pull/48721)) +- withFocusReturn: Convert to TypeScript. ([48748](https://github.com/WordPress/gutenberg/pull/48748)) +- withNotices: Convert to TypeScript. ([49088](https://github.com/WordPress/gutenberg/pull/49088)) +- Packages: Remove completely two deprecated webpack plugins. ([48770](https://github.com/WordPress/gutenberg/pull/48770)) + +### Tools + +- Env: Fix typo / grammar README.md. ([48952](https://github.com/WordPress/gutenberg/pull/48952)) +- ci: Add Rich Text code owner. ([48727](https://github.com/WordPress/gutenberg/pull/48727)) + +#### Testing + +- Add `pageUtils.pressKeys` to playwright utils. ([49009](https://github.com/WordPress/gutenberg/pull/49009)) +- Add artifacts upload for the performance tests. ([48243](https://github.com/WordPress/gutenberg/pull/48243)) +- Fix flaky block hierarchy navigation test by better inserter selection. ([48780](https://github.com/WordPress/gutenberg/pull/48780)) +- Migrate multi-block selection end-to-end tests to Playwright. ([48035](https://github.com/WordPress/gutenberg/pull/48035)) +- Navigation block end-to-end tests: Default to my most recently created menu. ([48132](https://github.com/WordPress/gutenberg/pull/48132)) +- Upgrade Jest from 27 to 29.5.0. ([47388](https://github.com/WordPress/gutenberg/pull/47388)) +- Duotone: Style Engine: Add unit test and associated refactoring. ([49033](https://github.com/WordPress/gutenberg/pull/49033)) + +## First time contributors + +The following PRs were merged by first time contributors: + +- @anver: Env: Fix typo / grammar README.md. ([48952](https://github.com/WordPress/gutenberg/pull/48952)) +- @bhavz-10: withSpokenMessages: Change js files to typescript. ([48163](https://github.com/WordPress/gutenberg/pull/48163)) +- @krishneup: Update missing translation from label. ([48760](https://github.com/WordPress/gutenberg/pull/48760)) +- @mike-day: Refactor/toolbar button component to typescript. ([47750](https://github.com/WordPress/gutenberg/pull/47750)) +- @shvlv: FormTokenField: Hide suggestions list on blur event if input value is invalid. ([48785](https://github.com/WordPress/gutenberg/pull/48785)) +- @TylerB24890: Embed Block: Fix Aspect Ratio Classes #29641. ([41141](https://github.com/WordPress/gutenberg/pull/41141)) + + +## Contributors + +The following contributors merged PRs in this release: + +@aaronrobertshaw @afercia @ajlende @andrewserong @anver @aristath @bhavz-10 @brookewp @chad1008 @ciampo @DaisyOlsen @dcalhoun @draganescu @ellatrix @fabiankaegy @felixarntz @flootr @fluiddot @geriux @getdave @glendaviesnz @gvgvgvijayan @gziolo @hideokamoto @jameskoster @jasmussen @jeryj @jorgefilipecosta @jsnajdr @kevin940726 @kienstra @krishneup @MaggieCabrera @Mamaduka @mburridge @mike-day @mirka @mtias @ndiego @ntsekouras @oandregal @Rahmon @richtabor @ryanwelcher @SavPhill @scruffian @shvlv @SiobhyB @swissspidy @t-hamano @talldan @tellthemachines @tomdevisser @TylerB24890 @tyxla @WunderBart @youknowriad + + += 15.3.1 = + + + +## Changelog + +### Enhancements + +#### Site Editor +- Refactor the site editor URLs for better backward compatibility. ([48063](https://github.com/WordPress/gutenberg/pull/48063)) +- Remove TemplateAreas from template details. ([48490](https://github.com/WordPress/gutenberg/pull/48490)) +- Update the edit button. ([48584](https://github.com/WordPress/gutenberg/pull/48584)) +- Change "Browse all templates" to "Manage all templates" in template details popover. ([48496](https://github.com/WordPress/gutenberg/pull/48496)) +- Match color of the focus template view with site dark material. ([48430](https://github.com/WordPress/gutenberg/pull/48430)) +- Polish add template modal style. ([48445](https://github.com/WordPress/gutenberg/pull/48445)) +- Site Editor Sidebar: Add line-height for template/parts name and update width for edit button. ([48160](https://github.com/WordPress/gutenberg/pull/48160)) +- Extract a DimensionsPanel component as a reusable component between Global Styles and Block Inspector. ([48070](https://github.com/WordPress/gutenberg/pull/48070)) +- Remove copy for managing a block's style variations. ([48367](https://github.com/WordPress/gutenberg/pull/48367)) + +#### Block Editor +- Apply keyboard shortcut conversions between paragraphs and headings to all editor instances. ([47972](https://github.com/WordPress/gutenberg/pull/47972)) +- Create automatic change higher order reducer. ([48312](https://github.com/WordPress/gutenberg/pull/48312)) +- [Inserter]: Preload media categories empty check - client side. ([47503](https://github.com/WordPress/gutenberg/pull/47503)) + +#### Post Editor +- Revert iframed editor for WP core only. ([48076](https://github.com/WordPress/gutenberg/pull/48076)) +- PageAttributesCheck: Return boolean value directly from the selector. ([48336](https://github.com/WordPress/gutenberg/pull/48336)) +- Apply busy status to the publish button in progress and unify button width. ([48444](https://github.com/WordPress/gutenberg/pull/48444)) + +#### Block Library +- Add all allowed innerblocks to the inspector animation experiment. ([47834](https://github.com/WordPress/gutenberg/pull/47834)) +- Make the Site Logo block placeholder state smaller. ([48218](https://github.com/WordPress/gutenberg/pull/48218)) +- ToggleControl: Remove margin overrides and add opt-in prop. ([47866](https://github.com/WordPress/gutenberg/pull/47866)) +- Post Terms block: Add transforms for variations. ([48328](https://github.com/WordPress/gutenberg/pull/48328)) +- List block: Add Firefox end-to-end tests. ([48271](https://github.com/WordPress/gutenberg/pull/48271)) +- Navigation List View: Add block movers to the more menu. ([48099](https://github.com/WordPress/gutenberg/pull/48099)) +- Navigation: Always create a fallback menu. ([47684](https://github.com/WordPress/gutenberg/pull/47684)) +- Navigation: Don't create a fallback navigation menu if there are inner blocks. ([48585](https://github.com/WordPress/gutenberg/pull/48585)) +- Navigation: Don't create duplicate navigation menus. ([48599](https://github.com/WordPress/gutenberg/pull/48599)) +- Navigation: Update the dependencies for the useEffect that handles notifications. ([48066](https://github.com/WordPress/gutenberg/pull/48066)) +- Navigation: Wrap the dependent functions in useCallback. ([48195](https://github.com/WordPress/gutenberg/pull/48195)) +- Page List: Move the modal to its own file. ([47922](https://github.com/WordPress/gutenberg/pull/47922)) +- [New Block] Add post time to read block. ([43403](https://github.com/WordPress/gutenberg/pull/43403)) +- Classic Block: Replace the deprecated `isPrimary` prop with `variant`. ([48230](https://github.com/WordPress/gutenberg/pull/48230)) +- Refactor core blocks to use HTML Tag Processor. ([43178](https://github.com/WordPress/gutenberg/pull/43178)) + +#### Block API +- HTML Tag Processor: Add WP 6.3 compat layer. ([47933](https://github.com/WordPress/gutenberg/pull/47933)) +- Tag Processor: Add bookmark invalidation logic. ([47559](https://github.com/WordPress/gutenberg/pull/47559)) + +#### Design Tools +- Duotone: Use the style engine to generate CSS for Duotone. ([48281](https://github.com/WordPress/gutenberg/pull/48281)) +- Duotone: Add Global Styles controls for blocks that support duotone. ([48255](https://github.com/WordPress/gutenberg/pull/48255)) +- Use Duotone presets in block duotone attributes. ([48318](https://github.com/WordPress/gutenberg/pull/48318)) +- Duotone: Use CSS variables instead of slugs in block attributes. ([48426](https://github.com/WordPress/gutenberg/pull/48426)) +- Border Panel: Add missing dep for `onBorderChange` callback. ([48010](https://github.com/WordPress/gutenberg/pull/48010)) +- Disable layout toolbar controls for content locked blocks. ([47939](https://github.com/WordPress/gutenberg/pull/47939)) +- SpacingSizesControl: Fix white dot on thumb. ([48574](https://github.com/WordPress/gutenberg/pull/48574)) + +#### List View +- Scroll selected block into view when single block selection changes. ([46895](https://github.com/WordPress/gutenberg/pull/46895)) + +#### Components +- TabPanel: Refactor unit tests in prep for controlled component updates. ([48086](https://github.com/WordPress/gutenberg/pull/48086)) +- Change higher order `with-constraint-tabbing` from `.js` to `.tsx`. ([48162](https://github.com/WordPress/gutenberg/pull/48162)) +- CircularOptionPicker: Refactor to TypeScript. ([47937](https://github.com/WordPress/gutenberg/pull/47937)) +- Extract delete handler to hook for RichText. ([48273](https://github.com/WordPress/gutenberg/pull/48273)) +- ToolsPanel: Remove unnecessary dep from resetAll callback. ([48011](https://github.com/WordPress/gutenberg/pull/48011)) +- Link Control - Add support for text only labels. ([47930](https://github.com/WordPress/gutenberg/pull/47930)) +- Pin `floating-ui/react-dom` version. ([48402](https://github.com/WordPress/gutenberg/pull/48402)) +- Use React 18 rendering for import dropdown. ([48244](https://github.com/WordPress/gutenberg/pull/48244)) + +### Bug Fixes + +#### Site Editor +- Fix Site Editor perf tests. ([48240](https://github.com/WordPress/gutenberg/pull/48240)) +- Fix routing for Classic themes using block-based template parts. ([48343](https://github.com/WordPress/gutenberg/pull/48343)) +- Fix the 'Browse all' link in the template details modal. ([48301](https://github.com/WordPress/gutenberg/pull/48301)) +- Fix the site editor home page loading when installed in a subdirectory. ([48363](https://github.com/WordPress/gutenberg/pull/48363)) +- Fix the tooltip and shortcut for the global save button. ([48282](https://github.com/WordPress/gutenberg/pull/48282)) +- Prevent distracting focused back button on site editor load. ([48472](https://github.com/WordPress/gutenberg/pull/48472)) +- Sort templates and template parts by slug. ([48473](https://github.com/WordPress/gutenberg/pull/48473)) +- Specify focus state color for template navigation button. ([48134](https://github.com/WordPress/gutenberg/pull/48134)) +- [Site Editor]: Set `html` block as freeform fallback block. ([48129](https://github.com/WordPress/gutenberg/pull/48129)) +- Remove broken site editor redirect. ([48283](https://github.com/WordPress/gutenberg/pull/48283)) +- Fix: Inserter does not appear on sidebar navigation. ([48623](https://github.com/WordPress/gutenberg/pull/48623)) +- Fix: Make navigation page list load its items on navigation sidebar. ([47853](https://github.com/WordPress/gutenberg/pull/47853)) +- Revert Site Tagline placeholder attribute, move example to block.json. ([48383](https://github.com/WordPress/gutenberg/pull/48383)) + +#### Block Editor +- MediaReplaceFlow: Fix styling for LinkControl. ([47949](https://github.com/WordPress/gutenberg/pull/47949)) +- Fix "Reset All" button in the typography panel of the block inspector. ([48123](https://github.com/WordPress/gutenberg/pull/48123)) +- [Inserter - Media tab]: Upload Openverse images when inserted. ([48501](https://github.com/WordPress/gutenberg/pull/48501)) +- Block alignment controls: Don't remount the block when alignments change. ([48209](https://github.com/WordPress/gutenberg/pull/48209)) +- Pin `valtio` version. ([48237](https://github.com/WordPress/gutenberg/pull/48237)) +- Fix block style preview flickering when a 'style' is focused. ([48418](https://github.com/WordPress/gutenberg/pull/48418)) +- Enable access to block settings within UBE. ([48435](https://github.com/WordPress/gutenberg/pull/48435)) +- Fix: Content only CPT template locking. ([48434](https://github.com/WordPress/gutenberg/pull/48434)) +- Firefox: Fix input rules (React async state issue). ([48210](https://github.com/WordPress/gutenberg/pull/48210)) +- Fix: Multiple overwrites on rest_controller_class for wp_template/wp_template_part. ([48078](https://github.com/WordPress/gutenberg/pull/48078)) +- Select blocks in `outline` list. ([48118](https://github.com/WordPress/gutenberg/pull/48118)) +- Only add layout classes to inner wrapper if block is a container. ([48611](https://github.com/WordPress/gutenberg/pull/48611)) + +#### Widgets Editor +- Widget Editor: Fix a problem with 'Move to Widget Area' button not working. ([48233](https://github.com/WordPress/gutenberg/pull/48233)) + +#### Block Library +- Add support for orientation-based block movers to core/social-links. ([48452](https://github.com/WordPress/gutenberg/pull/48452)) +- Fix Post Excerpt: Read more link is always on new line in the editor. ([47772](https://github.com/WordPress/gutenberg/pull/47772)) +- Fix: OffCanvasEditor does not inserts submenu on collapsed items. ([48214](https://github.com/WordPress/gutenberg/pull/48214)) +- List Item: Avoid an error when the 'onReplace' prop is undefined. ([48639](https://github.com/WordPress/gutenberg/pull/48639)) +- Add missing code on the fix page list loading PR. ([48621](https://github.com/WordPress/gutenberg/pull/48621)) +- Prevent text decoration from showing up in all blocks. ([48117](https://github.com/WordPress/gutenberg/pull/48117)) +- Widget Importer: Don't render controls when there's nothing to import. ([48396](https://github.com/WordPress/gutenberg/pull/48396)) +- [Query Loop] Fix top border in pattern selection modal. ([48303](https://github.com/WordPress/gutenberg/pull/48303)) +- [Query Loop] Sync `gutenberg_build_query_vars_from_query_block` with core. ([48640](https://github.com/WordPress/gutenberg/pull/48640)) +- Avatar: Clean up border application in editor. ([48024](https://github.com/WordPress/gutenberg/pull/48024)) + +#### Global Styles +- Fix for `WP_Theme_JSON_Resolver_Gutenberg::Get_merged_data`. ([48644](https://github.com/WordPress/gutenberg/pull/48644)) +- Display preset names via the tooltip. ([48304](https://github.com/WordPress/gutenberg/pull/48304)) +- Fix typo in valid settings for fluid typography. ([48605](https://github.com/WordPress/gutenberg/pull/48605)) +- Prevent the global styles previews thumbnails from resizing on load. ([48474](https://github.com/WordPress/gutenberg/pull/48474)) +- Site Tagline: Add example so that it will display in style book. ([48300](https://github.com/WordPress/gutenberg/pull/48300)) +- Fix wrong property name letterSpacing to lineHeight. ([48091](https://github.com/WordPress/gutenberg/pull/48091)) +- Update code position for constants and methods in `WP_Theme_JSON_Gutenberg` class. ([48631](https://github.com/WordPress/gutenberg/pull/48631)) +- `WP_Theme_JSON_Gutenberg`: Update comments to be aligned with core, so backports are easier. ([48624](https://github.com/WordPress/gutenberg/pull/48624)) + +### Accessibility +- Autocomplete: Duplicate list within iframe for non visual users. ([47907](https://github.com/WordPress/gutenberg/pull/47907)) +- Fix site editor switch mode message. ([48136](https://github.com/WordPress/gutenberg/pull/48136)) +- Fix the Publish region position and focus style. ([48102](https://github.com/WordPress/gutenberg/pull/48102)) +- Focus 1st parent block on block remove, if no previous block is available. ([48204](https://github.com/WordPress/gutenberg/pull/48204)) +- List view: Allow selected block to override roving tabindex. ([48339](https://github.com/WordPress/gutenberg/pull/48339)) +- Style Book: Allow button text labels for style book icon. ([48088](https://github.com/WordPress/gutenberg/pull/48088)) +- Style Book: Focus the Style Book when opened, and enable ESCAPE key to close. ([48151](https://github.com/WordPress/gutenberg/pull/48151)) +- Try to fix a11y test flakiness. ([48236](https://github.com/WordPress/gutenberg/pull/48236)) +- Make the template customized info accessible. ([48159](https://github.com/WordPress/gutenberg/pull/48159)) + + +### Performance + +#### Block Editor +- Block Editor: Improve empty `getBlockParents()` perf. ([48242](https://github.com/WordPress/gutenberg/pull/48242)) +- Fix perf regression in duotone hooks. ([48401](https://github.com/WordPress/gutenberg/pull/48401)) +- Writing flow: Avoid recalc style on every selection change. ([48409](https://github.com/WordPress/gutenberg/pull/48409)) +- useAsyncList: Flush state updates when processing queue. ([48238](https://github.com/WordPress/gutenberg/pull/48238)) + +#### Components +- Autocomplete: Reduce work before finding trigger. ([48327](https://github.com/WordPress/gutenberg/pull/48327)) +- Disable lazy term meta loading render_block_core_template_part. ([48000](https://github.com/WordPress/gutenberg/pull/48000)) +- Rich text: Only selectively handle keyup/pointerup. ([48385](https://github.com/WordPress/gutenberg/pull/48385)) +- Rich text: Remove unnecessary handleSelectionChange call. ([48373](https://github.com/WordPress/gutenberg/pull/48373)) +- Rich text: Try removing store change on focus. ([48342](https://github.com/WordPress/gutenberg/pull/48342)) +- Autocomplete: Avoid calling setState on input. ([48565](https://github.com/WordPress/gutenberg/pull/48565)) +- Autocomplete: Don't change state on every keystroke. ([48485](https://github.com/WordPress/gutenberg/pull/48485)) + +### Code Quality +- Tag Processor: Make `$html` field `protected`. ([48681](https://github.com/WordPress/gutenberg/pull/48681)) +- WP_HTML_Tag_Processor: Support tag closer bookmarks. ([48692](https://github.com/WordPress/gutenberg/pull/48692)) +- Fixed incorrect type annotations in @wordpress/data, part 2. ([48221](https://github.com/WordPress/gutenberg/pull/48221)) +- Lodash: Refactor away from `_.merge()`. ([48239](https://github.com/WordPress/gutenberg/pull/48239)) +- Lodash: Remove from integration tests. ([48122](https://github.com/WordPress/gutenberg/pull/48122)) +- Lodash: Remove remaining `_.get()` from `core-data`. ([48310](https://github.com/WordPress/gutenberg/pull/48310)) +- Lodash: Remove `_.get()` for post type usages. ([48121](https://github.com/WordPress/gutenberg/pull/48121)) +- Lodash: Remove remaining `_.get()` from `editor`. ([48314](https://github.com/WordPress/gutenberg/pull/48314)) +- Lodash: Remove some `_.get()` from editor. ([48104](https://github.com/WordPress/gutenberg/pull/48104)) +- Lodash: Refactor context system provider away from `_.merge()`. ([48036](https://github.com/WordPress/gutenberg/pull/48036)) +- Lodash: Remove `_.merge()` from `getMappedColumnWidths()`. ([48032](https://github.com/WordPress/gutenberg/pull/48032)) +- Lodash: Remove some `_.get()` from Gallery block. ([48488](https://github.com/WordPress/gutenberg/pull/48488)) +- Lodash: Remove some `_.get()` from Image block. ([48489](https://github.com/WordPress/gutenberg/pull/48489)) +- Playwright: Fix request utils for non Docker envs. ([48206](https://github.com/WordPress/gutenberg/pull/48206)) +- [Private APIs] Only prevent module re-registration if IS_WORDPRESS_CORE. ([48352](https://github.com/WordPress/gutenberg/pull/48352)) +- Add a manual performance job that we can trigger from Github UI. ([48302](https://github.com/WordPress/gutenberg/pull/48302)) +- Track new front-end metric: LCP-TTFB. ([48288](https://github.com/WordPress/gutenberg/pull/48288)) + +### Documentation +- Clarify backport status of `appearance-tools` theme support. ([48622](https://github.com/WordPress/gutenberg/pull/48622)) +- Docs: Clarify release process for major WP Beta 1. ([48248](https://github.com/WordPress/gutenberg/pull/48248)) +- Docs: Markdown fix for wp_enqueue_script usage. ([48212](https://github.com/WordPress/gutenberg/pull/48212)) +- Fix `e2e-test-utils-playwright`'s jsdoc and types. ([48266](https://github.com/WordPress/gutenberg/pull/48266)) +- Fix incorrect css property in editor-color-palette documentation. ([48333](https://github.com/WordPress/gutenberg/pull/48333)) +- Proactively update versions in WordPress ahead of 6.2. ([48145](https://github.com/WordPress/gutenberg/pull/48145)) +- Update curation document to include theme.json filters. ([48576](https://github.com/WordPress/gutenberg/pull/48576)) +- Updates to the curating the editor experience to include 6.1 & 6.2 items. ([48294](https://github.com/WordPress/gutenberg/pull/48294)) + +### Tools +#### Testing +- Migrate `switch-to-draft` to Playwright. ([48120](https://github.com/WordPress/gutenberg/pull/48120)) +- VizReg end-to-end tests: Programmatically test all combinations of a given list of props/values. ([48260](https://github.com/WordPress/gutenberg/pull/48260)) +- Update end-to-end test snapshots to Jest 29 default. ([48626](https://github.com/WordPress/gutenberg/pull/48626)) +- Update snapshot format to Jest 29 default. ([48366](https://github.com/WordPress/gutenberg/pull/48366)) +- Move react-native-editor parser tests to a test directory. ([48615](https://github.com/WordPress/gutenberg/pull/48615)) +- `ToolsPanel`: Refactor unit tests to TypeScript. ([48275](https://github.com/WordPress/gutenberg/pull/48275)) +- Migrate block deletion end-to-end tests to Playwright. ([48012](https://github.com/WordPress/gutenberg/pull/48012)) +- Migrate list view end-to-end tests to Playwright. ([47919](https://github.com/WordPress/gutenberg/pull/47919)) +- Navigation block: End-to-end code quality fixes. ([48071](https://github.com/WordPress/gutenberg/pull/48071)) +- Remove old end-to-end tests for the navigation block. ([48126](https://github.com/WordPress/gutenberg/pull/48126)) +- Update assertion Autocomplete end-to-end tests. ([48344](https://github.com/WordPress/gutenberg/pull/48344)) +- [Automated Testing]: Fix wrong button fixture. ([48305](https://github.com/WordPress/gutenberg/pull/48305)) +- Add typescript-eslint rules with type informations to end-to-end tests. ([48267](https://github.com/WordPress/gutenberg/pull/48267)) +- Fix snapshots for Spacer mobile unit tests. ([48406](https://github.com/WordPress/gutenberg/pull/48406)) +- Add command to run performance tests in debug mode. ([48614](https://github.com/WordPress/gutenberg/pull/48614)) +- Make the performance tests more stable. ([48094](https://github.com/WordPress/gutenberg/pull/48094)) + +## First time contributors + +The following PRs were merged by first time contributors: + +- @abhi3315: Link Control - Add support for text only labels. ([47930](https://github.com/WordPress/gutenberg/pull/47930)) +- @hbhalodia: Update: Change higher order `with-constraint-tabbing` from `.js` to `.tsx`. ([48162](https://github.com/WordPress/gutenberg/pull/48162)) +- @sboerrigter: Fix incorrect css property in editor-color-palette documentation. ([48333](https://github.com/WordPress/gutenberg/pull/48333)) +- @shreyasikhar: Site Editor Sidebar: Add line-height for template/parts name and update width for edit button. ([48160](https://github.com/WordPress/gutenberg/pull/48160)) +- @suvrodattamitu: Style Engine: Fix wrong property name letterSpacing to lineHeight. ([48091](https://github.com/WordPress/gutenberg/pull/48091)) +- @tomdevisser: Remove copy for managing a block's style variations. ([48367](https://github.com/WordPress/gutenberg/pull/48367)) + + + +## Contributors + +The following contributors merged PRs in this release: + +@aaronrobertshaw @abhi3315 @adamziel @afercia @alexstine @andrewserong @annezazu @brookewp @carolinan @chad1008 @ciampo @dcalhoun @draganescu @ellatrix @fluiddot @geriux @getdave @gvgvgvijayan @gziolo @hbhalodia @jorgefilipecosta @jsnajdr @kevin940726 @MaggieCabrera @Mamaduka @marekdedic @ndiego @ntsekouras @oandregal @ockham @richtabor @sboerrigter @scruffian @shreyasikhar @spacedmonkey @suvrodattamitu @t-hamano @tellthemachines @tomdevisser @tyxla @WunderBart @youknowriad + + += 15.3.0 = ## Changelog -### Code Quality +### Enhancements -- Tag Processor: Make `$html` field `protected`. ([48681](https://github.com/WordPress/gutenberg/pull/48681)) +#### Site Editor +- Refactor the site editor URLs for better backward compatibility. ([48063](https://github.com/WordPress/gutenberg/pull/48063)) +- Remove TemplateAreas from template details. ([48490](https://github.com/WordPress/gutenberg/pull/48490)) +- Update the edit button. ([48584](https://github.com/WordPress/gutenberg/pull/48584)) +- Change "Browse all templates" to "Manage all templates" in template details popover. ([48496](https://github.com/WordPress/gutenberg/pull/48496)) +- Match color of the focus template view with site dark material. ([48430](https://github.com/WordPress/gutenberg/pull/48430)) +- Polish add template modal style. ([48445](https://github.com/WordPress/gutenberg/pull/48445)) +- Site Editor Sidebar: Add line-height for template/parts name and update width for edit button. ([48160](https://github.com/WordPress/gutenberg/pull/48160)) +- Extract a DimensionsPanel component as a reusable component between Global Styles and Block Inspector. ([48070](https://github.com/WordPress/gutenberg/pull/48070)) +- Remove copy for managing a block's style variations. ([48367](https://github.com/WordPress/gutenberg/pull/48367)) +#### Block Editor +- Apply keyboard shortcut conversions between paragraphs and headings to all editor instances. ([47972](https://github.com/WordPress/gutenberg/pull/47972)) +- Create automatic change higher order reducer. ([48312](https://github.com/WordPress/gutenberg/pull/48312)) +- [Inserter]: Preload media categories empty check - client side. ([47503](https://github.com/WordPress/gutenberg/pull/47503)) -### Various +#### Post Editor +- Revert iframed editor for WP core only. ([48076](https://github.com/WordPress/gutenberg/pull/48076)) +- PageAttributesCheck: Return boolean value directly from the selector. ([48336](https://github.com/WordPress/gutenberg/pull/48336)) +- Apply busy status to the publish button in progress and unify button width. ([48444](https://github.com/WordPress/gutenberg/pull/48444)) + +#### Block Library +- Add all allowed innerblocks to the inspector animation experiment. ([47834](https://github.com/WordPress/gutenberg/pull/47834)) +- Make the Site Logo block placeholder state smaller. ([48218](https://github.com/WordPress/gutenberg/pull/48218)) +- ToggleControl: Remove margin overrides and add opt-in prop. ([47866](https://github.com/WordPress/gutenberg/pull/47866)) +- Post Terms block: Add transforms for variations. ([48328](https://github.com/WordPress/gutenberg/pull/48328)) +- List block: Add Firefox end-to-end tests. ([48271](https://github.com/WordPress/gutenberg/pull/48271)) +- Navigation List View: Add block movers to the more menu. ([48099](https://github.com/WordPress/gutenberg/pull/48099)) +- Navigation: Always create a fallback menu. ([47684](https://github.com/WordPress/gutenberg/pull/47684)) +- Navigation: Don't create a fallback navigation menu if there are inner blocks. ([48585](https://github.com/WordPress/gutenberg/pull/48585)) +- Navigation: Don't create duplicate navigation menus. ([48599](https://github.com/WordPress/gutenberg/pull/48599)) +- Navigation: Update the dependencies for the useEffect that handles notifications. ([48066](https://github.com/WordPress/gutenberg/pull/48066)) +- Navigation: Wrap the dependent functions in useCallback. ([48195](https://github.com/WordPress/gutenberg/pull/48195)) +- Page List: Move the modal to its own file. ([47922](https://github.com/WordPress/gutenberg/pull/47922)) +- [New Block] Add post time to read block. ([43403](https://github.com/WordPress/gutenberg/pull/43403)) +- Classic Block: Replace the deprecated `isPrimary` prop with `variant`. ([48230](https://github.com/WordPress/gutenberg/pull/48230)) +- Refactor core blocks to use HTML Tag Processor. ([43178](https://github.com/WordPress/gutenberg/pull/43178)) + +#### Block API +- HTML Tag Processor: Add WP 6.3 compat layer. ([47933](https://github.com/WordPress/gutenberg/pull/47933)) +- Tag Processor: Add bookmark invalidation logic. ([47559](https://github.com/WordPress/gutenberg/pull/47559)) + +#### Design Tools +- Duotone: Use the style engine to generate CSS for Duotone. ([48281](https://github.com/WordPress/gutenberg/pull/48281)) +- Duotone: Add Global Styles controls for blocks that support duotone. ([48255](https://github.com/WordPress/gutenberg/pull/48255)) +- Use Duotone presets in block duotone attributes. ([48318](https://github.com/WordPress/gutenberg/pull/48318)) +- Duotone: Use CSS variables instead of slugs in block attributes. ([48426](https://github.com/WordPress/gutenberg/pull/48426)) +- Border Panel: Add missing dep for `onBorderChange` callback. ([48010](https://github.com/WordPress/gutenberg/pull/48010)) +- Disable layout toolbar controls for content locked blocks. ([47939](https://github.com/WordPress/gutenberg/pull/47939)) +- SpacingSizesControl: Fix white dot on thumb. ([48574](https://github.com/WordPress/gutenberg/pull/48574)) + +#### List View +- Scroll selected block into view when single block selection changes. ([46895](https://github.com/WordPress/gutenberg/pull/46895)) + +#### Components +- TabPanel: Refactor unit tests in prep for controlled component updates. ([48086](https://github.com/WordPress/gutenberg/pull/48086)) +- Change higher order `with-constraint-tabbing` from `.js` to `.tsx`. ([48162](https://github.com/WordPress/gutenberg/pull/48162)) +- CircularOptionPicker: Refactor to TypeScript. ([47937](https://github.com/WordPress/gutenberg/pull/47937)) +- Extract delete handler to hook for RichText. ([48273](https://github.com/WordPress/gutenberg/pull/48273)) +- ToolsPanel: Remove unnecessary dep from resetAll callback. ([48011](https://github.com/WordPress/gutenberg/pull/48011)) +- Link Control - Add support for text only labels. ([47930](https://github.com/WordPress/gutenberg/pull/47930)) +- Pin `floating-ui/react-dom` version. ([48402](https://github.com/WordPress/gutenberg/pull/48402)) +- Use React 18 rendering for import dropdown. ([48244](https://github.com/WordPress/gutenberg/pull/48244)) +### Bug Fixes + +#### Site Editor +- Fix Site Editor perf tests. ([48240](https://github.com/WordPress/gutenberg/pull/48240)) +- Fix routing for Classic themes using block-based template parts. ([48343](https://github.com/WordPress/gutenberg/pull/48343)) +- Fix the 'Browse all' link in the template details modal. ([48301](https://github.com/WordPress/gutenberg/pull/48301)) +- Fix the site editor home page loading when installed in a subdirectory. ([48363](https://github.com/WordPress/gutenberg/pull/48363)) +- Fix the tooltip and shortcut for the global save button. ([48282](https://github.com/WordPress/gutenberg/pull/48282)) +- Prevent distracting focused back button on site editor load. ([48472](https://github.com/WordPress/gutenberg/pull/48472)) +- Sort templates and template parts by slug. ([48473](https://github.com/WordPress/gutenberg/pull/48473)) +- Specify focus state color for template navigation button. ([48134](https://github.com/WordPress/gutenberg/pull/48134)) +- [Site Editor]: Set `html` block as freeform fallback block. ([48129](https://github.com/WordPress/gutenberg/pull/48129)) +- Remove broken site editor redirect. ([48283](https://github.com/WordPress/gutenberg/pull/48283)) +- Fix: Inserter does not appear on sidebar navigation. ([48623](https://github.com/WordPress/gutenberg/pull/48623)) +- Fix: Make navigation page list load its items on navigation sidebar. ([47853](https://github.com/WordPress/gutenberg/pull/47853)) +- Revert Site Tagline placeholder attribute, move example to block.json. ([48383](https://github.com/WordPress/gutenberg/pull/48383)) + +#### Block Editor +- MediaReplaceFlow: Fix styling for LinkControl. ([47949](https://github.com/WordPress/gutenberg/pull/47949)) +- Fix "Reset All" button in the typography panel of the block inspector. ([48123](https://github.com/WordPress/gutenberg/pull/48123)) +- [Inserter - Media tab]: Upload Openverse images when inserted. ([48501](https://github.com/WordPress/gutenberg/pull/48501)) +- Block alignment controls: Don't remount the block when alignments change. ([48209](https://github.com/WordPress/gutenberg/pull/48209)) +- Pin `valtio` version. ([48237](https://github.com/WordPress/gutenberg/pull/48237)) +- Fix block style preview flickering when a 'style' is focused. ([48418](https://github.com/WordPress/gutenberg/pull/48418)) +- Enable access to block settings within UBE. ([48435](https://github.com/WordPress/gutenberg/pull/48435)) +- Fix: Content only CPT template locking. ([48434](https://github.com/WordPress/gutenberg/pull/48434)) +- Firefox: Fix input rules (React async state issue). ([48210](https://github.com/WordPress/gutenberg/pull/48210)) +- Fix: Multiple overwrites on rest_controller_class for wp_template/wp_template_part. ([48078](https://github.com/WordPress/gutenberg/pull/48078)) +- Select blocks in `outline` list. ([48118](https://github.com/WordPress/gutenberg/pull/48118)) +- Only add layout classes to inner wrapper if block is a container. ([48611](https://github.com/WordPress/gutenberg/pull/48611)) + +#### Widgets Editor +- Widget Editor: Fix a problem with 'Move to Widget Area' button not working. ([48233](https://github.com/WordPress/gutenberg/pull/48233)) + +#### Block Library +- Add support for orientation-based block movers to core/social-links. ([48452](https://github.com/WordPress/gutenberg/pull/48452)) +- Fix Post Excerpt: Read more link is always on new line in the editor. ([47772](https://github.com/WordPress/gutenberg/pull/47772)) +- Fix: OffCanvasEditor does not inserts submenu on collapsed items. ([48214](https://github.com/WordPress/gutenberg/pull/48214)) +- List Item: Avoid an error when the 'onReplace' prop is undefined. ([48639](https://github.com/WordPress/gutenberg/pull/48639)) +- Add missing code on the fix page list loading PR. ([48621](https://github.com/WordPress/gutenberg/pull/48621)) +- Prevent text decoration from showing up in all blocks. ([48117](https://github.com/WordPress/gutenberg/pull/48117)) +- Widget Importer: Don't render controls when there's nothing to import. ([48396](https://github.com/WordPress/gutenberg/pull/48396)) +- [Query Loop] Fix top border in pattern selection modal. ([48303](https://github.com/WordPress/gutenberg/pull/48303)) +- [Query Loop] Sync `gutenberg_build_query_vars_from_query_block` with core. ([48640](https://github.com/WordPress/gutenberg/pull/48640)) +- Avatar: Clean up border application in editor. ([48024](https://github.com/WordPress/gutenberg/pull/48024)) + +#### Global Styles +- Fix for `WP_Theme_JSON_Resolver_Gutenberg::Get_merged_data`. ([48644](https://github.com/WordPress/gutenberg/pull/48644)) +- Display preset names via the tooltip. ([48304](https://github.com/WordPress/gutenberg/pull/48304)) +- Fix typo in valid settings for fluid typography. ([48605](https://github.com/WordPress/gutenberg/pull/48605)) +- Prevent the global styles previews thumbnails from resizing on load. ([48474](https://github.com/WordPress/gutenberg/pull/48474)) +- Site Tagline: Add example so that it will display in style book. ([48300](https://github.com/WordPress/gutenberg/pull/48300)) +- Fix wrong property name letterSpacing to lineHeight. ([48091](https://github.com/WordPress/gutenberg/pull/48091)) +- Update code position for constants and methods in `WP_Theme_JSON_Gutenberg` class. ([48631](https://github.com/WordPress/gutenberg/pull/48631)) +- `WP_Theme_JSON_Gutenberg`: Update comments to be aligned with core, so backports are easier. ([48624](https://github.com/WordPress/gutenberg/pull/48624)) + +### Accessibility +- Autocomplete: Duplicate list within iframe for non visual users. ([47907](https://github.com/WordPress/gutenberg/pull/47907)) +- Fix site editor switch mode message. ([48136](https://github.com/WordPress/gutenberg/pull/48136)) +- Fix the Publish region position and focus style. ([48102](https://github.com/WordPress/gutenberg/pull/48102)) +- Focus 1st parent block on block remove, if no previous block is available. ([48204](https://github.com/WordPress/gutenberg/pull/48204)) +- List view: Allow selected block to override roving tabindex. ([48339](https://github.com/WordPress/gutenberg/pull/48339)) +- Style Book: Allow button text labels for style book icon. ([48088](https://github.com/WordPress/gutenberg/pull/48088)) +- Style Book: Focus the Style Book when opened, and enable ESCAPE key to close. ([48151](https://github.com/WordPress/gutenberg/pull/48151)) +- Try to fix a11y test flakiness. ([48236](https://github.com/WordPress/gutenberg/pull/48236)) +- Make the template customized info accessible. ([48159](https://github.com/WordPress/gutenberg/pull/48159)) + + +### Performance + +#### Block Editor +- Block Editor: Improve empty `getBlockParents()` perf. ([48242](https://github.com/WordPress/gutenberg/pull/48242)) +- Fix perf regression in duotone hooks. ([48401](https://github.com/WordPress/gutenberg/pull/48401)) +- Writing flow: Avoid recalc style on every selection change. ([48409](https://github.com/WordPress/gutenberg/pull/48409)) +- useAsyncList: Flush state updates when processing queue. ([48238](https://github.com/WordPress/gutenberg/pull/48238)) + +#### Components +- Autocomplete: Reduce work before finding trigger. ([48327](https://github.com/WordPress/gutenberg/pull/48327)) +- Disable lazy term meta loading render_block_core_template_part. ([48000](https://github.com/WordPress/gutenberg/pull/48000)) +- Rich text: Only selectively handle keyup/pointerup. ([48385](https://github.com/WordPress/gutenberg/pull/48385)) +- Rich text: Remove unnecessary handleSelectionChange call. ([48373](https://github.com/WordPress/gutenberg/pull/48373)) +- Rich text: Try removing store change on focus. ([48342](https://github.com/WordPress/gutenberg/pull/48342)) +- Autocomplete: Avoid calling setState on input. ([48565](https://github.com/WordPress/gutenberg/pull/48565)) +- Autocomplete: Don't change state on every keystroke. ([48485](https://github.com/WordPress/gutenberg/pull/48485)) + +### Code Quality +- Tag Processor: Make `$html` field `protected`. ([48681](https://github.com/WordPress/gutenberg/pull/48681)) - WP_HTML_Tag_Processor: Support tag closer bookmarks. ([48692](https://github.com/WordPress/gutenberg/pull/48692)) +- Fixed incorrect type annotations in @wordpress/data, part 2. ([48221](https://github.com/WordPress/gutenberg/pull/48221)) +- Lodash: Refactor away from `_.merge()`. ([48239](https://github.com/WordPress/gutenberg/pull/48239)) +- Lodash: Remove from integration tests. ([48122](https://github.com/WordPress/gutenberg/pull/48122)) +- Lodash: Remove remaining `_.get()` from `core-data`. ([48310](https://github.com/WordPress/gutenberg/pull/48310)) +- Lodash: Remove `_.get()` for post type usages. ([48121](https://github.com/WordPress/gutenberg/pull/48121)) +- Lodash: Remove remaining `_.get()` from `editor`. ([48314](https://github.com/WordPress/gutenberg/pull/48314)) +- Lodash: Remove some `_.get()` from editor. ([48104](https://github.com/WordPress/gutenberg/pull/48104)) +- Lodash: Refactor context system provider away from `_.merge()`. ([48036](https://github.com/WordPress/gutenberg/pull/48036)) +- Lodash: Remove `_.merge()` from `getMappedColumnWidths()`. ([48032](https://github.com/WordPress/gutenberg/pull/48032)) +- Lodash: Remove some `_.get()` from Gallery block. ([48488](https://github.com/WordPress/gutenberg/pull/48488)) +- Lodash: Remove some `_.get()` from Image block. ([48489](https://github.com/WordPress/gutenberg/pull/48489)) +- Playwright: Fix request utils for non Docker envs. ([48206](https://github.com/WordPress/gutenberg/pull/48206)) +- [Private APIs] Only prevent module re-registration if IS_WORDPRESS_CORE. ([48352](https://github.com/WordPress/gutenberg/pull/48352)) +- Add a manual performance job that we can trigger from Github UI. ([48302](https://github.com/WordPress/gutenberg/pull/48302)) +- Track new front-end metric: LCP-TTFB. ([48288](https://github.com/WordPress/gutenberg/pull/48288)) + +### Documentation +- Clarify backport status of `appearance-tools` theme support. ([48622](https://github.com/WordPress/gutenberg/pull/48622)) +- Docs: Clarify release process for major WP Beta 1. ([48248](https://github.com/WordPress/gutenberg/pull/48248)) +- Docs: Markdown fix for wp_enqueue_script usage. ([48212](https://github.com/WordPress/gutenberg/pull/48212)) +- Fix `e2e-test-utils-playwright`'s jsdoc and types. ([48266](https://github.com/WordPress/gutenberg/pull/48266)) +- Fix incorrect css property in editor-color-palette documentation. ([48333](https://github.com/WordPress/gutenberg/pull/48333)) +- Proactively update versions in WordPress ahead of 6.2. ([48145](https://github.com/WordPress/gutenberg/pull/48145)) +- Update curation document to include theme.json filters. ([48576](https://github.com/WordPress/gutenberg/pull/48576)) +- Updates to the curating the editor experience to include 6.1 & 6.2 items. ([48294](https://github.com/WordPress/gutenberg/pull/48294)) +### Tools +#### Testing +- Migrate `switch-to-draft` to Playwright. ([48120](https://github.com/WordPress/gutenberg/pull/48120)) +- VizReg end-to-end tests: Programmatically test all combinations of a given list of props/values. ([48260](https://github.com/WordPress/gutenberg/pull/48260)) +- Update end-to-end test snapshots to Jest 29 default. ([48626](https://github.com/WordPress/gutenberg/pull/48626)) +- Update snapshot format to Jest 29 default. ([48366](https://github.com/WordPress/gutenberg/pull/48366)) +- Move react-native-editor parser tests to a test directory. ([48615](https://github.com/WordPress/gutenberg/pull/48615)) +- `ToolsPanel`: Refactor unit tests to TypeScript. ([48275](https://github.com/WordPress/gutenberg/pull/48275)) +- Migrate block deletion end-to-end tests to Playwright. ([48012](https://github.com/WordPress/gutenberg/pull/48012)) +- Migrate list view end-to-end tests to Playwright. ([47919](https://github.com/WordPress/gutenberg/pull/47919)) +- Navigation block: End-to-end code quality fixes. ([48071](https://github.com/WordPress/gutenberg/pull/48071)) +- Remove old end-to-end tests for the navigation block. ([48126](https://github.com/WordPress/gutenberg/pull/48126)) +- Update assertion Autocomplete end-to-end tests. ([48344](https://github.com/WordPress/gutenberg/pull/48344)) +- [Automated Testing]: Fix wrong button fixture. ([48305](https://github.com/WordPress/gutenberg/pull/48305)) +- Add typescript-eslint rules with type informations to end-to-end tests. ([48267](https://github.com/WordPress/gutenberg/pull/48267)) +- Fix snapshots for Spacer mobile unit tests. ([48406](https://github.com/WordPress/gutenberg/pull/48406)) +- Add command to run performance tests in debug mode. ([48614](https://github.com/WordPress/gutenberg/pull/48614)) +- Make the performance tests more stable. ([48094](https://github.com/WordPress/gutenberg/pull/48094)) ## First time contributors The following PRs were merged by first time contributors: +- @abhi3315: Link Control - Add support for text only labels. ([47930](https://github.com/WordPress/gutenberg/pull/47930)) +- @hbhalodia: Update: Change higher order `with-constraint-tabbing` from `.js` to `.tsx`. ([48162](https://github.com/WordPress/gutenberg/pull/48162)) +- @sboerrigter: Fix incorrect css property in editor-color-palette documentation. ([48333](https://github.com/WordPress/gutenberg/pull/48333)) +- @shreyasikhar: Site Editor Sidebar: Add line-height for template/parts name and update width for edit button. ([48160](https://github.com/WordPress/gutenberg/pull/48160)) +- @suvrodattamitu: Style Engine: Fix wrong property name letterSpacing to lineHeight. ([48091](https://github.com/WordPress/gutenberg/pull/48091)) +- @tomdevisser: Remove copy for managing a block's style variations. ([48367](https://github.com/WordPress/gutenberg/pull/48367)) + ## Contributors The following contributors merged PRs in this release: -@ockham +@aaronrobertshaw @abhi3315 @adamziel @afercia @alexstine @andrewserong @annezazu @brookewp @carolinan @chad1008 @ciampo @dcalhoun @draganescu @ellatrix @fluiddot @geriux @getdave @gvgvgvijayan @gziolo @hbhalodia @jorgefilipecosta @jsnajdr @kevin940726 @MaggieCabrera @Mamaduka @marekdedic @ndiego @ntsekouras @oandregal @ockham @richtabor @sboerrigter @scruffian @shreyasikhar @spacedmonkey @suvrodattamitu @t-hamano @tellthemachines @tomdevisser @tyxla @WunderBart @youknowriad = 15.2.4 = @@ -4735,7 +5477,7 @@ The following contributors merged PRs in this release: - Docs: Fix required status of `onSelectUrl` prop of `MediaReplaceFlow` component. ([44025](https://github.com/WordPress/gutenberg/pull/44025)) - Document new global styles filters. ([44111](https://github.com/WordPress/gutenberg/pull/44111)) - Document template_lock=noContent for Custom Post Types. ([43977](https://github.com/WordPress/gutenberg/pull/43977)) -- InnerBlocks: document that `templateLock:NoContent` cannot be overriden by children. ([43825](https://github.com/WordPress/gutenberg/pull/43825)) +- InnerBlocks: document that `templateLock:NoContent` cannot be overridden by children. ([43825](https://github.com/WordPress/gutenberg/pull/43825)) - Theme.json: Add default values for settings.spacing.spacingScale. ([43860](https://github.com/WordPress/gutenberg/pull/43860)) - Theme.json: Fix schema for useRootPaddingAwareAlignments. ([43628](https://github.com/WordPress/gutenberg/pull/43628)) - Typography block supports: Call tear_down in tests and format PHP doc blocks. ([43968](https://github.com/WordPress/gutenberg/pull/43968)) diff --git a/docs/contributors/code/e2e/README.md b/docs/contributors/code/e2e/README.md index 8ad4abdfe4d384..e5c4cbb534102c 100644 --- a/docs/contributors/code/e2e/README.md +++ b/docs/contributors/code/e2e/README.md @@ -2,8 +2,11 @@ This living document serves to prescribe instructions and best practices for writing end-to-end (E2E) tests with Playwright in the Gutenberg project. -> **Note** -> See the dedicated guide if you're working with the previous Jest + Puppeteer framework. See the [migration guide](https://github.com/WordPress/gutenberg/tree/HEAD/docs/contributors/code/e2e/migration.md) if you're migrating tests from Jest + Puppeteer. +
Built with modern technology.
+ + + +Gutenberg was developed on GitHub using the WordPress REST API, JavaScript, and React.
+ + + + +Designed for compatibility.
+ + + +We recommend migrating features to blocks, but support for existing WordPress functionality remains. There will be transition paths for shortcodes, meta-boxes, and Custom Post Types.
+ + + + +Built with modern technology.
+ + + +Gutenberg was developed on GitHub using the WordPress REST API, JavaScript, and React.
+ + + + + + + +Designed for compatibility.
+ + + +We recommend migrating features to blocks, but support for existing WordPress functionality remains. There will be transition paths for shortcodes, meta-boxes, and Custom Post Types.
+ + + + +" +`; diff --git a/packages/block-library/src/columns/test/transforms.native.js b/packages/block-library/src/columns/test/transforms.native.js new file mode 100644 index 00000000000000..12ae9d9c0829f2 --- /dev/null +++ b/packages/block-library/src/columns/test/transforms.native.js @@ -0,0 +1,91 @@ +/** + * External dependencies + */ +import { + getEditorHtml, + initializeEditor, + setupCoreBlocks, + transformBlock, + getBlock, + openBlockActionsMenu, + fireEvent, + getBlockTransformOptions, +} from 'test/helpers'; + +const block = 'Columns'; +const initialHtml = ` + +Built with modern technology.
+ + + +Gutenberg was developed on GitHub using the WordPress REST API, JavaScript, and React.
+ + + + +Designed for compatibility.
+ + + +We recommend migrating features to blocks, but support for existing WordPress functionality remains. There will be transition paths for shortcodes, meta-boxes, and Custom Post Types.
+ + + + +
Mountain
+
Mountain
+
Mountain
+
Cloudup
+Cloudup
+Cloudup
+
Mountain
+Cloudup
+{ __( 'Select or create a menu' ) }
; - } - if ( currentMenuId && isNavigationMenuMissing ) { returnExample text
+Example text
+Example text+" +`; + +exports[`Paragraph block transforms to Pullquote block 1`] = ` +" +
Example text
++" +`; + +exports[`Paragraph block transforms to Verse block 1`] = ` +" +Example text
+
Example text+" +`; diff --git a/packages/block-library/src/paragraph/test/transforms.native.js b/packages/block-library/src/paragraph/test/transforms.native.js new file mode 100644 index 00000000000000..0f34038ca298c7 --- /dev/null +++ b/packages/block-library/src/paragraph/test/transforms.native.js @@ -0,0 +1,50 @@ +/** + * External dependencies + */ +import { + getEditorHtml, + initializeEditor, + setupCoreBlocks, + transformBlock, + getBlockTransformOptions, +} from 'test/helpers'; + +const block = 'Paragraph'; +const initialHtml = ` + +
Example text
+`; + +// NOTE: Paragraph block can be transformed to Buttons block in web, +// however this transform is not supported in the native version. +const transformsWithInnerBlocks = [ 'List', 'Quote', 'Columns', 'Group' ]; +const blockTransforms = [ + 'Heading', + 'Preformatted', + 'Pullquote', + 'Verse', + ...transformsWithInnerBlocks, +]; + +setupCoreBlocks(); + +describe( `${ block } block transforms`, () => { + test.each( blockTransforms )( 'to %s block', async ( blockTransform ) => { + const screen = await initializeEditor( { initialHtml } ); + const newBlock = await transformBlock( screen, block, blockTransform, { + hasInnerBlocks: + transformsWithInnerBlocks.includes( blockTransform ), + } ); + expect( newBlock ).toBeVisible(); + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'matches expected transformation options', async () => { + const screen = await initializeEditor( { initialHtml } ); + const transformOptions = await getBlockTransformOptions( + screen, + block + ); + expect( transformOptions ).toHaveLength( blockTransforms.length ); + } ); +} ); diff --git a/packages/block-library/src/post-date/edit.js b/packages/block-library/src/post-date/edit.js index 6ce9144023e6e7..d6b8cb2b15ae57 100644 --- a/packages/block-library/src/post-date/edit.js +++ b/packages/block-library/src/post-date/edit.js @@ -76,12 +76,15 @@ export default function PostDateEdit( { [ postTypeSlug ] ); + const dateLabel = + displayType === 'date' ? __( 'Post Date' ) : __( 'Post Modified Date' ); + let postDate = date ? ( ) : ( - __( 'Post Date' ) + dateLabel ); if ( isLink && date ) { diff --git a/packages/block-library/src/post-date/index.js b/packages/block-library/src/post-date/index.js index fddae539acfa34..232b715c3795b6 100644 --- a/packages/block-library/src/post-date/index.js +++ b/packages/block-library/src/post-date/index.js @@ -10,6 +10,7 @@ import initBlock from '../utils/init-block'; import metadata from './block.json'; import edit from './edit'; import deprecated from './deprecated'; +import variations from './variations'; const { name } = metadata; export { metadata, name }; @@ -18,6 +19,7 @@ export const settings = { icon, edit, deprecated, + variations, }; export const init = () => initBlock( { name, metadata, settings } ); diff --git a/packages/block-library/src/post-date/variations.js b/packages/block-library/src/post-date/variations.js new file mode 100644 index 00000000000000..0b99b9d5136883 --- /dev/null +++ b/packages/block-library/src/post-date/variations.js @@ -0,0 +1,20 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { postDate } from '@wordpress/icons'; + +const variations = [ + { + name: 'post-date-modified', + title: __( 'Post Modified Date' ), + description: __( "Display a post's last updated date." ), + attributes: { displayType: 'modified' }, + scope: [ 'block', 'inserter' ], + isActive: ( blockAttributes ) => + blockAttributes.displayType === 'modified', + icon: postDate, + }, +]; + +export default variations; diff --git a/packages/block-library/src/post-excerpt/edit.js b/packages/block-library/src/post-excerpt/edit.js index 378aa34cd00baa..10e36e267504d6 100644 --- a/packages/block-library/src/post-excerpt/edit.js +++ b/packages/block-library/src/post-excerpt/edit.js @@ -156,7 +156,10 @@ export default function PostExcerptEditor( { .split( '', excerptLength + numberOfSpaces ) .join( '' ); } else if ( wordCountType === 'characters_including_spaces' ) { - trimmedExcerpt = rawOrRenderedExcerpt.trim().split( '', excerptLength ); + trimmedExcerpt = rawOrRenderedExcerpt + .trim() + .split( '', excerptLength ) + .join( '' ); } trimmedExcerpt = trimmedExcerpt + '...'; diff --git a/packages/block-library/src/post-featured-image/dimension-controls.js b/packages/block-library/src/post-featured-image/dimension-controls.js index da66e7f4bda52d..f10872c178b5cc 100644 --- a/packages/block-library/src/post-featured-image/dimension-controls.js +++ b/packages/block-library/src/post-featured-image/dimension-controls.js @@ -96,10 +96,6 @@ const DimensionControls = ( { label: __( 'Square' ), value: '1', }, - { - label: __( '16:10' ), - value: '16/10', - }, { label: __( '16:9' ), value: '16/9', @@ -112,10 +108,6 @@ const DimensionControls = ( { label: __( '3:2' ), value: '3/2', }, - { - label: __( '10:16' ), - value: '10/16', - }, { label: __( '9:16' ), value: '9/16', diff --git a/packages/block-library/src/post-featured-image/edit.js b/packages/block-library/src/post-featured-image/edit.js index 950dbd57667b3d..cc0b2cfc6cd0cb 100644 --- a/packages/block-library/src/post-featured-image/edit.js +++ b/packages/block-library/src/post-featured-image/edit.js @@ -139,7 +139,7 @@ export default function PostFeaturedImageEdit( { imageSizeOptions={ imageSizeOptions } />Some preformatted text...
And more!
+"
+`;
+
+exports[`Preformatted block transforms to Columns block 1`] = `
+"
+Some preformatted text...+
And more!
Some preformatted text...+
And more!
Some preformatted text...
And more!
Some preformatted text...+`; + +const transformsWithInnerBlocks = [ 'Columns', 'Group' ]; +const blockTransforms = [ 'Paragraph', 'Code', ...transformsWithInnerBlocks ]; + +setupCoreBlocks(); + +describe( `${ block } block transforms`, () => { + test.each( blockTransforms )( 'to %s block', async ( blockTransform ) => { + const screen = await initializeEditor( { initialHtml } ); + const newBlock = await transformBlock( screen, block, blockTransform, { + hasInnerBlocks: + transformsWithInnerBlocks.includes( blockTransform ), + } ); + expect( newBlock ).toBeVisible(); + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'matches expected transformation options', async () => { + const screen = await initializeEditor( { initialHtml } ); + const transformOptions = await getBlockTransformOptions( + screen, + block + ); + expect( transformOptions ).toHaveLength( blockTransforms.length ); + } ); +} ); diff --git a/packages/block-library/src/pullquote/deprecated.js b/packages/block-library/src/pullquote/deprecated.js index 1f3ac876e4d45c..46ac8d2f13708b 100644 --- a/packages/block-library/src/pullquote/deprecated.js +++ b/packages/block-library/src/pullquote/deprecated.js @@ -2,7 +2,6 @@ * External dependencies */ import classnames from 'classnames'; -import { get } from 'lodash'; /** * WordPress dependencies @@ -435,11 +434,8 @@ const v2 = { // Is normal style and a named color is being used, we need to retrieve the color value to set the style, // as there is no expectation that themes create classes that set border colors. } else if ( mainColor ) { - const colors = get( - select( blockEditorStore ).getSettings(), - [ 'colors' ], - [] - ); + const colors = + select( blockEditorStore ).getSettings().colors ?? []; const colorObject = getColorObjectByAttributeValues( colors, mainColor diff --git a/packages/block-library/src/pullquote/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/pullquote/test/__snapshots__/transforms.native.js.snap new file mode 100644 index 00000000000000..6840d561dda0cc --- /dev/null +++ b/packages/block-library/src/pullquote/test/__snapshots__/transforms.native.js.snap @@ -0,0 +1,47 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Pullquote block transforms to Columns block 1`] = ` +" +
And more!
One of the hardest things to do in technology is disrupt yourself.
Matt Mullenweg
One of the hardest things to do in technology is disrupt yourself.
Matt Mullenweg
One of the hardest things to do in technology is disrupt yourself.
+ + + +Matt Mullenweg
+" +`; + +exports[`Pullquote block transforms to Quote block 1`] = ` +" +++" +`; diff --git a/packages/block-library/src/pullquote/test/transforms.native.js b/packages/block-library/src/pullquote/test/transforms.native.js new file mode 100644 index 00000000000000..c0360f82b6e87a --- /dev/null +++ b/packages/block-library/src/pullquote/test/transforms.native.js @@ -0,0 +1,46 @@ +/** + * External dependencies + */ +import { + getEditorHtml, + initializeEditor, + setupCoreBlocks, + transformBlock, + getBlockTransformOptions, +} from 'test/helpers'; + +const block = 'Pullquote'; +const initialHtml = ` + +One of the hardest things to do in technology is disrupt yourself.
+Matt Mullenweg
One of the hardest things to do in technology is disrupt yourself.
Matt Mullenweg
++"This will make running your own blog a viable alternative again."
+— Adrian Zumbrunnen
++"This will make running your own blog a viable alternative again."
+— Adrian Zumbrunnen
"This will make running your own blog a viable alternative again."
— Adrian Zumbrunnen
"This will make running your own blog a viable alternative again."
+ + + + +" +`; diff --git a/packages/block-library/src/quote/test/transforms.native.js b/packages/block-library/src/quote/test/transforms.native.js new file mode 100644 index 00000000000000..75cb887a4872be --- /dev/null +++ b/packages/block-library/src/quote/test/transforms.native.js @@ -0,0 +1,67 @@ +/** + * External dependencies + */ +import { + getEditorHtml, + initializeEditor, + setupCoreBlocks, + transformBlock, + getBlock, + openBlockActionsMenu, + fireEvent, + getBlockTransformOptions, +} from 'test/helpers'; + +const block = 'Quote'; +const initialHtml = ` + +++`; + +const transformsWithInnerBlocks = [ 'Columns', 'Group' ]; +const blockTransforms = [ 'Pullquote', ...transformsWithInnerBlocks ]; + +setupCoreBlocks(); + +describe( `${ block } block transforms`, () => { + test.each( blockTransforms )( 'to %s block', async ( blockTransform ) => { + const screen = await initializeEditor( { initialHtml } ); + const newBlock = await transformBlock( screen, block, blockTransform, { + hasInnerBlocks: + transformsWithInnerBlocks.includes( blockTransform ), + } ); + expect( newBlock ).toBeVisible(); + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'unwraps content', async () => { + const screen = await initializeEditor( { initialHtml } ); + const { getByText } = screen; + fireEvent.press( getBlock( screen, block ) ); + + await openBlockActionsMenu( screen ); + fireEvent.press( getByText( 'Transform block…' ) ); + fireEvent.press( getByText( 'Unwrap' ) ); + + // The first block created is the content of the Paragraph block. + const paragraph = getBlock( screen, 'Paragraph', 0 ); + expect( paragraph ).toBeVisible(); + // The second block created is the content of the citation element. + const citation = getBlock( screen, 'Paragraph', 1 ); + expect( citation ).toBeVisible(); + + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'matches expected transformation options', async () => { + const screen = await initializeEditor( { initialHtml } ); + const transformOptions = await getBlockTransformOptions( + screen, + block, + { canUnwrap: true } + ); + expect( transformOptions ).toHaveLength( blockTransforms.length ); + } ); +} ); diff --git a/packages/block-library/src/search/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/search/test/__snapshots__/edit.native.js.snap index 2d7971eeef7198..47652cd448c328 100644 --- a/packages/block-library/src/search/test/__snapshots__/edit.native.js.snap +++ b/packages/block-library/src/search/test/__snapshots__/edit.native.js.snap @@ -314,7 +314,17 @@ exports[`Search Block renders block with icon button option matches snapshot 1`] ] } > - Svg + diff --git a/packages/block-library/src/search/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/search/test/__snapshots__/transforms.native.js.snap new file mode 100644 index 00000000000000..fd5c0ad11e064d --- /dev/null +++ b/packages/block-library/src/search/test/__snapshots__/transforms.native.js.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Search block transforms to Columns block 1`] = ` +" +"This will make running your own blog a viable alternative again."
+— Adrian Zumbrunnen
Come+
Home.
Come+
Home.
Come
Home.
Come+`; + +const transformsWithInnerBlocks = [ 'Columns', 'Group' ]; +const blockTransforms = [ 'Paragraph', ...transformsWithInnerBlocks ]; + +setupCoreBlocks(); + +describe( `${ block } block transforms`, () => { + test.each( blockTransforms )( 'to %s block', async ( blockTransform ) => { + const screen = await initializeEditor( { initialHtml } ); + const newBlock = await transformBlock( screen, block, blockTransform, { + hasInnerBlocks: + transformsWithInnerBlocks.includes( blockTransform ), + } ); + expect( newBlock ).toBeVisible(); + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'matches expected transformation options', async () => { + const screen = await initializeEditor( { initialHtml } ); + const transformOptions = await getBlockTransformOptions( + screen, + block + ); + expect( transformOptions ).toHaveLength( blockTransforms.length ); + } ); +} ); diff --git a/packages/block-library/src/video/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/video/test/__snapshots__/transforms.native.js.snap new file mode 100644 index 00000000000000..c0ea73eadc4754 --- /dev/null +++ b/packages/block-library/src/video/test/__snapshots__/transforms.native.js.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Video block transforms to Columns block 1`] = ` +" +
Home.
Cloudup video
+First paragraph
- +x', } ); await editor.insertBlock( { name: 'core/list' } ); - await pageUtils.pressKeyWithModifier( 'primary', 'v' ); + await pageUtils.pressKeys( 'primary+v' ); // Ensure the selection is correct. await page.keyboard.type( 'y' ); expect( await editor.getEditedPostContent() ).toMatchSnapshot(); diff --git a/test/e2e/specs/editor/various/duplicating-blocks.spec.js b/test/e2e/specs/editor/various/duplicating-blocks.spec.js index 1878db2013dc44..aed4fae223894c 100644 --- a/test/e2e/specs/editor/various/duplicating-blocks.spec.js +++ b/test/e2e/specs/editor/various/duplicating-blocks.spec.js @@ -19,7 +19,7 @@ test.describe( 'Duplicating blocks', () => { // Select the test we just typed // This doesn't do anything but we previously had a duplicationi bug // When the selection was not collapsed. - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); await editor.clickBlockToolbarButton( 'Options' ); await page.click( 'role=menuitem[name=/Duplicate/i]' ); @@ -46,10 +46,10 @@ test.describe( 'Duplicating blocks', () => { // Select the test we just typed // This doesn't do anything but we previously had a duplicationi bug // When the selection was not collapsed. - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); // Duplicate using the keyboard shortccut. - await pageUtils.pressKeyWithModifier( 'primaryShift', 'd' ); + await pageUtils.pressKeys( 'primaryShift+d' ); expect( await editor.getEditedPostContent() ).toBe( ` diff --git a/test/e2e/specs/editor/various/font-size-picker.spec.js b/test/e2e/specs/editor/various/font-size-picker.spec.js index df16108afcf180..e63a5984443bca 100644 --- a/test/e2e/specs/editor/various/font-size-picker.spec.js +++ b/test/e2e/specs/editor/various/font-size-picker.spec.js @@ -58,7 +58,7 @@ test.describe( 'Font Size Picker', () => {
Paragraph reset - custom size
` ); - await pageUtils.pressKeyTimes( 'Backspace', 2 ); + await pageUtils.pressKeys( 'Backspace', { times: 2 } ); await expect.poll( editor.getEditedPostContent ) .toBe( `Paragraph reset - custom size
@@ -140,7 +140,7 @@ test.describe( 'Font Size Picker', () => { await page.click( 'role=group[name="Font size"i] >> role=button[name="Font size"i]' ); - await pageUtils.pressKeyTimes( 'ArrowDown', 4 ); + await pageUtils.pressKeys( 'ArrowDown', { times: 4 } ); await page.keyboard.press( 'Enter' ); await expect.poll( editor.getEditedPostContent ) @@ -162,7 +162,7 @@ test.describe( 'Font Size Picker', () => { await page.click( 'role=group[name="Font size"i] >> role=button[name="Font size"i]' ); - await pageUtils.pressKeyTimes( 'ArrowDown', 3 ); + await pageUtils.pressKeys( 'ArrowDown', { times: 3 } ); await page.keyboard.press( 'Enter' ); await expect.poll( editor.getEditedPostContent ) @@ -193,7 +193,7 @@ test.describe( 'Font Size Picker', () => { await page.click( 'role=group[name="Font size"i] >> role=button[name="Font size"i]' ); - await pageUtils.pressKeyTimes( 'ArrowDown', 2 ); + await pageUtils.pressKeys( 'ArrowDown', { times: 2 } ); await page.keyboard.press( 'Enter' ); await expect.poll( editor.getEditedPostContent ) @@ -205,7 +205,7 @@ test.describe( 'Font Size Picker', () => { 'role=region[name="Editor settings"i] >> role=button[name="Set custom size"i]' ); await page.click( 'role=spinbutton[name="Custom"i]' ); - await pageUtils.pressKeyWithModifier( 'primary', 'A' ); + await pageUtils.pressKeys( 'primary+A' ); await page.keyboard.press( 'Backspace' ); await expect.poll( editor.getEditedPostContent ) @@ -284,7 +284,7 @@ test.describe( 'Font Size Picker', () => { 'role=region[name="Editor settings"i] >> role=button[name="Set custom size"i]' ); await page.click( 'role=spinbutton[name="Custom"i]' ); - await pageUtils.pressKeyWithModifier( 'primary', 'A' ); + await pageUtils.pressKeys( 'primary+A' ); await page.keyboard.press( 'Backspace' ); await expect.poll( editor.getEditedPostContent ) diff --git a/test/e2e/specs/editor/various/list-view.spec.js b/test/e2e/specs/editor/various/list-view.spec.js index 46e86709c41313..906159c944d1e7 100644 --- a/test/e2e/specs/editor/various/list-view.spec.js +++ b/test/e2e/specs/editor/various/list-view.spec.js @@ -19,7 +19,7 @@ test.describe( 'List View', () => { await editor.insertBlock( { name: 'core/paragraph' } ); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); const listView = page.getByRole( 'treegrid', { name: 'Block navigation structure', } ); @@ -72,7 +72,7 @@ test.describe( 'List View', () => { await editor.insertBlock( { name: 'core/paragraph' } ); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); const listView = page.getByRole( 'treegrid', { name: 'Block navigation structure', } ); @@ -86,7 +86,7 @@ test.describe( 'List View', () => { ).toBeVisible(); // Go to the image block in List View. - await pageUtils.pressKeyTimes( 'ArrowUp', 2 ); + await pageUtils.pressKeys( 'ArrowUp', { times: 2 } ); await expect( listView .getByRole( 'gridcell', { @@ -127,7 +127,7 @@ test.describe( 'List View', () => { await editor.insertBlock( { name: 'core/paragraph' } ); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); const listView = page.getByRole( 'treegrid', { name: 'Block navigation structure', } ); @@ -168,7 +168,7 @@ test.describe( 'List View', () => { await editor.insertBlock( { name: 'core/paragraph' } ); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); const listView = page.getByRole( 'treegrid', { name: 'Block navigation structure', } ); @@ -182,7 +182,7 @@ test.describe( 'List View', () => { ).toBeVisible(); // Select the image block in List View. - await pageUtils.pressKeyTimes( 'ArrowUp', 2 ); + await pageUtils.pressKeys( 'ArrowUp', { times: 2 } ); await expect( listView .getByRole( 'gridcell', { @@ -221,7 +221,7 @@ test.describe( 'List View', () => { await editor.insertBlock( { name: 'core/heading' } ); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); const listView = page.getByRole( 'treegrid', { name: 'Block navigation structure', } ); @@ -235,7 +235,7 @@ test.describe( 'List View', () => { ).toBeVisible(); // Select the Image block as well. - await pageUtils.pressKeyWithModifier( 'shift', 'ArrowUp' ); + await pageUtils.pressKeys( 'shift+ArrowUp' ); await expect( listView.getByRole( 'gridcell', { name: 'Image link', @@ -271,7 +271,7 @@ test.describe( 'List View', () => { .click(); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); const listView = page.getByRole( 'treegrid', { name: 'Block navigation structure', } ); @@ -341,7 +341,7 @@ test.describe( 'List View', () => { await editor.insertBlock( { name: 'core/group' } ); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); const listView = page.getByRole( 'treegrid', { name: 'Block navigation structure', } ); @@ -409,7 +409,7 @@ test.describe( 'List View', () => { ).toBeFocused(); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); const listView = page.getByRole( 'treegrid', { name: 'Block navigation structure', } ); @@ -445,12 +445,12 @@ test.describe( 'List View', () => { // Since focus is now at the image block upload button in the canvas, // pressing the list view shortcut should bring focus back to the image // block in the list view. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); await expect( imageItem ).toBeFocused(); // Since focus is now inside the list view, the shortcut should close // the sidebar. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); // Focus should now be on the paragraph block since that is // where we opened the list view sidebar. This is not a perfect @@ -464,15 +464,15 @@ test.describe( 'List View', () => { await expect( listView ).not.toBeVisible(); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); // Focus the list view close button and make sure the shortcut will // close the list view. This is to catch a bug where elements could be // out of range of the sidebar region. Must shift+tab 3 times to reach // close button before tabs. - await pageUtils.pressKeyWithModifier( 'shift', 'Tab' ); - await pageUtils.pressKeyWithModifier( 'shift', 'Tab' ); - await pageUtils.pressKeyWithModifier( 'shift', 'Tab' ); + await pageUtils.pressKeys( 'shift+Tab' ); + await pageUtils.pressKeys( 'shift+Tab' ); + await pageUtils.pressKeys( 'shift+Tab' ); await expect( editor.canvas.getByRole( 'button', { name: 'Close Document Overview Sidebar', @@ -480,15 +480,15 @@ test.describe( 'List View', () => { ).toBeFocused(); // Close List View and ensure it's closed. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); await expect( listView ).not.toBeVisible(); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); // Focus the outline tab and select it. This test ensures the outline // tab receives similar focus events based on the shortcut. - await pageUtils.pressKeyWithModifier( 'shift', 'Tab' ); + await pageUtils.pressKeys( 'shift+Tab' ); const outlineButton = editor.canvas.getByRole( 'button', { name: 'Outline', } ); @@ -497,14 +497,14 @@ test.describe( 'List View', () => { // From here, tab in to the editor so focus can be checked on return to // the outline tab in the sidebar. - await pageUtils.pressKeyTimes( 'Tab', 2 ); + await pageUtils.pressKeys( 'Tab', { times: 2 } ); // Focus should be placed on the outline tab button since there is // nothing to focus inside the tab itself. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); await expect( outlineButton ).toBeFocused(); // Close List View and ensure it's closed. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); await expect( listView ).not.toBeVisible(); } ); @@ -519,7 +519,7 @@ test.describe( 'List View', () => { await editor.insertBlock( { name: 'core/paragraph' } ); // Open List View. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); const listView = page.getByRole( 'treegrid', { name: 'Block navigation structure', } ); @@ -533,7 +533,7 @@ test.describe( 'List View', () => { ).toBeVisible(); // Go to the image block in List View. - await pageUtils.pressKeyTimes( 'ArrowUp', 2 ); + await pageUtils.pressKeys( 'ArrowUp', { times: 2 } ); await expect( listView .getByRole( 'gridcell', { @@ -552,7 +552,7 @@ test.describe( 'List View', () => { ).toBeFocused(); // Triggering the List View shortcut should result in the image block gaining focus. - await pageUtils.pressKeyWithModifier( 'access', 'o' ); + await pageUtils.pressKeys( 'access+o' ); await expect( listView .getByRole( 'gridcell', { diff --git a/test/e2e/specs/editor/various/mentions.spec.js b/test/e2e/specs/editor/various/mentions.spec.js index 878cf148e8abf5..b7e75e046c471a 100644 --- a/test/e2e/specs/editor/various/mentions.spec.js +++ b/test/e2e/specs/editor/various/mentions.spec.js @@ -44,7 +44,7 @@ test.describe( 'autocomplete mentions', () => { } ) => { await page.click( 'role=button[name="Add default block"i]' ); await page.keyboard.type( 'Stuck in the middle with you' ); - await pageUtils.pressKeyTimes( 'ArrowLeft', 'you'.length ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 'you'.length } ); await page.keyboard.type( '@j' ); await expect( page.locator( 'role=listbox >> role=option[name=/testuser/i]' ) diff --git a/test/e2e/specs/editor/various/multi-block-selection.spec.js b/test/e2e/specs/editor/various/multi-block-selection.spec.js index d651001c8f2640..3e03a0c2805620 100644 --- a/test/e2e/specs/editor/various/multi-block-selection.spec.js +++ b/test/e2e/specs/editor/various/multi-block-selection.spec.js @@ -35,8 +35,8 @@ test.describe( 'Multi-block selection', () => { } // Multiselect via keyboard. - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+a' ); await expect .poll( multiBlockSelectionUtils.getSelectedFlatIndices ) @@ -67,10 +67,10 @@ test.describe( 'Multi-block selection', () => { .getByRole( 'document', { name: 'Empty block' } ) .click(); // Move to the middle of the first line. - await pageUtils.pressKeyTimes( 'ArrowUp', 4 ); + await pageUtils.pressKeys( 'ArrowUp', { times: 4 } ); await page.keyboard.press( 'ArrowRight' ); // Select mid line one to mid line four. - await pageUtils.pressKeyTimes( 'Shift+ArrowDown', 3 ); + await pageUtils.pressKeys( 'Shift+ArrowDown', { times: 3 } ); // Delete the text to see if the selection was correct. await page.keyboard.press( 'Backspace' ); @@ -227,8 +227,8 @@ test.describe( 'Multi-block selection', () => { attributes: { content: `${ i }` }, } ); } - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+a' ); await expect .poll( multiBlockSelectionUtils.getSelectedFlatIndices ) @@ -308,7 +308,7 @@ test.describe( 'Multi-block selection', () => { await editor.canvas .getByRole( 'document', { name: 'Paragraph block' } ) .click( { modifiers: [ 'Shift' ] } ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); await page.keyboard.type( 'new content' ); await expect.poll( editor.getBlocks ).toMatchObject( [ @@ -468,13 +468,13 @@ test.describe( 'Multi-block selection', () => { attributes: { content: '2' }, } ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'x' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+x' ); await expect.poll( editor.getBlocks ).toEqual( [] ); - await pageUtils.pressKeyWithModifier( 'primary', 'v' ); + await pageUtils.pressKeys( 'primary+v' ); await expect.poll( editor.getBlocks ).toMatchObject( [ { name: 'core/paragraph', attributes: { content: '1' } }, @@ -492,16 +492,16 @@ test.describe( 'Multi-block selection', () => { attributes: { content: 'second paragraph' }, } ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'c' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+c' ); await page.keyboard.press( 'Backspace' ); await expect .poll( editor.getBlocks, 'should select all blocks after copying' ) .toEqual( [] ); - await pageUtils.pressKeyWithModifier( 'primary', 'v' ); + await pageUtils.pressKeys( 'primary+v' ); await expect .poll( editor.getBlocks, 'should copy and paste multiple blocks' ) .toMatchObject( [ @@ -520,9 +520,9 @@ test.describe( 'Multi-block selection', () => { { attributes: { content: 'second paragraph|' } }, ] ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'v' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+v' ); await page.keyboard.type( '|' ); await expect .poll( editor.getBlocks, 'should replace blocks' ) @@ -532,8 +532,8 @@ test.describe( 'Multi-block selection', () => { ] ); await page.keyboard.press( 'Backspace' ); - await pageUtils.pressKeyTimes( 'ArrowLeft', 3 ); - await pageUtils.pressKeyWithModifier( 'primary', 'v' ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 3 } ); + await pageUtils.pressKeys( 'primary+v' ); await page.keyboard.type( '|' ); await expect .poll( editor.getBlocks, 'should paste mid-block' ) @@ -689,8 +689,8 @@ test.describe( 'Multi-block selection', () => { attributes: { content: `${ i }` }, } ); } - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+a' ); await page .getByRole( 'toolbar', { name: 'Block tools' } ) @@ -720,8 +720,8 @@ test.describe( 'Multi-block selection', () => { .click(); await page.keyboard.type( '1' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+a' ); await page.keyboard.press( 'Enter' ); await expect.poll( editor.getBlocks ).toMatchObject( [ @@ -761,8 +761,8 @@ test.describe( 'Multi-block selection', () => { .nth( 1 ) .click(); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); + await pageUtils.pressKeys( 'primary+a' ); await expect .poll( multiBlockSelectionUtils.getSelectedBlocks ) @@ -771,13 +771,13 @@ test.describe( 'Multi-block selection', () => { { name: 'core/paragraph' }, ] ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); await expect .poll( multiBlockSelectionUtils.getSelectedBlocks ) .toMatchObject( [ { name: 'core/column' } ] ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); await expect .poll( multiBlockSelectionUtils.getSelectedBlocks ) @@ -818,17 +818,17 @@ test.describe( 'Multi-block selection', () => { .getByRole( 'textbox' ) .click(); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); await expect .poll( multiBlockSelectionUtils.getSelectedBlocks ) .toMatchObject( [ { name: 'core/list-item' } ] ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); await expect .poll( multiBlockSelectionUtils.getSelectedBlocks ) .toMatchObject( [ { name: 'core/list' } ] ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); await expect .poll( multiBlockSelectionUtils.getSelectedBlocks ) .toMatchObject( [ @@ -858,7 +858,7 @@ test.describe( 'Multi-block selection', () => { .poll( multiBlockSelectionUtils.getSelectedBlocks ) .toEqual( [] ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); await page.keyboard.press( 'Backspace' ); @@ -883,7 +883,7 @@ test.describe( 'Multi-block selection', () => { .getByRole( 'textbox', { name: 'Add title' } ) .type( 'Post title' ); - await pageUtils.pressKeyWithModifier( 'primary', 'a' ); + await pageUtils.pressKeys( 'primary+a' ); await expect .poll( multiBlockSelectionUtils.getSelectedBlocks ) @@ -958,7 +958,7 @@ test.describe( 'Multi-block selection', () => { navButtons.nth( 3 ).getByRole( 'link', { includeHidden: true } ) ).toBeFocused(); // Press Up twice to highlight the second block. - await pageUtils.pressKeyTimes( 'ArrowUp', 2 ); + await pageUtils.pressKeys( 'ArrowUp', { times: 2 } ); await page.keyboard.press( 'Shift+ArrowDown' ); await expect @@ -976,7 +976,7 @@ test.describe( 'Multi-block selection', () => { ) .toEqual( [ 2, 3, 4 ] ); - await pageUtils.pressKeyTimes( 'Shift+ArrowUp', 3 ); + await pageUtils.pressKeys( 'Shift+ArrowUp', { times: 3 } ); await expect .poll( multiBlockSelectionUtils.getSelectedFlatIndices, @@ -985,7 +985,7 @@ test.describe( 'Multi-block selection', () => { .toEqual( [ 1, 2 ] ); // Navigate to the bottom of the list of blocks. - await pageUtils.pressKeyTimes( 'ArrowDown', 3 ); + await pageUtils.pressKeys( 'ArrowDown', { times: 3 } ); // This tests that shift selecting blocks by keyboard that are not adjacent // to an existing selection resets the selection. @@ -1022,7 +1022,7 @@ test.describe( 'Multi-block selection', () => { await page.keyboard.press( 'ArrowLeft' ); // Select everything between []. - await pageUtils.pressKeyTimes( 'Shift+ArrowLeft', 5 ); + await pageUtils.pressKeys( 'Shift+ArrowLeft', { times: 5 } ); await page.keyboard.press( 'Delete' ); @@ -1049,7 +1049,7 @@ test.describe( 'Multi-block selection', () => { await page.keyboard.type( ']2' ); await page.keyboard.press( 'ArrowLeft' ); // Select everything between []. - await pageUtils.pressKeyTimes( 'Shift+ArrowLeft', 3 ); + await pageUtils.pressKeys( 'Shift+ArrowLeft', { times: 3 } ); // Ensure selection is in the correct place. await page.keyboard.type( '|' ); @@ -1084,7 +1084,7 @@ test.describe( 'Multi-block selection', () => { .click(); await page.keyboard.press( 'ArrowLeft' ); // Select everything between []. - await pageUtils.pressKeyTimes( 'Shift+ArrowLeft', 5 ); + await pageUtils.pressKeys( 'Shift+ArrowLeft', { times: 5 } ); await page.keyboard.press( 'Enter' ); @@ -1127,7 +1127,7 @@ test.describe( 'Multi-block selection', () => { .filter( { hasText: 'a' } ) .click(); - await pageUtils.pressKeyTimes( 'Shift+ArrowDown', 2 ); + await pageUtils.pressKeys( 'Shift+ArrowDown', { times: 2 } ); await page.keyboard.press( 'Backspace' ); // Ensure selection is in the correct place. diff --git a/test/e2e/specs/editor/various/rtl.spec.js b/test/e2e/specs/editor/various/rtl.spec.js index d06c0ec8a43894..899dfd3c87ddec 100644 --- a/test/e2e/specs/editor/various/rtl.spec.js +++ b/test/e2e/specs/editor/various/rtl.spec.js @@ -151,9 +151,9 @@ test.describe( 'RTL', () => { pageUtils, } ) => { await page.click( 'role=button[name="Add default block"i]' ); - await pageUtils.pressKeyWithModifier( 'primary', 'b' ); + await pageUtils.pressKeys( 'primary+b' ); await page.keyboard.type( ARABIC_ONE ); - await pageUtils.pressKeyWithModifier( 'primary', 'b' ); + await pageUtils.pressKeys( 'primary+b' ); await page.keyboard.type( ARABIC_TWO ); // Insert a character at each boundary position. diff --git a/test/e2e/specs/editor/various/splitting-merging.spec.js b/test/e2e/specs/editor/various/splitting-merging.spec.js index 510c1cb46cf3b3..fc6d09fcc3240c 100644 --- a/test/e2e/specs/editor/various/splitting-merging.spec.js +++ b/test/e2e/specs/editor/various/splitting-merging.spec.js @@ -23,7 +23,7 @@ test.describe( 'splitting and merging blocks', () => { // Move caret between 'First' and 'Second' and press Enter to split // paragraph blocks. - await pageUtils.pressKeyTimes( 'ArrowLeft', 6 ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 6 } ); await page.keyboard.press( 'Enter' ); // Assert that there are now two paragraph blocks with correct content. @@ -55,16 +55,16 @@ test.describe( 'splitting and merging blocks', () => { ` ); - await pageUtils.pressKeyTimes( 'Backspace', 7 ); // Delete "Between" + await pageUtils.pressKeys( 'Backspace', { times: 7 } ); // Delete "Between" // Edge case: Without ensuring that the editor still has focus when // restoring a bookmark, the caret may be inadvertently moved back to // an inline boundary after a split occurs. await page.keyboard.press( 'Home' ); await page.keyboard.down( 'Shift' ); - await pageUtils.pressKeyTimes( 'ArrowRight', 5 ); + await pageUtils.pressKeys( 'ArrowRight', { times: 5 } ); await page.keyboard.up( 'Shift' ); - await pageUtils.pressKeyWithModifier( 'primary', 'b' ); + await pageUtils.pressKeys( 'primary+b' ); // Collapse selection, still within inline boundary. await page.keyboard.press( 'ArrowRight' ); await page.keyboard.press( 'Enter' ); @@ -90,13 +90,13 @@ test.describe( 'splitting and merging blocks', () => { // Regression Test: Caret should reset to end of inline boundary when // backspacing to delete second paragraph. await editor.insertBlock( { name: 'core/paragraph' } ); - await pageUtils.pressKeyWithModifier( 'primary', 'b' ); + await pageUtils.pressKeys( 'primary+b' ); await page.keyboard.type( 'Foo' ); await page.keyboard.press( 'Enter' ); await page.keyboard.press( 'Backspace' ); // Replace contents of first paragraph with "Bar". - await pageUtils.pressKeyTimes( 'Backspace', 4 ); + await pageUtils.pressKeys( 'Backspace', { times: 4 } ); await page.keyboard.type( 'Bar' ); const content = await editor.getEditedPostContent(); @@ -161,7 +161,7 @@ test.describe( 'splitting and merging blocks', () => { // Select text. await page.keyboard.down( 'Shift' ); - await pageUtils.pressKeyTimes( 'ArrowLeft', 3 ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 3 } ); await page.keyboard.up( 'Shift' ); // Delete selection. @@ -194,9 +194,9 @@ test.describe( 'splitting and merging blocks', () => { // The regression appeared to only affect paragraphs created while // within an inline boundary. await page.keyboard.down( 'Shift' ); - await pageUtils.pressKeyTimes( 'ArrowLeft', 3 ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 3 } ); await page.keyboard.up( 'Shift' ); - await pageUtils.pressKeyWithModifier( 'primary', 'b' ); + await pageUtils.pressKeys( 'primary+b' ); await page.keyboard.press( 'ArrowRight' ); await page.keyboard.press( 'Enter' ); await page.keyboard.press( 'Enter' ); @@ -331,7 +331,7 @@ test.describe( 'splitting and merging blocks', () => { await page.keyboard.type( '12' ); await page.keyboard.press( 'ArrowLeft' ); await page.keyboard.press( 'Enter' ); - await pageUtils.pressKeyWithModifier( 'primary', 'z' ); + await pageUtils.pressKeys( 'primary+z' ); // Check the content. expect( await editor.getEditedPostContent() ).toMatchSnapshot(); @@ -345,7 +345,7 @@ test.describe( 'splitting and merging blocks', () => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( '1' ); await page.keyboard.press( 'Enter' ); - await pageUtils.pressKeyWithModifier( 'shift', 'Enter' ); + await pageUtils.pressKeys( 'shift+Enter' ); await page.keyboard.type( '2' ); await page.keyboard.press( 'ArrowLeft' ); await page.keyboard.press( 'Backspace' ); @@ -377,7 +377,7 @@ test.describe( 'splitting and merging blocks', () => { await page.keyboard.type( 'item 1' ); await page.keyboard.press( 'Enter' ); await page.keyboard.type( 'item 2' ); - await pageUtils.pressKeyTimes( 'ArrowUp', 3 ); + await pageUtils.pressKeys( 'ArrowUp', { times: 3 } ); await page.keyboard.press( 'Delete' ); expect( await editor.getEditedPostContent() ).toMatchSnapshot(); @@ -398,7 +398,7 @@ test.describe( 'splitting and merging blocks', () => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( 'item 2' ); await page.keyboard.press( 'ArrowUp' ); - await pageUtils.pressKeyTimes( 'ArrowLeft', 6 ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 6 } ); await page.keyboard.press( 'Backspace' ); expect( await editor.getEditedPostContent() ).toMatchSnapshot(); diff --git a/test/e2e/specs/editor/various/toolbar-roving-tabindex.spec.js b/test/e2e/specs/editor/various/toolbar-roving-tabindex.spec.js index 0feb50f1b92330..7026be84c72a3f 100644 --- a/test/e2e/specs/editor/various/toolbar-roving-tabindex.spec.js +++ b/test/e2e/specs/editor/various/toolbar-roving-tabindex.spec.js @@ -93,6 +93,7 @@ test.describe( 'Toolbar roving tabindex', () => { editor, page, ToolbarRovingTabindexUtils, + pageUtils, } ) => { await editor.insertBlock( { name: 'core/table' } ); await ToolbarRovingTabindexUtils.testBlockToolbarKeyboardNavigation( @@ -103,7 +104,7 @@ test.describe( 'Toolbar roving tabindex', () => { await page.keyboard.press( 'Home' ); await ToolbarRovingTabindexUtils.expectLabelToHaveFocus( 'Table' ); await page.click( `role=button[name="Create Table"i]` ); - await page.keyboard.press( 'Tab' ); + await pageUtils.pressKeys( 'Tab' ); await ToolbarRovingTabindexUtils.testBlockToolbarKeyboardNavigation( 'Body cell text', 'Table' @@ -144,8 +145,8 @@ test.describe( 'Toolbar roving tabindex', () => { await ToolbarRovingTabindexUtils.focusBlockToolbar(); await page.keyboard.press( 'ArrowRight' ); await ToolbarRovingTabindexUtils.expectLabelToHaveFocus( 'Move up' ); - await page.keyboard.press( 'Tab' ); - await pageUtils.pressKeyWithModifier( 'shift', 'Tab' ); + await pageUtils.pressKeys( 'Tab' ); + await pageUtils.pressKeys( 'shift+Tab' ); await ToolbarRovingTabindexUtils.expectLabelToHaveFocus( 'Move up' ); } ); @@ -154,7 +155,7 @@ test.describe( 'Toolbar roving tabindex', () => { pageUtils, ToolbarRovingTabindexUtils, } ) => { - await pageUtils.pressKeyWithModifier( 'alt', 'F10' ); + await pageUtils.pressKeys( 'alt+F10' ); await page.keyboard.press( 'ArrowRight' ); await page.keyboard.press( 'ArrowRight' ); await ToolbarRovingTabindexUtils.expectLabelToHaveFocus( 'Bold' ); @@ -168,7 +169,7 @@ class ToolbarRovingTabindexUtils { } async focusBlockToolbar() { - await this.pageUtils.pressKeyWithModifier( 'alt', 'F10' ); + await this.pageUtils.pressKeys( 'alt+F10' ); } async testBlockToolbarKeyboardNavigation( @@ -179,9 +180,9 @@ class ToolbarRovingTabindexUtils { await this.expectLabelToHaveFocus( currentBlockTitle ); await this.page.keyboard.press( 'ArrowRight' ); await this.expectLabelToHaveFocus( 'Move up' ); - await this.page.keyboard.press( 'Tab' ); + await this.pageUtils.pressKeys( 'Tab' ); await this.expectLabelToHaveFocus( currentBlockLabel ); - await this.pageUtils.pressKeyWithModifier( 'shift', 'Tab' ); + await this.pageUtils.pressKeys( 'shift+Tab' ); await this.expectLabelToHaveFocus( 'Move up' ); } @@ -208,7 +209,7 @@ class ToolbarRovingTabindexUtils { await this.expectLabelToHaveFocus( 'Block: Group' ); await this.page.keyboard.press( 'ArrowRight' ); await this.expectLabelToHaveFocus( currentBlockLabel ); - await this.pageUtils.pressKeyWithModifier( 'shift', 'Tab' ); + await this.pageUtils.pressKeys( 'shift+Tab' ); await this.expectLabelToHaveFocus( 'Select Group' ); await this.page.keyboard.press( 'ArrowRight' ); await this.expectLabelToHaveFocus( currentBlockTitle ); diff --git a/test/e2e/specs/editor/various/writing-flow.spec.js b/test/e2e/specs/editor/various/writing-flow.spec.js index 64f28c4f5a0931..80e3fb3b126827 100644 --- a/test/e2e/specs/editor/various/writing-flow.spec.js +++ b/test/e2e/specs/editor/various/writing-flow.spec.js @@ -122,13 +122,13 @@ test.describe( 'Writing Flow', () => { await page.keyboard.type( 'Third' ); // Navigate to second paragraph. - await pageUtils.pressKeyTimes( 'ArrowLeft', 6 ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 6 } ); // Bold second paragraph text. await page.keyboard.down( 'Shift' ); - await pageUtils.pressKeyTimes( 'ArrowLeft', 6 ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 6 } ); await page.keyboard.up( 'Shift' ); - await pageUtils.pressKeyWithModifier( 'primary', 'b' ); + await pageUtils.pressKeys( 'primary+b' ); // Arrow left from selected bold should collapse to before the inline // boundary. Arrow once more to traverse into first paragraph. @@ -138,18 +138,18 @@ test.describe( 'Writing Flow', () => { // Arrow right from end of first should traverse to second, *BEFORE* // the bolded text. Another press should move within inline boundary. - await pageUtils.pressKeyTimes( 'ArrowRight', 2 ); + await pageUtils.pressKeys( 'ArrowRight', { times: 2 } ); await page.keyboard.type( 'Inside' ); // Arrow left from end of beginning of inline boundary should move to // the outside of the inline boundary. - await pageUtils.pressKeyTimes( 'ArrowLeft', 6 ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 6 } ); await page.keyboard.press( 'ArrowLeft' ); // Separate for emphasis. await page.keyboard.type( 'Before' ); // Likewise, test at the end of the inline boundary for same effect. await page.keyboard.press( 'ArrowRight' ); // Move inside - await pageUtils.pressKeyTimes( 'ArrowRight', 12 ); + await pageUtils.pressKeys( 'ArrowRight', { times: 12 } ); await page.keyboard.type( 'Inside' ); await page.keyboard.press( 'ArrowRight' ); @@ -176,18 +176,18 @@ test.describe( 'Writing Flow', () => { pageUtils, } ) => { await page.keyboard.press( 'Enter' ); - await pageUtils.pressKeyWithModifier( 'primary', 'b' ); + await pageUtils.pressKeys( 'primary+b' ); await page.keyboard.type( '1 2' ); await page.keyboard.down( 'Shift' ); await page.keyboard.press( 'ArrowLeft' ); await page.keyboard.up( 'Shift' ); - await pageUtils.pressKeyWithModifier( 'primary', 'i' ); + await pageUtils.pressKeys( 'primary+i' ); await page.keyboard.press( 'ArrowLeft' ); await page.keyboard.press( 'ArrowLeft' ); await page.keyboard.down( 'Shift' ); await page.keyboard.press( 'ArrowLeft' ); await page.keyboard.up( 'Shift' ); - await pageUtils.pressKeyWithModifier( 'primary', 'i' ); + await pageUtils.pressKeys( 'primary+i' ); await page.keyboard.press( 'ArrowLeft' ); await expect.poll( editor.getEditedPostContent ) @@ -228,7 +228,7 @@ test.describe( 'Writing Flow', () => { } ) => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( 'a' ); - await pageUtils.pressKeyWithModifier( 'shift', 'Enter' ); + await pageUtils.pressKeys( 'shift+Enter' ); await expect.poll( editor.getEditedPostContent ) .toBe( `a
a
b
a
1
@@ -629,7 +628,7 @@ test.describe( 'Writing Flow', () => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( '1' ); await page.keyboard.press( 'Enter' ); - await pageUtils.pressKeyWithModifier( 'shift', 'Enter' ); + await pageUtils.pressKeys( 'shift+Enter' ); await page.keyboard.type( '2' ); await page.keyboard.press( 'ArrowUp' ); await page.keyboard.press( 'ArrowUp' ); @@ -675,10 +674,10 @@ test.describe( 'Writing Flow', () => { await page.keyboard.type( 'cd' ); // Selects part of the first list item, although invisible. - await pageUtils.pressKeyWithModifier( 'shift', 'ArrowUp' ); + await pageUtils.pressKeys( 'shift+ArrowUp' ); await page.evaluate( () => new Promise( window.requestIdleCallback ) ); // Extends selection into the first paragraph - await pageUtils.pressKeyWithModifier( 'shift', 'ArrowUp' ); + await pageUtils.pressKeys( 'shift+ArrowUp' ); await page.evaluate( () => new Promise( window.requestIdleCallback ) ); // Mixed selection, so all content will be removed. @@ -731,6 +730,7 @@ test.describe( 'Writing Flow', () => { test( 'should not have a dead zone above an aligned block', async ( { editor, page, + pageUtils, } ) => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( '1' ); @@ -745,7 +745,7 @@ test.describe( 'Writing Flow', () => { await wideButton.click(); // Focus the block content - await page.keyboard.press( 'Tab' ); + await pageUtils.pressKeys( 'Tab' ); // Select the previous block. await page.keyboard.press( 'ArrowUp' ); @@ -791,13 +791,14 @@ test.describe( 'Writing Flow', () => { test( 'should only consider the content as one tab stop', async ( { editor, page, + pageUtils, } ) => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( '/table' ); await page.keyboard.press( 'Enter' ); // Tab to the "Create table" button. - await page.keyboard.press( 'Tab' ); - await page.keyboard.press( 'Tab' ); + await pageUtils.pressKeys( 'Tab' ); + await pageUtils.pressKeys( 'Tab' ); // Create the table. await page.keyboard.press( 'Space' ); await expect( @@ -881,12 +882,12 @@ test.describe( 'Writing Flow', () => { await page.keyboard.type( 'second' ); // Multi select both paragraphs. - await pageUtils.pressKeyTimes( 'ArrowLeft', 2 ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 2 } ); await page.keyboard.down( 'Shift' ); - await pageUtils.pressKeyTimes( 'ArrowLeft', 2 ); + await pageUtils.pressKeys( 'ArrowLeft', { times: 2 } ); await page.keyboard.press( 'ArrowUp' ); await page.keyboard.up( 'Shift' ); - await pageUtils.pressKeyWithModifier( 'primary', 'b' ); + await pageUtils.pressKeys( 'primary+b' ); await expect.poll( editor.getEditedPostContent ) .toBe( ` @@ -989,7 +990,7 @@ test.describe( 'Writing Flow', () => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( 'b' ); await page.keyboard.press( 'ArrowLeft' ); - await pageUtils.pressKeyWithModifier( 'alt', 'ArrowUp' ); + await pageUtils.pressKeys( 'alt+ArrowUp' ); await page.keyboard.type( '.' ); // Expect the "." to be added at the start of the paragraph diff --git a/test/e2e/specs/site-editor/style-book.spec.js b/test/e2e/specs/site-editor/style-book.spec.js index f3c06308b92154..56d0ca0cf20f1b 100644 --- a/test/e2e/specs/site-editor/style-book.spec.js +++ b/test/e2e/specs/site-editor/style-book.spec.js @@ -59,37 +59,45 @@ test.describe( 'Style Book', () => { ).toBeVisible(); await expect( page.locator( 'role=tab[name="Theme"i]' ) ).toBeVisible(); + // Buttons to select block examples are rendered within the Style Book iframe. + const styleBookIframe = page.frameLocator( + '[name="style-book-canvas"]' + ); + await expect( - page.locator( - 'role=button[name="Open Headings styles in Styles panel"i]' - ) + styleBookIframe.getByRole( 'button', { + name: 'Open Headings styles in Styles panel', + } ) ).toBeVisible(); await expect( - page.locator( - 'role=button[name="Open Paragraph styles in Styles panel"i]' - ) + styleBookIframe.getByRole( 'button', { + name: 'Open Paragraph styles in Styles panel', + } ) ).toBeVisible(); await page.click( 'role=tab[name="Media"i]' ); await expect( - page.locator( - 'role=button[name="Open Image styles in Styles panel"i]' - ) + styleBookIframe.getByRole( 'button', { + name: 'Open Image styles in Styles panel', + } ) ).toBeVisible(); await expect( - page.locator( - 'role=button[name="Open Gallery styles in Styles panel"i]' - ) + styleBookIframe.getByRole( 'button', { + name: 'Open Gallery styles in Styles panel', + } ) ).toBeVisible(); } ); test( 'should open correct Global Styles panel when example is clicked', async ( { page, } ) => { - await page.click( - 'role=button[name="Open Headings styles in Styles panel"i]' - ); + await page + .frameLocator( '[name="style-book-canvas"]' ) + .getByRole( 'button', { + name: 'Open Headings styles in Styles panel', + } ) + .click(); await expect( page.locator( @@ -105,9 +113,12 @@ test.describe( 'Style Book', () => { await page.click( 'role=button[name="Heading block styles"]' ); await page.click( 'role=button[name="Typography styles"]' ); - await page.click( - 'role=button[name="Open Quote styles in Styles panel"i]' - ); + await page + .frameLocator( '[name="style-book-canvas"]' ) + .getByRole( 'button', { + name: 'Open Quote styles in Styles panel', + } ) + .click(); await page.click( 'role=button[name="Navigate to the previous view"]' ); await page.click( 'role=button[name="Navigate to the previous view"]' ); diff --git a/test/e2e/specs/site-editor/title.spec.js b/test/e2e/specs/site-editor/title.spec.js index e194e90449160c..fada3fbe41e1ef 100644 --- a/test/e2e/specs/site-editor/title.spec.js +++ b/test/e2e/specs/site-editor/title.spec.js @@ -15,14 +15,13 @@ test.describe( 'Site editor title', () => { test( 'displays the selected template name in the title for the index template', async ( { admin, page, - editor, } ) => { // Navigate to a template. await admin.visitSiteEditor( { postId: 'emptytheme//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.click( 'body' ); const title = page.locator( 'role=region[name="Editor top bar"i] >> role=heading[level=1]' ); @@ -33,14 +32,13 @@ test.describe( 'Site editor title', () => { test( 'displays the selected template name in the title for the header template', async ( { admin, page, - editor, } ) => { // Navigate to a template part. await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.click( 'body' ); const title = page.locator( 'role=region[name="Editor top bar"i] >> role=heading[level=1]' ); @@ -51,13 +49,12 @@ test.describe( 'Site editor title', () => { test( "displays the selected template part's name in the secondary title when a template part is selected from List View", async ( { admin, page, - editor, } ) => { await admin.visitSiteEditor( { postId: 'emptytheme//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.click( 'body' ); // Select the header template part via list view. await page.click( 'role=button[name="List View"i]' ); const listView = page.locator( diff --git a/test/e2e/specs/site-editor/writing-flow.spec.js b/test/e2e/specs/site-editor/writing-flow.spec.js index 2f9a83b4874e5e..d9c63a1da1ddc5 100644 --- a/test/e2e/specs/site-editor/writing-flow.spec.js +++ b/test/e2e/specs/site-editor/writing-flow.spec.js @@ -33,7 +33,7 @@ test.describe( 'Site editor writing flow', () => { await editor.selectBlocks( siteTitleBlock ); // Shift tab to the toolbar. - await pageUtils.pressKeyWithModifier( 'shift', 'Tab' ); + await pageUtils.pressKeys( 'shift+Tab' ); const blockToolbarButton = page.locator( 'role=toolbar[name="Block tools"i] >> role=button[name="Site Title"i]' ); @@ -64,7 +64,7 @@ test.describe( 'Site editor writing flow', () => { await editor.selectBlocks( siteTaglineBlock ); // Tab to the inspector, tabbing three times to go past the two resize handles. - await pageUtils.pressKeyTimes( 'Tab', 3 ); + await pageUtils.pressKeys( 'Tab', { times: 3 } ); const inspectorTemplateTab = page.locator( 'role=region[name="Editor settings"i] >> role=button[name="Template"i]' ); diff --git a/test/e2e/specs/widgets/customizing-widgets.spec.js b/test/e2e/specs/widgets/customizing-widgets.spec.js index 01b6cf7e13ea70..9bf3dcb32b371b 100644 --- a/test/e2e/specs/widgets/customizing-widgets.spec.js +++ b/test/e2e/specs/widgets/customizing-widgets.spec.js @@ -342,6 +342,7 @@ test.describe( 'Widgets Customizer', () => { editor, page, widgetsCustomizerPage, + pageUtils, } ) => { await widgetsCustomizerPage.visitCustomizerPage(); await widgetsCustomizerPage.expandWidgetArea( 'Footer #1' ); @@ -368,7 +369,7 @@ test.describe( 'Widgets Customizer', () => { await titleInput.type( 'Hello Title' ); // Unfocus the current legacy widget. - await page.keyboard.press( 'Tab' ); + await pageUtils.pressKeys( 'Tab' ); const previewFrame = widgetsCustomizerPage.previewFrame; const legacyWidgetPreviewFrame = page.frameLocator( @@ -403,7 +404,7 @@ test.describe( 'Widgets Customizer', () => { await titleInput.type( 'Hello again!' ); // Unfocus the current legacy widget. - await page.keyboard.press( 'Tab' ); + await pageUtils.pressKeys( 'Tab' ); // Expect the preview in block to show when unfocusing the legacy widget block. await expect( diff --git a/test/integration/fixtures/blocks/core__media-text.html b/test/integration/fixtures/blocks/core__media-text.html index 8c05e44479a5ab..52ed3cb3c8a496 100644 --- a/test/integration/fixtures/blocks/core__media-text.html +++ b/test/integration/fixtures/blocks/core__media-text.html @@ -1,5 +1,5 @@ -My Content
My Content
My Content
+ +My Content
\n\t\t", + "innerContent": [ + "\n\t\tMy Content
\n\t\t" + ] + } + ], + "innerHTML": "\nMy Content
+Content
My Content
My Content
My Content
My content
My Content