diff --git a/plugins/woocommerce-blocks/.eslintrc.js b/plugins/woocommerce-blocks/.eslintrc.js index d3090e395a0..3e8eba8099c 100644 --- a/plugins/woocommerce-blocks/.eslintrc.js +++ b/plugins/woocommerce-blocks/.eslintrc.js @@ -167,10 +167,7 @@ module.exports = { '@wordpress/keycodes', '@wordpress/url', '@woocommerce/blocks-test-utils', - '@woocommerce/e2e-mocks', - '@woocommerce/e2e-types', '@woocommerce/e2e-utils', - '@woocommerce/e2e-playwright-utils', 'babel-jest', 'dotenv', 'jest-environment-puppeteer', diff --git a/plugins/woocommerce-blocks/.wp-env.json b/plugins/woocommerce-blocks/.wp-env.json index 2e3da1652c5..451e1cd1b0a 100644 --- a/plugins/woocommerce-blocks/.wp-env.json +++ b/plugins/woocommerce-blocks/.wp-env.json @@ -8,28 +8,18 @@ "env": { "tests": { "mappings": { + "wp-cli.yml": "./wp-cli.yml", "wp-content/mu-plugins": "./node_modules/@wordpress/e2e-tests/mu-plugins", "wp-content/plugins/gutenberg-test-plugins": "./node_modules/@wordpress/e2e-tests/plugins", "wp-content/plugins/woocommerce-blocks-test-plugins": "./tests/e2e/plugins", - "wp-cli.yml": "./wp-cli.yml", "wp-content/plugins/woocommerce/blocks-bin": "./bin", - "wp-content/plugins/woocommerce/blocks-bin/playwright": "./tests/e2e/bin" + "wp-content/plugins/woocommerce/blocks-bin/playwright": "./tests/e2e/bin", + "wp-content/themes": "./tests/e2e/themes", + "wp-content/themes/storefront": "https://downloads.wordpress.org/theme/storefront.latest-stable.zip", + "wp-content/themes/twentytwentyfour": "https://downloads.wordpress.org/theme/twentytwentyfour.latest-stable.zip" } } }, - "themes": [ - "https://downloads.wordpress.org/theme/storefront.latest-stable.zip", - "https://downloads.wordpress.org/theme/twentytwentyone.latest-stable.zip", - "https://downloads.wordpress.org/theme/twentytwentyfour.latest-stable.zip", - "./tests/e2e/themes/emptytheme", - "./tests/e2e/themes/storefront-child__block-notices-filter", - "./tests/e2e/themes/storefront-child__block-notices-template", - "./tests/e2e/themes/storefront-child__classic-notices-template", - "./tests/e2e/themes/theme-with-woo-templates", - "./tests/e2e/themes/twentytwentyfour-child__block-notices-filter", - "./tests/e2e/themes/twentytwentyfour-child__block-notices-template", - "./tests/e2e/themes/twentytwentyfour-child__classic-notices-template" - ], "config": { "JETPACK_AUTOLOAD_DEV": true, "SCRIPT_DEBUG": false, diff --git a/plugins/woocommerce-blocks/docs/.media/images/e2e-download-failure-artifacts.png b/plugins/woocommerce-blocks/docs/.media/images/e2e-download-failure-artifacts.png new file mode 100644 index 00000000000..a4138fa125b Binary files /dev/null and b/plugins/woocommerce-blocks/docs/.media/images/e2e-download-failure-artifacts.png differ diff --git a/plugins/woocommerce-blocks/docs/.media/images/e2e-open-trace-cmd.png b/plugins/woocommerce-blocks/docs/.media/images/e2e-open-trace-cmd.png new file mode 100644 index 00000000000..9c56155e378 Binary files /dev/null and b/plugins/woocommerce-blocks/docs/.media/images/e2e-open-trace-cmd.png differ diff --git a/plugins/woocommerce-blocks/docs/.media/images/e2e-playwright-inspector.png b/plugins/woocommerce-blocks/docs/.media/images/e2e-playwright-inspector.png new file mode 100644 index 00000000000..4de11c4c6f7 Binary files /dev/null and b/plugins/woocommerce-blocks/docs/.media/images/e2e-playwright-inspector.png differ diff --git a/plugins/woocommerce-blocks/docs/.media/images/e2e-run-from-vscode.png b/plugins/woocommerce-blocks/docs/.media/images/e2e-run-from-vscode.png new file mode 100644 index 00000000000..50056453b65 Binary files /dev/null and b/plugins/woocommerce-blocks/docs/.media/images/e2e-run-from-vscode.png differ diff --git a/plugins/woocommerce-blocks/docs/contributors/e2e-guidelines.md b/plugins/woocommerce-blocks/docs/contributors/e2e-guidelines.md index e7c26644120..d0a16c90c8a 100644 --- a/plugins/woocommerce-blocks/docs/contributors/e2e-guidelines.md +++ b/plugins/woocommerce-blocks/docs/contributors/e2e-guidelines.md @@ -1,68 +1,287 @@ -# E2E Guidelines +# WooCommerce Blocks End-to-End Tests -## Table of contents +This living document serves as a guide for writing end-to-end (E2E) tests with Playwright in the WooCommerce Blocks project. -- [Structure](#structure) -- [Playwright](#playwright) - - [Structure](#structure-1) +## Preparing the environment -This living document serves to prescribe coding guidelines specific to the WooCommerce Blocks project E2E tests. For more information on how to run Playwright end-to-end (E2E) tests, please refer to the [dedicated resource](../../tests/e2e/README.md). +Please refer to [the Getting Started section of the main `README.md`](https://github.com/woocommerce/woocommerce/blob/trunk/README.md) for a general-purpose guide on getting started. The rest of this document will assume that you've installed all of the prequisites and setup described there. -## Structure +Run the following command from the repository root to build the WooCommerce plugin: -There are two folders dedicated to E2E tests. +```sh +pnpm --filter='@woocommerce/plugin-woocommerce' watch:build +``` -The first folder is named "e2e-jest" and it contains all the E2E tests that were created with the deprecated infrastructure Jest + Puppetter. The "e2e" folder contains all the E2E tests that were created with the current infrastructure: Playwright. These tests are actively maintained and should be used for all new E2E testing. +Next, run the following command from the [`woocommerce-blocks` plugin folder](../../../woocommerce-blocks/) to start a `wp-env` instance and install all the testing products, languages, etc.: -### Playwright +```shell +cd plugins/woocommerce-blocks/ +pnpm env:start +``` -#### Structure +> [!TIP] +> If you want to start/stop the environment without running the whole setup, use the native `wp-env` commands directly, e.g. `npx wp-env start` and `npx wp-env stop`. -There are three Playwright projects configuration: +The testing environment should now be ready under [localhost:8889](http://localhost:8889). -- blockTheme -- blockThemeWithGlobalSideEffects -- classicTheme +### Resetting the environment -The blockTheme project runs the tests with the suffix _block_theme_. In this case, the theme is a block theme. The block theme is the default WordPress theme. Currently, it is Twenty-Twenty Three. You should use this configuration if you want test the block with the Site Editor. +Occasionally, you'll need to reset the environment, e.g., when testing products have been updated. To do that, run the following command and go make yourself some coffee: -The blockThemeWithGlobalSideEffects project runs the tests with the suffix _block_theme.side_effects_. These tests have side effects that can potentially impact other end-to-end (E2E) tests. Due to the nature of these tests and their potential impact, they are not executed in parallel with other tests. +```shell +pnpm env:restart +``` -The classicTheme project runs the tests with the suffix _classic_theme_. In this case, the theme is a Twenty Twenty-One. You should use this configuration if you want test the block with a classic theme. +## Running and debugging tests -Each block should have a dedicated folder with a scoped util file if you want share some logic related to the block. +> [!NOTE] +> If you're using VSCode, we recommend using the [Playwright Test](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright) extension to run and debug the tests. -#### Code Guidelines +Here is a basic set of commands to quickly start running and debugging the tests. For full documentation, see the official Playwright guide on [Running and Debugging Tests](https://playwright.dev/docs/running-tests). -##### Make tests as isolated as possible - Avoid side effects +```shell +# Run all available tests. +pnpm test:e2e -Each test should be completely isolated from another test and should run independently with its own local storage, session storage, data, cookies etc. Test isolation improves reproducibility, makes debugging easier and prevents cascading test failures. +# Run in headed mode. +pnpm test:e2e --headed -In order to avoid repetition for a particular part of your test you can use before and after hooks. Within your test file add a before hook to run a part of your test before each test such as going to a particular URL or logging in to a part of your app. This keeps your tests isolated as no test relies on another. However it is also ok to have a little duplication when tests are simple enough especially if it keeps your tests clearer and easier to read and maintain. Avoid using functions that impact other tests, such as the `deleteAllTemplates` function, which restores all templates and can break other tests since E2E tests run in parallel. After running a suite of tests for a specific block, it is important to clean up any changes made during the tests to ensure a clean slate for subsequent test runs. +# Run/Debug in UI mode. +pnpm test:e2e --ui -For more detail see [Make Tests as Isolated as Possible](https://playwright.dev/docs/best-practices#make-tests-as-isolated-as-possible). +# Run a single test file. +pnpm run test:e2e cart-block.spec.ts -##### Use Locators +# Run a set of files from a different directories. +pnpm run test:e2e tests/cart/ tests/products/ -In order to write end to end tests we need to first find elements on the webpage. We can do this by using Playwright's built in locators. Locators come with auto waiting and retry-ability. Auto waiting means that Playwright performs a range of actionability checks on the elements, such as ensuring the element is visible and enabled before it performs the click. To make tests resilient, we recommend prioritizing user-facing attributes and explicit contracts. For more detail see [Use Locators](https://playwright.dev/docs/best-practices#use-locators). +# Run files that have `cart` or `checkout` in the file name. +pnpm run test:e2e cart checkout -##### Avoid Using Relative Imports +# Run a single test via its line number. +pnpm run test:e2e cart-block.spec.ts:38 -In order to make the codebase cleaner, you should import the function from the packages: +# Run/Debug a test with a specific title. +pnpm run test:e2e -g "should display a discount label" --ui +``` -- "@woocommerce/e2e-utils": Contains generic utils for interactive with the page. -- "@woocommerce/e2e-types": Contains generic types. -- "@woocommerce/e2e-playwright-utils": Contains utils for playwright for example custom hooks. +> [!TIP] +> When a test fails, it leaves a trace info at the bottom. You can quickly jump into debugging mode by running the generated trace view command, for example: +> +> ![Playwright failed test report](../.media/images/e2e-open-trace-cmd.png) -By using these packages, you can make your code more modular and easier to maintain. +### Debugging tests in CI - +When a test fails in CI, a failure artifact is zipped and uploaded to the Summary page of the current job: ---- +![Summary page of the Blocks end-to-end tests job](../.media/images/e2e-download-failure-artifacts.png) -[We're hiring!](https://woocommerce.com/careers/) Come work with us! +Once you download and extract that zip, you'll see dedicated folders for the failed test artifacts. In CI, we retry running a failed test twice before considering it a failure, so there can be up to three folders per failed test. Each of those folders should contain a Playwright trace zip file and a screenshot from the failure moment. On the first retry, we also record the entire test, so the first retry folder should contain a video recording as well. To view a trace, head to the [Playwright Trace Viewer](https://trace.playwright.dev) page and drag and drop the trace zip file there, or run it from the command line: -🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/e2e-guidelines.md) +```shell +npx playwright show-trace +``` - +## Writing Tests +We're using the [`@wordpress/e2e-test-utils-playwright`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/e2e-test-utils-playwright) package as our framework base, so we generally follow Gutenberg E2E's [best practices](https://github.com/WordPress/gutenberg/blob/trunk/docs/contributors/code/e2e/README.md#best-practices) to reduce the framework entry threshold and necessary maintenance. However, our framework has specific aspects, which you can learn about in this section. + +> [!TIP] +> Using the right selectors can be a daunting task, so let Playwright pick the right selector for you. Open the page you're testing against via `npx playwright open localhost:8889/path-to-the-page`. From there, you can use Playwright Inspector to generate the recommended locators: +> +> ![Playwright Inspector example usage](../.media/images/e2e-playwright-inspector.png) +> +> Read more about generating tests with Playwright in the [Generating Tests](https://playwright.dev/docs/codegen-intro) guide. + +### Setup and teardown + +We isolate our tests from each other by resetting the database to its initial state **for every test**. Since every test starts with a clean slate, and there's no need to manually reset the environment, we only allow the `beforeEach` hook as there's no point in using `beforeAll`, `afterAll`, or `afterEach`. This approach might seem like a limitation at first, but ultimately it makes tests more stable and easier to write. This convention is enforced by an ESLint rule, so you don't need to worry about it. + +### Plugins + +To use a custom plugin with your tests, first create the plugin PHP file and save it to the [test plugins folder](../../tests/e2e/plugins/). Here's a handy snippet to help you get started: + +```php +// plugins/my-fancy-plugin.php + + { + await requestUtils.activatePlugin( + 'woocommerce-blocks-test-my-fancy-plugin' + ); + + await page.goto( '/shop' ); + + await expect( page.getByText( 'Howdy!' ) ).toBeVisible(); +} ); +``` + +> [!IMPORTANT] +> A plugin's slug is created automatically **from the plugin's name**, not from the `@package` statement as you might think. So, if your plugin is named `WooCommerce Blocks Test Bazzinga`, you'll need to activate it by `woocommerce-blocks-test-bazzinga`. + +### Themes + +Currently, the default theme is Twenty Twenty Four. Activating other themes is done by the `RequestUtils.activateTheme()` API, for example: + +```ts +test.beforeEach( async ( { page, requestUtils } ) => { + await requestUtils.activateTheme( 'storefront' ); +} ); +``` + +> [!NOTE] +> Unless it's a one-off thing, remember to use the `beforeEach` hook to activate your theme. Each test starts with a clean database, which means the theme will be reset to the default one as well. + +#### Adding a new theme + +If you've created a custom theme and want to use it in your tests, save it in the [test themes folder](../../tests/e2e/themes/). Check out the themes that are already there for inspiration. The activation part was explained above, so you're good to go! + +### Utilities + +We have a handful of [custom utilities](../../tests/e2e/utils/) built on top of core's [`@wordpress/e2e-test-utils-playwright`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/e2e-test-utils-playwright), so make sure to familiarize yourself with them. + +#### Creating new utilities + +Most of the time, it's better to do a little repetition instead of creating a utility, as over-abstracting can make the code too vague, complicated, or confusing. However, if the piece is complex and repeated enough, we recommend abstracting it into a [POM (Page Object Model)](https://playwright.dev/docs/pom), for example: + +```ts +import { test as base, expect, Editor } from '@woocommerce/e2e-utils'; + +class CartUtils { + editor: Editor + + constructor( { editor }: { editor: Editor } ) { + this.editor = editor; + } + + async addClothes( list ) { + // Add clothes from the list. + } + + async addBooks( list ) { + // Add books from the list. + } +} + +const test = base.extend< { cartUtils: CartUtils } >( { + cartUtils: async ( { editor }, use ) => { + await use( new CartUtils( { editor } ) ); + }, +} ); + +test( 'Add products', async( { admin, cartUtils } ) => { + await admin.createNewPost(); + await cartUtils.addClotes( [ 'Shirt', 'Cap', 'Pants' ] ); + await cartUtils.addBooks( [ 'Cooking with Woo' ] ) + + await page.goto( '/cart' ); + + await expect( this.page.getByLabel( 'Shirt' ) ).toBeVisible(); + // etc. +} ); +``` + +#### Extending Core utilities + +If you've come up with a utility that you think should be a part of the Core utilities (`Admin`, `Editor`, `RequestUtils`, etc.), go ahead and make a PR in Gutenberg - it's best to move as much as possible upstream. If you think that the utility still fits under, e.g., `Editor` but is Woo-specific, you'll need to write an extension, for example: + +```ts +// utils/editor/index.ts + +import { Editor as CoreEditor } from '@wordpress/e2e-test-utils-playwright'; + +export class Editor extends CoreEditor { + async insertAllWooBlocks() { + for ( const wooBlock of [ 'all', 'woo', 'blocks' ] ) { + await this.insertBlock( wooBlock ); + } + } +} +``` + +### Content Templates + +We have created `RequestUtils.createPostFromFile()` and `RequestUtils.createTemplateFromFile()` utilities that enable creating complex content testing scenarios with Handlebars templates. The template files are kept in the [content-templates](../../tests/e2e/content-templates/) folder, so you can head there for some inspiration. + +> [!IMPORTANT] +> The Handlebars template filenames must be prefixed with the entity type. For posts, an example filename would be `post_with-filters.handlebars`, and for templates `template_archive-product_with-filters.handlebars`. Notice that the latter contains the slug of the template (`archive-product`) before the name (`with-filters`), separated with an underscore - it's necessary for the template to be properly loaded and created. + +When you have the template ready, we recommend creating a [test fixture](https://playwright.dev/docs/test-fixtures) that will be used to compile and create your template with given data, for example: + +```ts +// tests/product-collection.spec.ts + +import { test as base, expect, TemplateCompiler } from '@woocommerce/e2e-utils'; + +const test = base.extend< { + filteredProductsTemplate: TemplateCompiler +} >( { + filteredProductsTemplate: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_with-filters' + ); + await use( compiler ); + }, +} ); + +test( 'Renders correct products for $10-$99 price range', async ( { + page, + filteredProductsTemplate, +} ) => { + await filteredProductsTemplate.compile( { + price: { + from: '$10', + to: '$99', + }, + } ); + + await page.goto( '/shop' ); + + await expect( page.getByLabel( 'Products' ) ).toHaveText( [ + 'Socks', + 'T-Shirt', + ] ); +} ); + +test( 'Renders correct products for $100-$999 price range', async ( { + page, + filteredProductsTemplate, +} ) => { + await filteredProductsTemplate.compile( { + price: { + from: '$100', + to: '$990', + }, + } ); + + await page.goto( '/shop' ); + + await expect( page.getByLabel( 'Products' ) ).toHaveText( [ + 'Rolex', + 'Lambo', + ] ); +} ); +``` diff --git a/plugins/woocommerce-blocks/tests/e2e/README.md b/plugins/woocommerce-blocks/tests/e2e/README.md index c568f872fd0..5cbc24a179f 100644 --- a/plugins/woocommerce-blocks/tests/e2e/README.md +++ b/plugins/woocommerce-blocks/tests/e2e/README.md @@ -1,224 +1,45 @@ -# WooCommerce Blocks Playwright End to End Tests +# WooCommerce Blocks End-to-End Tests -This is the documentation for the new E2E testing setup based on Playwright and wp-env. Over time, these playwright E2E tests should replace the current [Puppeteer E2E tests](../e2e-jest/). +This document provides an overview of the WooCommerce Blocks end-to-end testing process. For detailed instructions and comprehensive guidelines, please refer to the [contributor guidelines document](../../docs/contributors/e2e-guidelines.md). -## Table of contents +## Quick Start -- [Pre-requisites](#pre-requisites) -- [Introduction](#introduction) - - [Running tests for the first time](#running-tests-for-the-first-time) - - [To run the test again, re-create the environment to start with a fresh state](#to-run-the-test-again-re-create-the-environment-to-start-with-a-fresh-state) - - [Other ways of running tests](#other-ways-of-running-tests) - - [Troubleshooting](#troubleshooting) +### Preparing the Environment -## Pre-requisites +1. Build the WooCommerce Plugin: -- Node.js ([Installation instructions](https://nodejs.org/en/download/)) -- NVM ([Installation instructions](https://github.com/nvm-sh/nvm)) -- Docker and Docker Compose ([Installation instructions](https://docs.docker.com/engine/install/)) + ```sh + pnpm --filter='@woocommerce/plugin-woocommerce' watch:build + ``` -Note, that if you are on Mac and you install docker through other methods such as homebrew, for example, your steps to set it up might be different. The commands listed in steps below may also vary. +2. Go to the WooCommerce Blocks plugin folder: -If you are using Windows, we recommend using [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/) for running E2E tests. Follow the [WSL Setup Instructions](../tests/e2e-jest/WSL_SETUP_INSTRUCTIONS.md) first before proceeding with the steps below. + ```sh + cd plugins/woocommerce-blocks/ + ``` -## Introduction +3. Start the environment: -End-to-end tests are powered by Playwright. The test site is spun up using `wp-env` (recommended), but we will continue to support `e2e-environment` in the meantime. + ```sh + pnpm env:start + ``` -### Running tests for the first time +### Running the Tests -In the root directory, run: +1. Run all tests: -```sh -nvm use -``` + ```sh + pnpm test:e2e + ``` -```sh -pnpm install -``` +2. Run a single test file: -Now change directory to `plugins/woocommerce-blocks/`: + ```sh + pnpm test:e2e path/to/the/file.spec.ts + ``` -```sh -cd plugins/woocommerce-blocks/ -``` +3. Run/Debug in UI mode: -Ensure necessary browsers are installed: - -```sh -npx playwright install -``` - -```sh -pnpm run env:start -``` - -```sh -pnpm run test:e2e -``` - -ℹ️ If you have any problems running the tests, check out the [Troubleshooting](#troubleshooting) section for help. - -### To run the test again, re-create the environment to start with a fresh state - -```sh -pnpm run env:restart -``` - -```sh -pnpm run test:e2e -``` - -### Adding posts for testing block content - -During test setup posts are automatically created from all the html files contained in `./bin/posts`. All posts are given a title like `File Name Block` which generates a url like `file-name-block`. - -e.g. `my-test.html` will generate a post with the title `My Test Block` and permalink `my-test-block`. You'll be able to navigate to that page in your test like: - -```ts -await page.goto( '/my-test-block/' ); -``` - -Please also note that the posts are generated during initial environment setup, so if you add or edit a post file you'll need to restart the environment to see the changes. - -### Tests with side effects - -We call tests that affect other tests (ones that modify the site settings, using custom plugins) are tests with side effects and we [split](https://github.com/woocommerce/woocommerce-blocks/pull/10508) those tests to a separate test suite: - -```sh -pnpm run test:e2e:side-effects -``` - -_Note: All command parameters of `test:e2e` can be used for -`test:e2e:side-effects`._ - -### Tests with a classic theme and a block theme with custom templates - -By default, e2e tests run in a non-customized block theme. However, we also have some e2e tests which run specifically in a classic theme and in a block theme with custom templates. They can be run like this: - -```sh -pnpm run test:e2e:classic-theme -``` - -```sh -pnpm run test:e2e:block-theme-with-templates -``` - -\_Note: All command parameters of `test:e2e` can be used for these commands too. - -### Other ways of running tests - -Headless mode: - -```sh -pnpm run test:e2e -``` - -Interactive UI mode: - -```sh -pnpm run test:e2e --ui -``` - -Headed mode: - -```sh -pnpm run test:e2e --headed -``` - -Debug mode: - -```sh -pnpm run test:e2e --debug -``` - -Running a single test: - -```sh -pnpm run test:e2e ./tests/e2e/tests/example.spec.ts -``` - -To see all options, run the following command: - -```sh -npx playwright test --help -``` - -### Generating dynamic posts to test block variations - -Testing a single block can be daunting considering all the different attribute combinations that could be -considered valid for a single block. The basic templating system available in this test suite allows for -the generation of dynamic posts that can be used to test block variations. - -Templates use the Handlebars templating system and you can put them anywhere. It's simplest to co-locate them -with the test. You can easily pass custom attributes to a block in your template using the wp-block helper -we've defined. - -It looks like this in the template: - -```handlebars -{{#> wp-block name="woocommerce/featured-category" attributes=attributes /}} - You can nest content here if you want to test the block with some content. -{{/wp-block}} -``` - -In your tests you can use `createPostFromTemplate` to create a post containing your template. If you use it -more than once in your test you can extend the test suite and provide the posts as fixtures, like in the example -below - -```js -import { test as base } from '@playwright/test'; - -const test = base.extend< { - dropdownBlockPost: Post; - defaultBlockPost: Post; -} >( { - defaultBlockPost: async ( { requestUtils }, use ) => { - const testingPost = await requestUtils.createPostFromTemplate( - requestUtils, - { title: 'Product Filter Stock Status Block' }, - TEMPLATE_PATH, - {} - ); - - await use( testingPost ); - await requestUtils.deletePost( post.id ); - }, - - dropdownBlockPost: async ( { requestUtils }, use ) => { - const testingPost = await requestUtils.createPostFromTemplate( - requestUtils, - { title: 'Product Filter Stock Status Block' }, - TEMPLATE_PATH, - { - attributes: { - displayStyle: 'dropdown', - }, - } - ); - - await use( testingPost ); - await requestUtils.deletePost( post.id ); - }, -} ); -``` - -In your test you can navigate to the page. You won't need to clean it up, because -the fixture will take care of that for you. - -```js -test( 'Test the block', async ( { page, defaultBlockPost } ) => { - await page.goto( defaultBlockPost.link ); - // do your tests here -} ); -``` - -### Troubleshooting - -If you run into problems the first time you try to run the tests, please run the following command before starting the test suite: - -```sh -pnpm wp-env:config -``` - -This helps set up your environment correctly and can prevent some of the usual issues from happening. + ```sh + pnpm test:e2e --ui + ``` diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/filters-with-all-products.handlebars b/plugins/woocommerce-blocks/tests/e2e/content-templates/post_filters-with-all-products.handlebars similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/filters-with-all-products.handlebars rename to plugins/woocommerce-blocks/tests/e2e/content-templates/post_filters-with-all-products.handlebars diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/active-filters.handlebars b/plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_active-filters.handlebars similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/active-filters.handlebars rename to plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_active-filters.handlebars diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/attribute-filter.handlebars b/plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_attribute-filter.handlebars similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/attribute-filter.handlebars rename to plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_attribute-filter.handlebars diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/shared/filters-with-product-collection.handlebars b/plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_filters-with-product-collection.handlebars similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/shared/filters-with-product-collection.handlebars rename to plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_filters-with-product-collection.handlebars diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/price-filter.handlebars b/plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_price-filter.handlebars similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/price-filter.handlebars rename to plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_price-filter.handlebars diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/rating-filter.handlebars b/plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_rating-filter.handlebars similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/rating-filter.handlebars rename to plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_rating-filter.handlebars diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/stock-status.handlebars b/plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_stock-status.handlebars similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/stock-status.handlebars rename to plugins/woocommerce-blocks/tests/e2e/content-templates/template_archive-product_stock-status.handlebars diff --git a/plugins/woocommerce-blocks/tests/e2e/playwright-utils/index.ts b/plugins/woocommerce-blocks/tests/e2e/playwright-utils/index.ts deleted file mode 100644 index 607718c2a5c..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/playwright-utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './test'; diff --git a/plugins/woocommerce-blocks/tests/e2e/rules/no-raw-playwright-test-import.js b/plugins/woocommerce-blocks/tests/e2e/rules/no-raw-playwright-test-import.js index 7d3d214288d..676b73f0bf5 100644 --- a/plugins/woocommerce-blocks/tests/e2e/rules/no-raw-playwright-test-import.js +++ b/plugins/woocommerce-blocks/tests/e2e/rules/no-raw-playwright-test-import.js @@ -3,7 +3,7 @@ module.exports = { type: 'problem', docs: { description: - 'advise using @woocommerce/e2e-playwright-utils for importing test or expect functions', + 'advise using @woocommerce/e2e-utils for importing test or expect functions', category: 'Possible Errors', recommended: true, }, @@ -11,7 +11,7 @@ module.exports = { schema: [], messages: { unexpected: - "Prefer importing { test, expect } from '@woocommerce/e2e-playwright-utils'.", + "Prefer importing { test, expect } from '@woocommerce/e2e-utils'.", }, }, create( context ) { @@ -34,12 +34,12 @@ module.exports = { context.report( { node, message: - 'Import test or expect from @woocommerce/e2e-playwright-utils instead of @playwright/test for additional utilities.', + 'Import test or expect from @woocommerce/e2e-utils instead of @playwright/test for additional utilities.', fix( fixer ) { return [ fixer.replaceText( node.source, - "'@woocommerce/e2e-playwright-utils'" + "'@woocommerce/e2e-utils'" ), ]; }, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/add-to-cart-form/add-to-cart-form.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/add-to-cart-form/add-to-cart-form.block_theme.spec.ts index e7111e42cd1..5fbda7377fd 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/add-to-cart-form/add-to-cart-form.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/add-to-cart-form/add-to-cart-form.block_theme.spec.ts @@ -1,9 +1,12 @@ /** * External dependencies */ -import { BlockData } from '@woocommerce/e2e-types'; -import { expect, test } from '@woocommerce/e2e-playwright-utils'; -import { EditorUtils } from '@woocommerce/e2e-utils'; +import { + test as base, + expect, + Editor, + BlockData, +} from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -19,45 +22,62 @@ const blockData: BlockData = { }, }; -const configureSingleProductBlock = async ( editorUtils: EditorUtils ) => { - const singleProductBlock = await editorUtils.getBlockByName( - 'woocommerce/single-product' - ); +class BlockUtils { + editor: Editor; - await singleProductBlock.locator( 'input[type="radio"]' ).nth( 0 ).click(); + constructor( { editor }: { editor: Editor } ) { + this.editor = editor; + } - await singleProductBlock.getByText( 'Done' ).click(); -}; + async configureSingleProductBlock() { + const singleProductBlock = await this.editor.getBlockByName( + 'woocommerce/single-product' + ); + + await singleProductBlock + .locator( 'input[type="radio"]' ) + .nth( 0 ) + .click(); + + await singleProductBlock.getByText( 'Done' ).click(); + } +} + +const test = base.extend< { blockUtils: BlockUtils } >( { + blockUtils: async ( { editor }, use ) => { + await use( new BlockUtils( { editor } ) ); + }, +} ); test.describe( `${ blockData.name } Block`, () => { test( 'can be added in the Post Editor only as inner block of the Single Product Block', async ( { admin, editor, - editorUtils, + blockUtils, } ) => { // Add to Cart with Options in the Post Editor is only available as inner block of the Single Product Block. await admin.createNewPost(); await editor.insertBlock( { name: 'woocommerce/single-product' } ); - await configureSingleProductBlock( editorUtils ); + await blockUtils.configureSingleProductBlock(); await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toBeVisible(); // When the block is registered as ancestor, the function doesn't throw an error, but the block is not added. // So we check that only one instance of the block is present. await editor.insertBlock( { name: blockData.slug } ); await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toBeVisible(); } ); test( 'can be added in the Site Editor only as inner block of the Single Product Block - Product Catalog Template', async ( { admin, editor, - editorUtils, requestUtils, + blockUtils, } ) => { // Add to Cart with Options in the Site Editor is only available as // inner block of the Single Product Block except for the Single Product @@ -78,24 +98,23 @@ test.describe( `${ blockData.name } Block`, () => { await editor.insertBlock( { name: 'woocommerce/single-product' } ); - await configureSingleProductBlock( editorUtils ); + await blockUtils.configureSingleProductBlock(); await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toBeVisible(); // When the block is registered as ancestor, the function doesn't throw an error, but the block is not added. // So we check that only one instance of the block is present. await editor.insertBlock( { name: blockData.slug } ); await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toBeVisible(); } ); test( 'can be added in the Post Editor - Single Product Template', async ( { admin, editor, - editorUtils, requestUtils, } ) => { const template = await requestUtils.createTemplate( 'wp_template', { @@ -115,7 +134,7 @@ test.describe( `${ blockData.name } Block`, () => { await editor.insertBlock( { name: blockData.slug } ); await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toBeVisible(); } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts index 7746283097c..627261e1408 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -16,10 +16,10 @@ test.describe( `${ BLOCK_NAME } Block`, () => { } ); test( 'block can be inserted and it is rendered on the frontend', async ( { - editorUtils, + editor, page, } ) => { - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); await expect( page.locator( '.wc-block-grid__product.wc-block-layout' ) diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/all-reviews/all-reviews.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/all-reviews/all-reviews.block_theme.spec.ts index 2ee49976379..1376194c533 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/all-reviews/all-reviews.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/all-reviews/all-reviews.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -29,11 +29,11 @@ test.describe( `${ BLOCK_NAME } Block`, () => { test( 'block can be inserted and it sorts reviews by most recent by default', async ( { frontendUtils, page, - editorUtils, + editor, } ) => { await expect( page.getByText( allReviews[ 0 ].review ) ).toBeVisible(); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const block = await frontendUtils.getBlockByName( BLOCK_NAME ); const reviews = block.locator( @@ -46,9 +46,9 @@ test.describe( `${ BLOCK_NAME } Block`, () => { test( 'can sort by highest rating in the frontend', async ( { page, frontendUtils, - editorUtils, + editor, } ) => { - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const block = await frontendUtils.getBlockByName( BLOCK_NAME ); const reviews = block.locator( @@ -66,9 +66,9 @@ test.describe( `${ BLOCK_NAME } Block`, () => { test( 'can sort by lowest rating in the frontend', async ( { page, frontendUtils, - editorUtils, + editor, } ) => { - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const block = await frontendUtils.getBlockByName( BLOCK_NAME ); const reviews = block.locator( diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/attribute-filter.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/attribute-filter.block_theme.spec.ts index a964099229f..48a4941318d 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/attribute-filter.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/attribute-filter.block_theme.spec.ts @@ -1,15 +1,12 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { cli } from '@woocommerce/e2e-utils'; -import path from 'path'; - -const PRODUCT_CATALOG_LINK = '/shop'; -const TEMPLATE_PATH = path.join( - __dirname, - '../shared/filters-with-product-collection.handlebars' -); +import { + test as base, + expect, + cli, + TemplateCompiler, +} from '@woocommerce/e2e-utils'; const blockData = { name: 'Filter by Attribute', @@ -17,8 +14,17 @@ const blockData = { urlSearchParamWhenFilterIsApplied: 'filter_size=small&query_type_size=or', }; +const test = base.extend< { templateCompiler: TemplateCompiler } >( { + templateCompiler: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_filters-with-product-collection' + ); + await use( compiler ); + }, +} ); + test.describe( `${ blockData.name } Block`, () => { - test.beforeEach( async ( { admin, editor, editorUtils } ) => { + test.beforeEach( async ( { admin, editor } ) => { await admin.createNewPost(); await editor.insertBlock( { name: 'woocommerce/filter-wrapper', @@ -27,9 +33,7 @@ test.describe( `${ blockData.name } Block`, () => { heading: 'Filter By Attribute', }, } ); - const attributeFilter = await editorUtils.getBlockByName( - blockData.slug - ); + const attributeFilter = await editor.getBlockByName( blockData.slug ); await attributeFilter.getByText( 'Size' ).click(); await attributeFilter.getByText( 'Done' ).click(); @@ -49,12 +53,9 @@ test.describe( `${ blockData.name } Block`, () => { test( 'should allow changing the display style', async ( { page, - editorUtils, editor, } ) => { - const attributeFilter = await editorUtils.getBlockByName( - blockData.slug - ); + const attributeFilter = await editor.getBlockByName( blockData.slug ); await editor.selectBlocks( attributeFilter ); await expect( @@ -78,12 +79,9 @@ test.describe( `${ blockData.name } Block`, () => { test( 'should allow toggling the visibility of the filter button', async ( { page, - editorUtils, editor, } ) => { - const attributeFilter = await editorUtils.getBlockByName( - blockData.slug - ); + const attributeFilter = await editor.getBlockByName( blockData.slug ); await editor.selectBlocks( attributeFilter ); await expect( @@ -103,7 +101,7 @@ test.describe( `${ blockData.name } Block`, () => { } ); test.describe( `${ blockData.name } Block - with PHP classic template`, () => { - test.beforeEach( async ( { admin, page, editor, editorUtils } ) => { + test.beforeEach( async ( { admin, page, editor } ) => { await cli( 'npm run wp-env run tests-cli -- wp option update wc_blocks_use_blockified_product_grid_block_as_template false' ); @@ -113,7 +111,7 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.insertBlock( { name: 'woocommerce/filter-wrapper', attributes: { @@ -121,15 +119,13 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { heading: 'Filter By Attribute', }, } ); - const attributeFilter = await editorUtils.getBlockByName( - blockData.slug - ); + const attributeFilter = await editor.getBlockByName( blockData.slug ); await attributeFilter.getByText( 'Size' ).click(); await attributeFilter.getByText( 'Done' ).click(); await editor.saveSiteEditorEntities(); - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); } ); test( 'should show all products', async ( { frontendUtils, page } ) => { @@ -179,16 +175,10 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { } ); test.describe( `${ blockData.name } Block - with Product Collection`, () => { - test.beforeEach( async ( { requestUtils } ) => { - await requestUtils.updateTemplateContents( - 'woocommerce/woocommerce//archive-product', - TEMPLATE_PATH, - {} - ); - } ); + test( 'should show all products', async ( { page, templateCompiler } ) => { + await templateCompiler.compile(); - test( 'should show all products', async ( { page } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const products = page .locator( '.wp-block-woocommerce-product-template' ) .getByRole( 'listitem' ); @@ -198,8 +188,11 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { test( 'should show only products that match the filter', async ( { page, + templateCompiler, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await templateCompiler.compile(); + + await page.goto( '/shop' ); await page.getByRole( 'checkbox', { name: 'Small' } ).click(); await expect( page ).toHaveURL( @@ -217,15 +210,17 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { page, admin, editor, - editorUtils, + templateCompiler, } ) => { + const template = await templateCompiler.compile(); + await admin.visitSiteEditor( { - postId: 'woocommerce/woocommerce//archive-product', - postType: 'wp_template', + postId: template.id, + postType: template.type, } ); - await editorUtils.enterEditMode(); - const attributeFilterControl = await editorUtils.getBlockByName( + await editor.enterEditMode(); + const attributeFilterControl = await editor.getBlockByName( blockData.slug ); await expect( attributeFilterControl ).toBeVisible(); @@ -235,7 +230,7 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { await page.getByText( "Show 'Apply filters' button" ).click(); await editor.saveSiteEditorEntities(); - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); await page.getByRole( 'checkbox', { name: 'Small' } ).click(); await page.getByRole( 'button', { name: 'Apply' } ).click(); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/filter-products-by-attributes-count.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/filter-products-by-attributes-count.block_theme.spec.ts index 2bf401a6da3..1b55aba907c 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/filter-products-by-attributes-count.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/attributes-filter/filter-products-by-attributes-count.block_theme.spec.ts @@ -1,41 +1,30 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; -import { Post } from '@wordpress/e2e-test-utils-playwright/build-types/request-utils/posts'; -import path from 'path'; - -const TEMPLATE_PATH = path.join( - __dirname, - './filters-with-all-products.handlebars' -); +import { test as base, expect, PostCompiler } from '@woocommerce/e2e-utils'; const test = base.extend< { - defaultBlockPost: Post; + postCompiler: PostCompiler; } >( { - defaultBlockPost: async ( { requestUtils }, use ) => { - const testingPost = await requestUtils.createPostFromTemplate( - { title: 'Active Filters Block' }, - TEMPLATE_PATH, - {} + postCompiler: async ( { requestUtils }, use ) => { + const post = await requestUtils.createPostFromFile( + 'filters-with-all-products' ); - await use( testingPost ); - await requestUtils.deletePost( testingPost.id ); + await use( post ); }, } ); test.describe( 'Filter by Attributes Block - with All products Block', () => { test( 'should show correct attrs count (color=blue|query_type_color=or)', async ( { page, - defaultBlockPost, + postCompiler, } ) => { - await page.goto( - `${ defaultBlockPost.link }?filter_color=blue&query_type_color=or` - ); + const post = await postCompiler.compile( {} ); - // Check if the page has loaded successfully. - await expect( page.getByText( 'Active Filters block' ) ).toBeVisible(); + await page.goto( + `${ post.link }?filter_color=blue&query_type_color=or` + ); const expectedValues = [ '4', '2', '3', '4', '1' ]; @@ -51,14 +40,13 @@ test.describe( 'Filter by Attributes Block - with All products Block', () => { test( 'should show correct attrs count (color=blue,gray|query_type_color=or)', async ( { page, - defaultBlockPost, + postCompiler, } ) => { - await page.goto( - `${ defaultBlockPost.link }?filter_color=blue,gray&query_type_color=or` - ); + const post = await postCompiler.compile( {} ); - // Check if the page has loaded successfully. - await expect( page.getByText( 'Active Filters block' ) ).toBeVisible(); + await page.goto( + `${ post.link }?filter_color=blue,gray&query_type_color=or` + ); const expectedValues = [ '4', '2', '3', '4', '1' ]; @@ -74,14 +62,13 @@ test.describe( 'Filter by Attributes Block - with All products Block', () => { test( 'should show correct attrs count (color=blue|query_type_color=or|min_price=15|max_price=40)', async ( { page, - defaultBlockPost, + postCompiler, } ) => { - await page.goto( - `${ defaultBlockPost.link }?filter_color=blue&query_type_color=or&min_price=15&max_price=40` - ); + const post = await postCompiler.compile( {} ); - // Check if the page has loaded successfully. - await expect( page.getByText( 'Active Filters block' ) ).toBeVisible(); + await page.goto( + `${ post.link }?filter_color=blue&query_type_color=or&min_price=15&max_price=40` + ); const expectedValues = [ '2', '2', '2', '3', '1' ]; diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/basic.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/basic.block_theme.spec.ts index 6d6f2423a4b..c99e5903da2 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/basic.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/basic.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { customerFile, guestFile } from '@woocommerce/e2e-utils'; +import { test, expect, customerFile, guestFile } from '@woocommerce/e2e-utils'; test.describe( 'Basic role-based functionality tests', () => { test.describe( 'As admin', () => { diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/breadcrumbs/breadcrumbs.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/breadcrumbs/breadcrumbs.block_theme.spec.ts index 4c1fd276da2..43e0dd6126d 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/breadcrumbs/breadcrumbs.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/breadcrumbs/breadcrumbs.block_theme.spec.ts @@ -1,11 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; - -/** - * Internal dependencies - */ +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { slug: 'woocommerce/breadcrumbs', @@ -28,7 +24,6 @@ test.describe( `${ blockData.slug } Block`, () => { test( 'block can be inserted in the Site Editor', async ( { admin, requestUtils, - editorUtils, editor, } ) => { const template = await requestUtils.createTemplate( 'wp_template', { @@ -49,7 +44,7 @@ test.describe( `${ blockData.slug } Block`, () => { name: blockData.slug, } ); - const block = await editorUtils.getBlockByName( blockData.slug ); + const block = await editor.getBlockByName( blockData.slug ); await expect( block ).toHaveText( 'Breadcrumbs / Navigation / Path' ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.block_theme.spec.ts index 060ffcffc47..20e3f1b68ec 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { BlockData } from '@woocommerce/e2e-types'; -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect, BlockData } from '@woocommerce/e2e-utils'; const blockData: BlockData = { name: 'Cart', @@ -25,24 +24,22 @@ test.describe( 'Merchant β†’ Cart', () => { const blockSelectorInEditor = blockData.selectors.editor.block as string; test.describe( 'in page editor', () => { - test.beforeEach( async ( { editorUtils, admin } ) => { + test.beforeEach( async ( { editor, admin } ) => { await admin.visitSiteEditor( { postId: 'woocommerce/woocommerce//page-cart', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); } ); test( 'renders without crashing and can only be inserted once', async ( { page, - editorUtils, + editor, } ) => { - const blockPresence = await editorUtils.getBlockByName( - blockData.slug - ); + const blockPresence = await editor.getBlockByName( blockData.slug ); expect( blockPresence ).toBeTruthy(); - await editorUtils.openGlobalBlockInserter(); + await editor.openGlobalBlockInserter(); await page.getByPlaceholder( 'Search' ).fill( blockData.slug ); const cartBlockButton = page.getByRole( 'option', { name: blockData.name, @@ -57,7 +54,6 @@ test.describe( 'Merchant β†’ Cart', () => { test( 'inner blocks can be added/removed by filters', async ( { page, editor, - editorUtils, } ) => { // Begin by removing the block. await editor.selectBlocks( blockSelectorInEditor ); @@ -71,7 +67,7 @@ test.describe( 'Merchant β†’ Cart', () => { await removeButton.click(); // Expect block to have been removed. await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toHaveCount( 0 ); // Register a checkout filter to allow `core/table` block in the Checkout block's inner blocks, add @@ -91,7 +87,7 @@ test.describe( 'Merchant β†’ Cart', () => { await editor.insertBlock( { name: 'woocommerce/cart' } ); await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).not.toHaveCount( 0 ); // Select the cart-order-summary-block block and try to insert a block. Check the Table block is available. @@ -146,7 +142,6 @@ test.describe( 'Merchant β†’ Cart', () => { test( 'shows empty cart when changing the view', async ( { page, editor, - editorUtils, } ) => { await editor.selectBlocks( blockSelectorInEditor ); await editor.page @@ -160,10 +155,10 @@ test.describe( 'Merchant β†’ Cart', () => { await emptyCartButton.focus(); await emptyCartButton.dispatchEvent( 'click' ); - const filledCartBlock = await editorUtils.getBlockByName( + const filledCartBlock = await editor.getBlockByName( 'woocommerce/filled-cart-block' ); - const emptyCartBlock = await editorUtils.getBlockByName( + const emptyCartBlock = await editor.getBlockByName( 'woocommerce/empty-cart-block' ); await expect( filledCartBlock ).toBeHidden(); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.classic_theme.spec.ts index fbf6c227028..e880b607f4e 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.classic_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect, CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; test.describe( 'Merchant β†’ Cart', () => { test.beforeEach( async ( { requestUtils } ) => { @@ -11,17 +10,16 @@ test.describe( 'Merchant β†’ Cart', () => { test.describe( 'in widget editor', () => { test( "can't be inserted in a widget area", async ( { - editorUtils, - page, + admin, + editor, } ) => { - await page.goto( '/wp-admin/widgets.php' ); - await editorUtils.closeModalByName( 'Welcome to block Widgets' ); + await admin.visitWidgetEditor(); - await editorUtils.openGlobalBlockInserter(); - await editorUtils.page + await editor.openGlobalBlockInserter(); + await editor.page .getByLabel( 'Search for blocks and patterns' ) .fill( 'woocommerce/cart' ); - const cartButton = editorUtils.page.getByRole( 'option', { + const cartButton = editor.page.getByRole( 'option', { name: 'Cart', exact: true, } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.perf.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.perf.ts index 1d08ddaaa37..47c1cef3b1e 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.perf.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.perf.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.shopper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.shopper.block_theme.spec.ts index d3c24bb9a92..c14f07a4c6b 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.shopper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.shopper.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-coupons.shopper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-coupons.shopper.block_theme.spec.ts index 7d8555fc7c4..669b4b655f6 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-coupons.shopper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-coupons.shopper.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; -import { cli } from '@woocommerce/e2e-utils'; +import { expect, test as base, cli } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.block_theme.spec.ts index 48c5e901fcf..6b636b905c9 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.block_theme.spec.ts @@ -1,14 +1,16 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; import { + expect, + test as base, cli, BLOCK_THEME_SLUG, BLOCK_CHILD_THEME_WITH_BLOCK_NOTICES_FILTER_SLUG, BLOCK_CHILD_THEME_WITH_BLOCK_NOTICES_TEMPLATE_SLUG, BLOCK_CHILD_THEME_WITH_CLASSIC_NOTICES_TEMPLATE_SLUG, } from '@woocommerce/e2e-utils'; + /** * Internal dependencies */ diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.classic_theme.spec.ts index e4859030bc5..7bd2121db6a 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.classic_theme.spec.ts @@ -1,8 +1,9 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; import { + expect, + test as base, cli, CLASSIC_THEME_SLUG, CLASSIC_CHILD_THEME_WITH_CLASSIC_NOTICES_TEMPLATE_SLUG, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts index 1b3509b5829..98380a90726 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; -import { FrontendUtils } from '@woocommerce/e2e-utils'; +import { expect, test as base, FrontendUtils } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-taxes.shopper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-taxes.shopper.block_theme.spec.ts index d722467e412..a6e59899124 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-taxes.shopper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-taxes.shopper.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; +import { expect, test as base } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.spec.ts index 61f41393183..0f8106f943e 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; -import { cli } from '@woocommerce/e2e-utils'; +import { expect, test as base, cli } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/catalog-sorting/catalog-sorting.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/catalog-sorting/catalog-sorting.block_theme.spec.ts index d651717725b..14f70554551 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/catalog-sorting/catalog-sorting.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/catalog-sorting/catalog-sorting.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Catalog Sorting', @@ -25,7 +25,6 @@ test.describe( `${ blockData.slug } Block`, () => { test( 'block can be inserted in the Site Editor', async ( { admin, requestUtils, - editorUtils, editor, } ) => { const template = await requestUtils.createTemplate( 'wp_template', { @@ -46,7 +45,7 @@ test.describe( `${ blockData.slug } Block`, () => { name: blockData.slug, } ); - const block = await editorUtils.getBlockByName( blockData.slug ); + const block = await editor.getBlockByName( blockData.slug ); await expect( block ).toHaveText( 'Default sorting' ); } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.guest-shopper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.guest-shopper.block_theme.spec.ts index 54ffad7f4be..7a4d9042897 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.guest-shopper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.guest-shopper.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; -import { guestFile } from '@woocommerce/e2e-utils'; +import { expect, test as base, guestFile } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.merchant.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.merchant.block_theme.spec.ts index 2bfb45a8ac0..bdc9b0e03df 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.merchant.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.merchant.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; +import { expect, test as base } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.shopper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.shopper.block_theme.spec.ts index 5e488d4d198..6e377fe0965 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.shopper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.shopper.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; -import { customerFile } from '@woocommerce/e2e-utils'; +import { expect, test as base, customerFile } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.block_theme.spec.ts index 64242cc1a78..74bd07ee4f7 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { BlockData } from '@woocommerce/e2e-types'; -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; +import { test as base, expect, BlockData } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -42,32 +41,42 @@ test.describe( 'Merchant β†’ Checkout', () => { // `as string` is safe here because we know the variable is a string, it is defined above. const blockSelectorInEditor = blockData.selectors.editor.block as string; - test.beforeEach( async ( { editorUtils, admin, editor } ) => { + test.beforeEach( async ( { admin, editor } ) => { await admin.visitSiteEditor( { postId: 'woocommerce/woocommerce//page-checkout', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.openDocumentSettingsSidebar(); } ); test( 'renders without crashing and can only be inserted once', async ( { page, - editorUtils, editor, } ) => { - const blockPresence = await editorUtils.getBlockByName( - blockData.slug - ); + const blockPresence = await editor.getBlockByName( blockData.slug ); expect( blockPresence ).toBeTruthy(); - await editorUtils.openGlobalBlockInserter(); + await editor.openGlobalBlockInserter(); await page.getByPlaceholder( 'Search' ).fill( blockData.slug ); const checkoutBlockButton = page.getByRole( 'option', { name: blockData.name, exact: true, } ); - expect( await editorUtils.ensureNoErrorsOnBlockPage() ).toBe( true ); + + const errorMessages = [ + /This block contains unexpected or invalid content/gi, + /Your site doesn’t include support for/gi, + /There was an error whilst rendering/gi, + /This block has encountered an error and cannot be previewed/gi, + ]; + + for ( const errorMessage of errorMessages ) { + await expect( + editor.canvas.getByText( errorMessage ) + ).toBeHidden(); + } + await expect( editor.canvas.locator( blockSelectorInEditor ) ).toBeVisible(); @@ -140,7 +149,6 @@ test.describe( 'Merchant β†’ Checkout', () => { test( 'Merchant can see T&S and Privacy Policy links with checkbox', async ( { frontendUtils, checkoutPageObject, - editorUtils, admin, editor, } ) => { @@ -148,7 +156,7 @@ test.describe( 'Merchant β†’ Checkout', () => { postId: 'woocommerce/woocommerce//page-checkout', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.openDocumentSettingsSidebar(); await editor.selectBlocks( blockSelectorInEditor + @@ -191,7 +199,7 @@ test.describe( 'Merchant β†’ Checkout', () => { postId: 'woocommerce/woocommerce//page-checkout', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.openDocumentSettingsSidebar(); await editor.selectBlocks( blockSelectorInEditor + @@ -208,7 +216,6 @@ test.describe( 'Merchant β†’ Checkout', () => { test( 'inner blocks can be added/removed by filters', async ( { page, editor, - editorUtils, } ) => { // Begin by removing the block. await editor.selectBlocks( blockSelectorInEditor ); @@ -222,7 +229,7 @@ test.describe( 'Merchant β†’ Checkout', () => { await removeButton.click(); // Expect block to have been removed. await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toHaveCount( 0 ); // Register a checkout filter to allow `core/table` block in the Checkout block's inner blocks, add @@ -241,7 +248,7 @@ test.describe( 'Merchant β†’ Checkout', () => { await editor.insertBlock( { name: 'woocommerce/checkout' } ); await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).not.toHaveCount( 0 ); // Select the checkout-fields-block block and try to insert a block. Check the Table block is available. @@ -293,14 +300,11 @@ test.describe( 'Merchant β†’ Checkout', () => { await editor.selectBlocks( blockSelectorInEditor ); } ); - test( 'can enable dark mode inputs', async ( { - editorUtils, - page, - } ) => { + test( 'can enable dark mode inputs', async ( { editor, page } ) => { const toggleLabel = page.getByLabel( 'Dark mode inputs' ); await toggleLabel.check(); - const shippingAddressBlock = await editorUtils.getBlockByName( + const shippingAddressBlock = await editor.getBlockByName( 'woocommerce/checkout' ); @@ -320,14 +324,13 @@ test.describe( 'Merchant β†’ Checkout', () => { test( 'Company input visibility and optional and required can be toggled', async ( { editor, - editorUtils, } ) => { await editor.selectBlocks( blockSelectorInEditor + ' [data-type="woocommerce/checkout-shipping-address-block"]' ); - const shippingAddressBlock = await editorUtils.getBlockByName( + const shippingAddressBlock = await editor.getBlockByName( 'woocommerce/checkout-shipping-address-block' ); @@ -385,7 +388,7 @@ test.describe( 'Merchant β†’ Checkout', () => { ' [data-type="woocommerce/checkout-billing-address-block"]' ); - const billingAddressBlock = await editorUtils.getBlockByName( + const billingAddressBlock = await editor.getBlockByName( 'woocommerce/checkout-billing-address-block' ); @@ -438,14 +441,13 @@ test.describe( 'Merchant β†’ Checkout', () => { test( 'Apartment input visibility and optional and required can be toggled', async ( { editor, - editorUtils, } ) => { await editor.selectBlocks( blockSelectorInEditor + ' [data-type="woocommerce/checkout-shipping-address-block"]' ); - const shippingAddressBlock = await editorUtils.getBlockByName( + const shippingAddressBlock = await editor.getBlockByName( 'woocommerce/checkout-shipping-address-block' ); @@ -508,7 +510,7 @@ test.describe( 'Merchant β†’ Checkout', () => { ' [data-type="woocommerce/checkout-billing-address-block"]' ); - const billingAddressBlock = await editorUtils.getBlockByName( + const billingAddressBlock = await editor.getBlockByName( 'woocommerce/checkout-billing-address-block' ); @@ -573,14 +575,13 @@ test.describe( 'Merchant β†’ Checkout', () => { test( 'Phone input visibility and optional and required can be toggled', async ( { editor, - editorUtils, } ) => { await editor.selectBlocks( blockSelectorInEditor + ' [data-type="woocommerce/checkout-shipping-address-block"]' ); - const shippingAddressBlock = await editorUtils.getBlockByName( + const shippingAddressBlock = await editor.getBlockByName( 'woocommerce/checkout-shipping-address-block' ); @@ -632,7 +633,7 @@ test.describe( 'Merchant β†’ Checkout', () => { ' [data-type="woocommerce/checkout-billing-address-block"]' ); - const billingAddressBlock = await editorUtils.getBlockByName( + const billingAddressBlock = await editor.getBlockByName( 'woocommerce/checkout-billing-address-block' ); @@ -688,7 +689,6 @@ test.describe( 'Merchant β†’ Checkout', () => { test( 'Return to cart link is visible and can be toggled', async ( { editor, - editorUtils, } ) => { await editor.selectBlocks( `${ blockSelectorInEditor } .wp-block-woocommerce-checkout-actions-block` @@ -700,7 +700,7 @@ test.describe( 'Merchant β†’ Checkout', () => { { exact: true } ); await returnToCartLinkToggle.check(); - const shippingAddressBlock = await editorUtils.getBlockByName( + const shippingAddressBlock = await editor.getBlockByName( 'woocommerce/checkout-actions-block' ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.classic_theme.spec.ts index d49fc184eaf..3da342800ac 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.classic_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect, CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; test.describe( 'Merchant β†’ Checkout', () => { test.beforeEach( async ( { requestUtils } ) => { @@ -11,17 +10,15 @@ test.describe( 'Merchant β†’ Checkout', () => { test.describe( 'in widget editor', () => { test( "can't be inserted in a widget area", async ( { - editorUtils, - page, + admin, + editor, } ) => { - await page.goto( '/wp-admin/widgets.php' ); - await editorUtils.closeModalByName( 'Welcome to block Widgets' ); - - await editorUtils.openGlobalBlockInserter(); - await editorUtils.page + await admin.visitWidgetEditor(); + await editor.openGlobalBlockInserter(); + await editor.page .getByLabel( 'Search for blocks and patterns' ) .fill( 'woocommerce/checkout' ); - const checkoutButton = editorUtils.page.getByRole( 'option', { + const checkoutButton = editor.page.getByRole( 'option', { name: 'Checkout', exact: true, } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.spec.ts index 333717c0e17..64c6fd12405 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.spec.ts @@ -1,9 +1,13 @@ /** * External dependencies */ -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; -import { BlockData } from '@woocommerce/e2e-types'; -import { customerFile, guestFile } from '@woocommerce/e2e-utils'; +import { + expect, + test as base, + customerFile, + guestFile, + BlockData, +} from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -243,12 +247,12 @@ test.describe( 'Shopper β†’ Shipping and Billing Addresses', () => { // `as string` is safe here because we know the variable is a string, it is defined above. const blockSelectorInEditor = blockData.selectors.editor.block as string; - test.beforeEach( async ( { editor, admin, editorUtils, page } ) => { + test.beforeEach( async ( { admin, editor, page } ) => { await admin.visitSiteEditor( { postId: 'woocommerce/woocommerce//page-checkout', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.selectBlocks( blockSelectorInEditor + @@ -268,7 +272,7 @@ test.describe( 'Shopper β†’ Shipping and Billing Addresses', () => { 'div.wc-block-components-address-form__company' ) ).toBeVisible(); - await editorUtils.saveSiteEditorEntities(); + await editor.saveSiteEditorEntities(); } ); test( 'User can add postcodes for different countries', async ( { @@ -498,12 +502,7 @@ test.describe( 'Shopper β†’ Checkout Form Errors (guest user)', () => { test.describe( 'Billing Address Form', () => { const blockSelectorInEditor = blockData.selectors.editor.block as string; - test( 'Enable company field', async ( { - page, - editor, - admin, - editorUtils, - } ) => { + test( 'Enable company field', async ( { page, admin, editor } ) => { await admin.visitSiteEditor( { postId: 'woocommerce/woocommerce//page-checkout', postType: 'wp_template', @@ -526,7 +525,7 @@ test.describe( 'Billing Address Form', () => { const companyInput = editor.canvas.getByLabel( 'Company (optional)' ); await expect( companyInput ).toBeVisible(); - await editorUtils.saveSiteEditorEntities(); + await editor.saveSiteEditorEntities(); } ); test.describe( 'Guest user', () => { diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout.page.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout.page.ts index 0e81d082772..423a6dcc90e 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout.page.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout.page.ts @@ -2,7 +2,7 @@ * External dependencies */ import { Page } from '@playwright/test'; -import { expect } from '@woocommerce/e2e-playwright-utils'; +import { expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts index aed32c285ba..ddce320b46c 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; -import { guestFile } from '@woocommerce/e2e-utils'; +import { test as base, expect, guestFile } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -38,15 +37,15 @@ const test = base.extend< { pageObject: CheckoutPage } >( { } ); test.describe( 'Shopper β†’ Order Confirmation (logged in user)', () => { - test.beforeEach( async ( { admin, editorUtils, localPickupUtils } ) => { + test.beforeEach( async ( { admin, editor, localPickupUtils } ) => { await localPickupUtils.disableLocalPickup(); await admin.visitSiteEditor( { postId: 'woocommerce/woocommerce//order-confirmation', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); - await editorUtils.transformIntoBlocks(); + await editor.enterEditMode(); + await editor.transformIntoBlocks(); } ); test( 'Place order', async ( { diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/classic-template/classic-template.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/classic-template/classic-template.block_theme.spec.ts index 63898037d99..280113e3398 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/classic-template/classic-template.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/classic-template/classic-template.block_theme.spec.ts @@ -1,9 +1,7 @@ /** * External dependencies */ -import { BlockData } from '@woocommerce/e2e-types'; -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { cli } from '@woocommerce/e2e-utils'; +import { test, expect, cli, BlockData } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/customer-account/customer-account.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/customer-account/customer-account.block_theme.spec.ts index 436eca2ab2c..4e2d028aedd 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/customer-account/customer-account.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/customer-account/customer-account.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'woocommerce/customer-account', @@ -47,14 +47,13 @@ test.describe( `${ blockData.name } Block`, () => { editor, page, frontendUtils, - editorUtils, } ) => { - await admin.createNewPost( { legacyCanvas: true } ); + await admin.createNewPost(); await editor.insertBlock( { name: blockData.name } ); await selectTextOnlyOption( { page } ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); // We have specified the parent block name as 'main' to ensure that the // block is found within the main content area of the page and not the hooked block in the header. @@ -76,14 +75,13 @@ test.describe( `${ blockData.name } Block`, () => { editor, page, frontendUtils, - editorUtils, } ) => { - await admin.createNewPost( { legacyCanvas: true } ); + await admin.createNewPost(); await editor.insertBlock( { name: blockData.name } ); await selectIconOnlyOption( { page } ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); // We have specified the parent block name as 'main' to ensure that the // block is found within the main content area of the page and not the hooked block in the header. @@ -105,14 +103,13 @@ test.describe( `${ blockData.name } Block`, () => { editor, page, frontendUtils, - editorUtils, } ) => { - await admin.createNewPost( { legacyCanvas: true } ); + await admin.createNewPost(); await editor.insertBlock( { name: blockData.name } ); await selectIconAndTextOption( { page } ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); // We have specified the parent block name as 'main' to ensure that the // block is found within the main content area of the page and not the hooked block in the header. diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/featured-category/featured-category.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/featured-category/featured-category.block_theme.spec.ts index 91ec40f0d14..8fd407d67b8 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/featured-category/featured-category.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/featured-category/featured-category.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { slug: 'woocommerce/featured-category', @@ -9,17 +9,16 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await blockLocator.getByText( 'Music' ).click(); await blockLocator.getByText( 'Done' ).click(); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/featured-product/featured-product.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/featured-product/featured-product.block_theme.spec.ts index a2fda183feb..94657793414 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/featured-product/featured-product.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/featured-product/featured-product.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { slug: 'woocommerce/featured-product', @@ -9,17 +9,16 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await blockLocator.getByText( 'Album' ).click(); await blockLocator.getByText( 'Done' ).click(); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/active-filters.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/active-filters.block_theme.spec.ts index a7a3dbb5b65..b4c78fd0ab1 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/active-filters.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/active-filters.block_theme.spec.ts @@ -1,15 +1,16 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import path from 'path'; +import { TemplateCompiler, test as base, expect } from '@woocommerce/e2e-utils'; -/** - * Internal dependencies - */ -import { PRODUCT_CATALOG_LINK, PRODUCT_CATALOG_TEMPLATE_ID } from './constants'; - -const TEMPLATE_PATH = path.join( __dirname, './active-filters.handlebars' ); +const test = base.extend< { templateCompiler: TemplateCompiler } >( { + templateCompiler: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_active-filters' + ); + await use( compiler ); + }, +} ); test.describe( 'Product Filter: Active Filters Block', () => { test.describe( 'frontend', () => { @@ -17,17 +18,15 @@ test.describe( 'Product Filter: Active Filters Block', () => { await requestUtils.activatePlugin( 'woocommerce-blocks-test-enable-experimental-features' ); - await requestUtils.updateTemplateContents( - PRODUCT_CATALOG_TEMPLATE_ID, - TEMPLATE_PATH, - {} - ); } ); test( 'Without any filters selected, only a wrapper block is rendered', async ( { page, + templateCompiler, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await templateCompiler.compile(); + + await page.goto( '/shop' ); const locator = page.locator( '.wp-block-woocommerce-product-filter' @@ -41,8 +40,11 @@ test.describe( 'Product Filter: Active Filters Block', () => { test( 'With rating filters applied it shows the correct active filters', async ( { page, + templateCompiler, } ) => { - await page.goto( `${ PRODUCT_CATALOG_LINK }?rating_filter=1,2,5` ); + await templateCompiler.compile(); + + await page.goto( `${ '/shop' }?rating_filter=1,2,5` ); await expect( page.getByText( 'Rating:' ) ).toBeVisible(); await expect( page.getByText( 'Rated 1 out of 5' ) ).toBeVisible(); @@ -52,9 +54,12 @@ test.describe( 'Product Filter: Active Filters Block', () => { test( 'With stock filters applied it shows the correct active filters', async ( { page, + templateCompiler, } ) => { + await templateCompiler.compile(); + await page.goto( - `${ PRODUCT_CATALOG_LINK }?filter_stock_status=instock,onbackorder` + `${ '/shop' }?filter_stock_status=instock,onbackorder` ); await expect( page.getByText( 'Stock Status:' ) ).toBeVisible(); @@ -64,9 +69,12 @@ test.describe( 'Product Filter: Active Filters Block', () => { test( 'With attribute filters applied it shows the correct active filters', async ( { page, + templateCompiler, } ) => { + await templateCompiler.compile(); + await page.goto( - `${ PRODUCT_CATALOG_LINK }?filter_color=blue,gray&query_type_color=or` + `${ '/shop' }?filter_color=blue,gray&query_type_color=or` ); await expect( page.getByText( 'Color:' ) ).toBeVisible(); @@ -76,10 +84,11 @@ test.describe( 'Product Filter: Active Filters Block', () => { test( 'With price filters applied it shows the correct active filters', async ( { page, + templateCompiler, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?min_price=17&max_price=71` - ); + await templateCompiler.compile(); + + await page.goto( `${ '/shop' }?min_price=17&max_price=71` ); await expect( page.getByText( 'Price:' ) ).toBeVisible(); await expect( diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/attribute-filter.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/attribute-filter.block_theme.spec.ts index 090d7a07519..5b9cc809dfa 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/attribute-filter.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/attribute-filter.block_theme.spec.ts @@ -1,18 +1,9 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import path from 'path'; - -/** - * Internal dependencies - */ -import { PRODUCT_CATALOG_LINK, PRODUCT_CATALOG_TEMPLATE_ID } from './constants'; - -const TEMPLATE_PATH = path.join( __dirname, './attribute-filter.handlebars' ); +import { TemplateCompiler, test as base, expect } from '@woocommerce/e2e-utils'; const COLOR_ATTRIBUTE_VALUES = [ 'Blue', 'Gray', 'Green', 'Red', 'Yellow' ]; - const COLOR_ATTRIBUTES_WITH_COUNTS = [ 'Blue (4)', 'Gray (2)', @@ -21,27 +12,32 @@ const COLOR_ATTRIBUTES_WITH_COUNTS = [ 'Yellow (1)', ]; +const test = base.extend< { templateCompiler: TemplateCompiler } >( { + templateCompiler: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_attribute-filter' + ); + await use( compiler ); + }, +} ); + test.describe( 'Product Filter: Attribute Block', () => { test.describe( 'With default display style', () => { - test.beforeEach( async ( { requestUtils } ) => { + test.beforeEach( async ( { requestUtils, templateCompiler } ) => { await requestUtils.activatePlugin( 'woocommerce-blocks-test-enable-experimental-features' ); - await requestUtils.updateTemplateContents( - PRODUCT_CATALOG_TEMPLATE_ID, - TEMPLATE_PATH, - { - attributes: { - attributeId: 1, - }, - } - ); + await templateCompiler.compile( { + attributes: { + attributeId: 1, + }, + } ); } ); test( 'clear button is not shown on initial page load', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -51,7 +47,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'renders a checkbox list with the available attribute filters', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const attributes = page.locator( '.wc-block-components-checkbox__label' @@ -69,7 +65,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'filters the list of products by selecting an attribute', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const grayCheckbox = page.getByText( 'Gray' ); await grayCheckbox.click(); @@ -85,7 +81,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'clear button appears after a filter is applied', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const grayCheckbox = page.getByText( 'Gray' ); await grayCheckbox.click(); @@ -101,7 +97,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'clear button hides after deselecting all filters', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const grayCheckbox = page.getByText( 'Gray' ); await grayCheckbox.click(); @@ -119,7 +115,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'filters are cleared after clear button is clicked', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const grayCheckbox = page.getByText( 'Gray' ); await grayCheckbox.click(); @@ -142,26 +138,22 @@ test.describe( 'Product Filter: Attribute Block', () => { } ); test.describe( 'With show counts enabled', () => { - test.beforeEach( async ( { requestUtils } ) => { + test.beforeEach( async ( { requestUtils, templateCompiler } ) => { await requestUtils.activatePlugin( 'woocommerce-blocks-test-enable-experimental-features' ); - await requestUtils.updateTemplateContents( - PRODUCT_CATALOG_TEMPLATE_ID, - TEMPLATE_PATH, - { - attributes: { - attributeId: 1, - showCounts: true, - }, - } - ); + await templateCompiler.compile( { + attributes: { + attributeId: 1, + showCounts: true, + }, + } ); } ); test( 'Renders checkboxes with associated product counts', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const attributes = page.locator( '.wc-block-components-checkbox__label' @@ -178,26 +170,22 @@ test.describe( 'Product Filter: Attribute Block', () => { } ); test.describe( "With display style 'dropdown'", () => { - test.beforeEach( async ( { requestUtils } ) => { + test.beforeEach( async ( { requestUtils, templateCompiler } ) => { await requestUtils.activatePlugin( 'woocommerce-blocks-test-enable-experimental-features' ); - await requestUtils.updateTemplateContents( - PRODUCT_CATALOG_TEMPLATE_ID, - TEMPLATE_PATH, - { - attributes: { - attributeId: 1, - displayStyle: 'dropdown', - }, - } - ); + await templateCompiler.compile( { + attributes: { + attributeId: 1, + displayStyle: 'dropdown', + }, + } ); } ); test( 'clear button is not shown on initial page load', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -207,7 +195,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'renders a dropdown list with the available attribute filters', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const dropdownLocator = page.locator( '.wc-interactivity-dropdown' @@ -226,7 +214,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'Clicking a dropdown option should filter the displayed products', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const dropdownLocator = page.locator( '.wc-interactivity-dropdown' @@ -249,7 +237,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'clear button appears after a filter is applied', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const dropdownLocator = page.locator( '.wc-interactivity-dropdown' @@ -272,7 +260,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'clear button hides after deselecting all filters', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const dropdownLocator = page.locator( '.wc-interactivity-dropdown' @@ -302,7 +290,7 @@ test.describe( 'Product Filter: Attribute Block', () => { test( 'filters are cleared after clear button is clicked', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const dropdownLocator = page.locator( '.wc-interactivity-dropdown' diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/basic.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/basic.block_theme.spec.ts index a079fd774d1..e61c5a67253 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/basic.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/basic.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect } from '@woocommerce/e2e-utils'; const filterBlocks = [ { @@ -41,10 +41,10 @@ test.describe( 'Filter blocks registration', () => { test( 'Variations can be inserted through the inserter.', async ( { page, - editorUtils, + editor, } ) => { for ( const block of filterBlocks ) { - await editorUtils.insertBlockUsingGlobalInserter( block.title ); + await editor.insertBlockUsingGlobalInserter( block.title ); await expect( page.getByLabel( `Block: ${ block.title }` ) @@ -53,11 +53,11 @@ test.describe( 'Filter blocks registration', () => { } ); test( 'Each filter block comes with a default title', async ( { - editorUtils, + editor, page, } ) => { for ( const block of filterBlocks ) { - await editorUtils.insertBlockUsingGlobalInserter( block.title ); + await editor.insertBlockUsingGlobalInserter( block.title ); await expect( page diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/constants.ts b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/constants.ts deleted file mode 100644 index 4cfdb2028c8..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const PRODUCT_CATALOG_LINK = '/shop'; -export const PRODUCT_CATALOG_TEMPLATE_ID = - 'woocommerce/woocommerce//archive-product'; diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/price-filter.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/price-filter.block_theme.spec.ts index fa0e3036bd6..5172c32e94e 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/price-filter.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/price-filter.block_theme.spec.ts @@ -1,33 +1,30 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import path from 'path'; +import { TemplateCompiler, test as base, expect } from '@woocommerce/e2e-utils'; -/** - * Internal dependencies - */ -import { PRODUCT_CATALOG_LINK, PRODUCT_CATALOG_TEMPLATE_ID } from './constants'; - -const TEMPLATE_PATH = path.join( __dirname, './price-filter.handlebars' ); +const test = base.extend< { templateCompiler: TemplateCompiler } >( { + templateCompiler: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_price-filter' + ); + await use( compiler ); + }, +} ); test.describe( 'Product Filter: Price Filter Block', () => { test.describe( 'frontend', () => { - test.beforeEach( async ( { requestUtils } ) => { + test.beforeEach( async ( { requestUtils, templateCompiler } ) => { await requestUtils.activatePlugin( 'woocommerce-blocks-test-enable-experimental-features' ); - await requestUtils.updateTemplateContents( - PRODUCT_CATALOG_TEMPLATE_ID, - TEMPLATE_PATH, - {} - ); + await templateCompiler.compile(); } ); test( 'clear button is not shown on initial page load', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -37,9 +34,7 @@ test.describe( 'Product Filter: Price Filter Block', () => { test( 'With price filters applied it shows the correct price', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?min_price=20&max_price=67` - ); + await page.goto( '/shop?min_price=20&max_price=67' ); // Min price input field const leftInputContainer = page.locator( @@ -74,9 +69,7 @@ test.describe( 'Product Filter: Price Filter Block', () => { test( 'clear button appears after a filter is applied', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?min_price=20&max_price=67` - ); + await page.goto( '/shop?min_price=20&max_price=67' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -86,13 +79,11 @@ test.describe( 'Product Filter: Price Filter Block', () => { test( 'clear button hides after deselecting all filters', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?min_price=20&max_price=67` - ); + await page.goto( '/shop?min_price=20&max_price=67' ); - const defaultRange = await page + const defaultRange = ( await page .locator( '.wp-block-woocommerce-product-filter-price' ) - .getAttribute( 'data-wc-context' ); + .getAttribute( 'data-wc-context' ) ) as string; const defaultMinRange = JSON.parse( defaultRange ).minRange; const defaultMaxRange = JSON.parse( defaultRange ).maxRange; @@ -120,19 +111,17 @@ test.describe( 'Product Filter: Price Filter Block', () => { test( 'filters are cleared after clear button is clicked', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?min_price=20&max_price=67` - ); + await page.goto( '/shop?min_price=20&max_price=67' ); const button = page.getByRole( 'button', { name: 'Clear' } ); await button.click(); - await page.waitForURL( `${ PRODUCT_CATALOG_LINK }/` ); + await page.waitForURL( '/shop/' ); - const defaultRangePrice = await page + const defaultRangePrice = ( await page .locator( '.wp-block-woocommerce-product-filter-price' ) - .getAttribute( 'data-wc-context' ); + .getAttribute( 'data-wc-context' ) ) as string; const defaultMinRange = JSON.parse( defaultRangePrice ).minRange; const defaultMaxRange = JSON.parse( defaultRangePrice ).maxRange; @@ -146,9 +135,7 @@ test.describe( 'Product Filter: Price Filter Block', () => { test( 'Changes in the price input field triggers price slider updates', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?min_price=20&max_price=67` - ); + await page.goto( '/shop?min_price=20&max_price=67' ); // Min price input field const leftInputContainer = page.locator( @@ -187,9 +174,7 @@ test.describe( 'Product Filter: Price Filter Block', () => { test( 'Price input field rejects min price higher than max price', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?min_price=20&max_price=67` - ); + await page.goto( '/shop?min_price=20&max_price=67' ); // Min price input field const minPriceInput = page @@ -211,9 +196,7 @@ test.describe( 'Product Filter: Price Filter Block', () => { test( 'Price input field rejects max price lower than min price', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?min_price=20&max_price=67` - ); + await page.goto( '/shop?min_price=20&max_price=67' ); // Max price input field const maxPriceInput = page diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/rating-filter.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/rating-filter.block_theme.spec.ts index f6dad26fc0f..279fd391567 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/rating-filter.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/rating-filter.block_theme.spec.ts @@ -1,37 +1,34 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import path from 'path'; +import { TemplateCompiler, test as base, expect } from '@woocommerce/e2e-utils'; -/** - * Internal dependencies - */ -import { PRODUCT_CATALOG_LINK, PRODUCT_CATALOG_TEMPLATE_ID } from './constants'; - -const TEMPLATE_PATH = path.join( __dirname, './rating-filter.handlebars' ); +const test = base.extend< { templateCompiler: TemplateCompiler } >( { + templateCompiler: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_rating-filter' + ); + await use( compiler ); + }, +} ); test.describe( 'Product Filter: Rating Filter Block', () => { test.describe( 'frontend', () => { - test.beforeEach( async ( { requestUtils } ) => { + test.beforeEach( async ( { requestUtils, templateCompiler } ) => { await requestUtils.activatePlugin( 'woocommerce-blocks-test-enable-experimental-features' ); - await requestUtils.updateTemplateContents( - PRODUCT_CATALOG_TEMPLATE_ID, - TEMPLATE_PATH, - { - attributes: { - attributeId: 1, - }, - } - ); + await templateCompiler.compile( { + attributes: { + attributeId: 1, + }, + } ); } ); test( 'clear button is not shown on initial page load', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -41,7 +38,7 @@ test.describe( 'Product Filter: Rating Filter Block', () => { test( 'clear button appears after a filter is applied', async ( { page, } ) => { - await page.goto( `${ PRODUCT_CATALOG_LINK }?rating_filter=1` ); + await page.goto( '/shop?rating_filter=1' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -51,7 +48,7 @@ test.describe( 'Product Filter: Rating Filter Block', () => { test( 'clear button hides after deselecting all filters', async ( { page, } ) => { - await page.goto( `${ PRODUCT_CATALOG_LINK }?rating_filter=1` ); + await page.goto( '/shop?rating_filter=1' ); const ratingCheckboxes = page.getByLabel( /Checkbox: Rated \d out of 5/ @@ -67,7 +64,7 @@ test.describe( 'Product Filter: Rating Filter Block', () => { test( 'filters are cleared after clear button is clicked', async ( { page, } ) => { - await page.goto( `${ PRODUCT_CATALOG_LINK }?rating_filter=1` ); + await page.goto( '/shop?rating_filter=1' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -84,7 +81,7 @@ test.describe( 'Product Filter: Rating Filter Block', () => { test( 'Renders a checkbox list with the available ratings', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const ratingStars = page.getByLabel( /^Rated \d out of 5/ ); await expect( ratingStars ).toHaveCount( 2 ); @@ -103,7 +100,7 @@ test.describe( 'Product Filter: Rating Filter Block', () => { test( 'Selecting a checkbox filters down the products', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const ratingCheckboxes = page.getByLabel( /Checkbox: Rated \d out of 5/ diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/stock-status.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/stock-status.block_theme.spec.ts index 33e7bc7f0b9..86636c8db73 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/stock-status.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/filter-blocks/stock-status.block_theme.spec.ts @@ -1,33 +1,30 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import path from 'path'; +import { TemplateCompiler, test as base, expect } from '@woocommerce/e2e-utils'; -/** - * Internal dependencies - */ -import { PRODUCT_CATALOG_LINK, PRODUCT_CATALOG_TEMPLATE_ID } from './constants'; - -const TEMPLATE_PATH = path.join( __dirname, './stock-status.handlebars' ); +const test = base.extend< { templateCompiler: TemplateCompiler } >( { + templateCompiler: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_stock-status' + ); + await use( compiler ); + }, +} ); test.describe( 'Product Filter: Stock Status Block', () => { test.describe( 'With default display style', () => { - test.beforeEach( async ( { requestUtils } ) => { + test.beforeEach( async ( { requestUtils, templateCompiler } ) => { await requestUtils.activatePlugin( 'woocommerce-blocks-test-enable-experimental-features' ); - await requestUtils.updateTemplateContents( - PRODUCT_CATALOG_TEMPLATE_ID, - TEMPLATE_PATH, - {} - ); + await templateCompiler.compile(); } ); test( 'clear button is not shown on initial page load', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -37,7 +34,7 @@ test.describe( 'Product Filter: Stock Status Block', () => { test( 'renders a checkbox list with the available stock statuses', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const stockStatuses = page.locator( '.wc-block-components-checkbox__label' @@ -51,7 +48,7 @@ test.describe( 'Product Filter: Stock Status Block', () => { test( 'filters the list of products by selecting a stock status', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const outOfStockCheckbox = page.getByText( 'Out of stock' ); await outOfStockCheckbox.click(); @@ -67,7 +64,7 @@ test.describe( 'Product Filter: Stock Status Block', () => { test( 'clear button appears after a filter is applied', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const outOfStockCheckbox = page.getByText( 'Out of stock' ); await outOfStockCheckbox.click(); @@ -83,9 +80,7 @@ test.describe( 'Product Filter: Stock Status Block', () => { test( 'clear button hides after deselecting all filters', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?filter_stock_status=outofstock` - ); + await page.goto( '/shop?filter_stock_status=outofstock' ); const outOfStockCheckbox = page.getByText( 'Out of stock' ); await outOfStockCheckbox.click(); @@ -98,9 +93,7 @@ test.describe( 'Product Filter: Stock Status Block', () => { test( 'filters are cleared after clear button is clicked', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?filter_stock_status=outofstock` - ); + await page.goto( '/shop?filter_stock_status=outofstock' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -115,25 +108,21 @@ test.describe( 'Product Filter: Stock Status Block', () => { } ); test.describe( 'With dropdown display style', () => { - test.beforeEach( async ( { requestUtils } ) => { + test.beforeEach( async ( { requestUtils, templateCompiler } ) => { await requestUtils.activatePlugin( 'woocommerce-blocks-test-enable-experimental-features' ); - await requestUtils.updateTemplateContents( - PRODUCT_CATALOG_TEMPLATE_ID, - TEMPLATE_PATH, - { - attributes: { - displayStyle: 'dropdown', - }, - } - ); + await templateCompiler.compile( { + attributes: { + displayStyle: 'dropdown', + }, + } ); } ); test( 'clear button is not shown on initial page load', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const button = page.getByRole( 'button', { name: 'Clear' } ); @@ -143,7 +132,7 @@ test.describe( 'Product Filter: Stock Status Block', () => { test( 'a dropdown is displayed with the available stock statuses', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const dropdownLocator = page.locator( '.wc-interactivity-dropdown' @@ -159,7 +148,7 @@ test.describe( 'Product Filter: Stock Status Block', () => { test( 'clear button appears after a filter is applied', async ( { page, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const dropdownLocator = page.locator( '.wc-interactivity-dropdown' @@ -180,9 +169,7 @@ test.describe( 'Product Filter: Stock Status Block', () => { test( 'clear button hides after deselecting all filters', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?filter_stock_status=instock` - ); + await page.goto( '/shop?filter_stock_status=instock' ); const dropdownLocator = page.locator( '.wc-interactivity-dropdown' @@ -204,9 +191,7 @@ test.describe( 'Product Filter: Stock Status Block', () => { test( 'filters are cleared after clear button is clicked', async ( { page, } ) => { - await page.goto( - `${ PRODUCT_CATALOG_LINK }?filter_stock_status=instock` - ); + await page.goto( '/shop?filter_stock_status=instock' ); const button = page.getByRole( 'button', { name: 'Clear' } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/handpicked-products/handpicked-products.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/handpicked-products/handpicked-products.block_theme.spec.ts index b5545dc7ebe..58b3d2714e9 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/handpicked-products/handpicked-products.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/handpicked-products/handpicked-products.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Hand-picked Products', @@ -10,17 +10,16 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await blockLocator.getByText( 'Album' ).click(); await blockLocator.getByText( 'Done' ).click(); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.spec.ts index 285dbd131ba..231efbcd425 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -189,7 +189,6 @@ test.describe( 'Merchant β†’ Local Pickup Settings', () => { localPickupUtils, admin, editor, - editorUtils, frontendUtils, } ) => { // First update the title via the site editor then check the local pickup settings. @@ -197,7 +196,7 @@ test.describe( 'Merchant β†’ Local Pickup Settings', () => { postId: 'woocommerce/woocommerce//page-checkout', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); const block = editor.canvas.locator( '[data-type="woocommerce/checkout-shipping-method-block"]' ); @@ -227,7 +226,7 @@ test.describe( 'Merchant β†’ Local Pickup Settings', () => { postId: 'woocommerce/woocommerce//page-checkout', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await expect( editor.canvas.getByText( 'Edited from settings page' ) diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.block_theme.spec.ts index c1e56dd99dc..1950f0cb70e 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { BlockData } from '@woocommerce/e2e-types'; +import { test, expect, BlockData } from '@woocommerce/e2e-utils'; const blockData: BlockData = { name: 'Mini-Cart', @@ -19,16 +18,12 @@ const blockData: BlockData = { test.describe( 'Merchant β†’ Mini Cart', () => { test.describe( 'in FSE editor', () => { - test( 'can be inserted in FSE area', async ( { - editorUtils, - editor, - admin, - } ) => { + test( 'can be inserted in FSE area', async ( { editor, admin } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//single-product`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.setContent( '' ); @@ -38,19 +33,19 @@ test.describe( 'Merchant β†’ Mini Cart', () => { ).toBeVisible(); } ); - test( 'can only be inserted once', async ( { editorUtils, admin } ) => { + test( 'can only be inserted once', async ( { editor, admin } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//single-product`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); - await editorUtils.openGlobalBlockInserter(); + await editor.enterEditMode(); + await editor.openGlobalBlockInserter(); - await editorUtils.page + await editor.page .getByLabel( 'Search for blocks and patterns' ) .fill( blockData.slug ); - const miniCartButton = editorUtils.page.getByRole( 'option', { + const miniCartButton = editor.page.getByRole( 'option', { name: blockData.name, } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.classic_theme.spec.ts index 8200a9b4417..ff930da7e7f 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.classic_theme.spec.ts @@ -1,9 +1,12 @@ /** * External dependencies */ -import { CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; -import { expect, test } from '@woocommerce/e2e-playwright-utils'; -import { BlockData } from '@woocommerce/e2e-types'; +import { + expect, + test, + CLASSIC_THEME_SLUG, + BlockData, +} from '@woocommerce/e2e-utils'; const blockData: BlockData = { name: 'Mini-Cart', @@ -21,15 +24,18 @@ test.describe( 'Merchant β†’ Mini Cart', () => { } ); test.describe( 'in widget editor', () => { - test( 'can be inserted in a widget area', async ( { editorUtils } ) => { - await editorUtils.openWidgetEditor(); - await editorUtils.openGlobalBlockInserter(); + test( 'can be inserted in a widget area', async ( { + admin, + editor, + } ) => { + await admin.visitWidgetEditor(); + await editor.openGlobalBlockInserter(); - await editorUtils.page + await editor.page .getByLabel( 'Search for blocks and patterns' ) .fill( blockData.slug ); - const miniCartButton = editorUtils.page.getByRole( 'option', { + const miniCartButton = editor.page.getByRole( 'option', { name: blockData.name, exact: true, } ); @@ -39,18 +45,22 @@ test.describe( 'Merchant β†’ Mini Cart', () => { await miniCartButton.click(); await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toBeVisible(); } ); - test( 'can only be inserted once', async ( { editorUtils } ) => { - await editorUtils.openWidgetEditor(); - await editorUtils.openGlobalBlockInserter(); + test( 'can only be inserted once', async ( { + page, + admin, + editor, + } ) => { + await admin.visitWidgetEditor(); + await editor.openGlobalBlockInserter(); - await editorUtils.page + await editor.page .getByLabel( 'Search for blocks and patterns' ) .fill( blockData.slug ); - const miniCartButton = editorUtils.page.getByRole( 'option', { + const miniCartButton = page.getByRole( 'option', { name: blockData.name, exact: true, } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.shopper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.shopper.block_theme.spec.ts index 60b1395f6fe..6cde9f865ef 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.shopper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.shopper.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; -import { cli } from '@woocommerce/e2e-utils'; +import { expect, test, cli } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart.block_theme.spec.ts index d52d4c60eb0..8e123ab9ed2 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { BlockData } from '@woocommerce/e2e-types'; +import { test, expect, BlockData } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/utils.ts b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/utils.ts index a6efb31c44a..f3c0692401b 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/utils.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/utils.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { BlockData } from '@woocommerce/e2e-types'; -import { FrontendUtils } from '@woocommerce/e2e-utils'; +import { FrontendUtils, BlockData } from '@woocommerce/e2e-utils'; export const blockData: BlockData = { name: 'Mini-Cart', diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/on-sale-badge/on-sale-badge-single-product-template.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/on-sale-badge/on-sale-badge-single-product-template.block_theme.spec.ts index 5a494ac3b42..0da735fdcbf 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/on-sale-badge/on-sale-badge-single-product-template.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/on-sale-badge/on-sale-badge-single-product-template.block_theme.spec.ts @@ -1,8 +1,12 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; -import { EditorUtils, FrontendUtils } from '@woocommerce/e2e-utils'; +import { + test as base, + expect, + Editor, + FrontendUtils, +} from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -14,14 +18,12 @@ const blockData = { mainClass: '.wp-block-woocommerce-product-sale-badge', selectors: { frontend: { - productSaleBadge: '.wc-block-components-product-sale-badge', - productSaleBadgeContainer: - '.wp-block-woocommerce-product-sale-badge', + badge: '.wc-block-components-product-sale-badge', + badgeContainer: '.wp-block-woocommerce-product-sale-badge', }, editor: { - productSaleBadge: '.wc-block-components-product-sale-badge', - productSaleBadgeContainer: - '.wp-block-woocommerce-product-sale-badge', + badge: '.wc-block-components-product-sale-badge', + badgeContainer: '.wp-block-woocommerce-product-sale-badge', }, }, // This margin is applied via Block Styles to the product sale badge. It's necessary to take it into account when calculating the position of the badge. https://github.com/woocommerce/woocommerce-blocks/blob/445b9431ccba460f9badd41d52ed991958524e33/assets/js/blocks/product-gallery/edit.tsx/#L44-L53 @@ -31,65 +33,80 @@ const blockData = { productPageNotOnSale: '/product/album/', }; -const test = base.extend< { pageObject: ProductGalleryPage } >( { - pageObject: async ( { page, editor, frontendUtils, editorUtils }, use ) => { - const pageObject = new ProductGalleryPage( { - page, - editor, - frontendUtils, - editorUtils, - } ); - await use( pageObject ); +class BlockUtils { + editor: Editor; + frontendUtils: FrontendUtils; + + constructor( { + editor, + frontendUtils, + }: { + editor: Editor; + frontendUtils: FrontendUtils; + } ) { + this.editor = editor; + this.frontendUtils = frontendUtils; + } + + async getSaleBadgeBoundingClientRect( isFrontend: boolean ): Promise< { + badge: DOMRect; + badgeContainer: DOMRect; + } > { + const page = isFrontend ? this.frontendUtils.page : this.editor.canvas; + return { + badge: await page + .locator( + blockData.selectors[ isFrontend ? 'frontend' : 'editor' ] + .badge + ) + .first() + .evaluate( ( el ) => el.getBoundingClientRect() ), + badgeContainer: await page + .locator( + blockData.selectors[ isFrontend ? 'frontend' : 'editor' ] + .badgeContainer + ) + .first() + .evaluate( ( el ) => el.getBoundingClientRect() ), + }; + } +} + +const test = base.extend< { + pageObject: ProductGalleryPage; + blockUtils: BlockUtils; +} >( { + pageObject: async ( { page, editor, frontendUtils }, use ) => { + await use( + new ProductGalleryPage( { + page, + editor, + frontendUtils, + } ) + ); + }, + blockUtils: async ( { editor, frontendUtils }, use ) => { + await use( new BlockUtils( { editor, frontendUtils } ) ); }, } ); -const getBoundingClientRect = async ( { - frontendUtils, - editorUtils, - isFrontend, -}: { - frontendUtils: FrontendUtils; - editorUtils: EditorUtils; - isFrontend: boolean; -} ) => { - const page = isFrontend ? frontendUtils.page : editorUtils.editor.canvas; - return { - productSaleBadge: await page - .locator( - blockData.selectors[ isFrontend ? 'frontend' : 'editor' ] - .productSaleBadge - ) - .first() - .evaluate( ( el ) => el.getBoundingClientRect() ), - productSaleBadgeContainer: await page - .locator( - blockData.selectors[ isFrontend ? 'frontend' : 'editor' ] - .productSaleBadgeContainer - ) - .first() - .evaluate( ( el ) => el.getBoundingClientRect() ), - }; -}; test.describe( `${ blockData.name }`, () => { test.describe( `On the Single Product Template`, () => { - test.beforeEach( async ( { admin, editorUtils, editor } ) => { + test.beforeEach( async ( { admin, editor } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//${ blockData.slug }`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.setContent( '' ); } ); - test( 'should be rendered on the editor side', async ( { - editorUtils, - editor, - } ) => { + test( 'should be rendered on the editor side', async ( { editor } ) => { await editor.insertBlock( { name: 'woocommerce/product-gallery', } ); - const block = await editorUtils.getBlockByName( blockData.name ); + const block = await editor.getBlockByName( blockData.name ); await expect( block ).toBeVisible(); } ); @@ -138,12 +155,11 @@ test.describe( `${ blockData.name }`, () => { await expect( block ).toBeHidden(); } ); - test( 'should be aligned on the left', async ( { - frontendUtils, - editorUtils, + test( 'should be aligned to the left', async ( { editor, page, pageObject, + blockUtils, } ) => { await editor.openDocumentSettingsSidebar(); await editor.insertBlock( { @@ -152,43 +168,43 @@ test.describe( `${ blockData.name }`, () => { await pageObject.toggleFullScreenOnClickSetting( false ); - const block = await editorUtils.getBlockByName( blockData.name ); + const block = await editor.getBlockByName( blockData.name ); await block.click(); - await editorUtils.setAlignOption( 'Align Left' ); + await page.locator( "button[aria-label='Align']" ).click(); + await page.getByText( 'Align Left' ).click(); - const editorBoundingClientRect = await getBoundingClientRect( { - frontendUtils, - editorUtils, - isFrontend: false, - } ); + await expect + .poll( async () => { + const { badge, badgeContainer } = + await blockUtils.getSaleBadgeBoundingClientRect( + false + ); - expect( - editorBoundingClientRect.productSaleBadge.x - blockData.margin - ).toEqual( editorBoundingClientRect.productSaleBadgeContainer.x ); + return badge.x - badgeContainer.x; + } ) + .toEqual( blockData.margin ); await editor.saveSiteEditorEntities(); await page.goto( blockData.productPage ); - const clientBoundingClientRect = await getBoundingClientRect( { - frontendUtils, - editorUtils, - isFrontend: true, - } ); + await expect + .poll( async () => { + const { badge, badgeContainer } = + await blockUtils.getSaleBadgeBoundingClientRect( true ); - expect( - clientBoundingClientRect.productSaleBadge.x - blockData.margin - ).toEqual( clientBoundingClientRect.productSaleBadgeContainer.x ); + return badge.x - badgeContainer.x; + } ) + .toEqual( blockData.margin ); } ); - test( 'should be aligned on the center', async ( { - frontendUtils, - editorUtils, + test( 'should be aligned to the center', async ( { editor, page, pageObject, + blockUtils, } ) => { await editor.openDocumentSettingsSidebar(); await editor.insertBlock( { @@ -197,47 +213,43 @@ test.describe( `${ blockData.name }`, () => { await pageObject.toggleFullScreenOnClickSetting( false ); - const block = await editorUtils.getBlockByName( blockData.name ); + const block = await editor.getBlockByName( blockData.name ); await block.click(); - await editorUtils.setAlignOption( 'Align Center' ); + await page.locator( "button[aria-label='Align']" ).click(); + await page.getByText( 'Align Center' ).click(); - const editorBoundingClientRect = await getBoundingClientRect( { - frontendUtils, - editorUtils, - isFrontend: false, - } ); + await expect + .poll( async () => { + const { badge, badgeContainer } = + await blockUtils.getSaleBadgeBoundingClientRect( + false + ); - expect( - editorBoundingClientRect.productSaleBadge.right - ).toBeLessThan( - editorBoundingClientRect.productSaleBadgeContainer.right - ); + return badge.right < badgeContainer.right; + } ) + .toBe( true ); await editor.saveSiteEditorEntities(); await page.goto( blockData.productPage ); - const clientBoundingClientRect = await getBoundingClientRect( { - frontendUtils, - editorUtils, - isFrontend: true, - } ); + await expect + .poll( async () => { + const { badge, badgeContainer } = + await blockUtils.getSaleBadgeBoundingClientRect( true ); - expect( - clientBoundingClientRect.productSaleBadge.right - ).toBeLessThan( - clientBoundingClientRect.productSaleBadgeContainer.right - ); + return badge.right < badgeContainer.right; + } ) + .toBe( true ); } ); - test( 'should be aligned on the right by default', async ( { - frontendUtils, - editorUtils, + test( 'should be aligned to the right by default', async ( { editor, page, pageObject, + blockUtils, } ) => { await editor.openDocumentSettingsSidebar(); await editor.insertBlock( { @@ -245,35 +257,29 @@ test.describe( `${ blockData.name }`, () => { } ); await pageObject.toggleFullScreenOnClickSetting( false ); - const editorBoundingClientRect = await getBoundingClientRect( { - frontendUtils, - editorUtils, - isFrontend: false, - } ); + await expect + .poll( async () => { + const { badge, badgeContainer } = + await blockUtils.getSaleBadgeBoundingClientRect( + false + ); - expect( - editorBoundingClientRect.productSaleBadge.right + - blockData.margin - ).toEqual( - editorBoundingClientRect.productSaleBadgeContainer.right - ); + return badgeContainer.right - badge.right; + } ) + .toEqual( blockData.margin ); await editor.saveSiteEditorEntities(); await page.goto( blockData.productPage ); - const clientBoundingClientRect = await getBoundingClientRect( { - frontendUtils, - editorUtils, - isFrontend: true, - } ); + await expect + .poll( async () => { + const { badge, badgeContainer } = + await blockUtils.getSaleBadgeBoundingClientRect( true ); - expect( - clientBoundingClientRect.productSaleBadge.right + - blockData.margin - ).toEqual( - clientBoundingClientRect.productSaleBadgeContainer.right - ); + return badgeContainer.right - badge.right; + } ) + .toEqual( blockData.margin ); } ); } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/page-content-wrapper/page-content-wrapper.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/page-content-wrapper/page-content-wrapper.block_theme.spec.ts index 9c8923231ab..31a446e3215 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/page-content-wrapper/page-content-wrapper.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/page-content-wrapper/page-content-wrapper.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import type { FrontendUtils } from '@woocommerce/e2e-utils'; +import { test, expect, FrontendUtils } from '@woocommerce/e2e-utils'; // Instead of testing the block individually, we test the Cart and Checkout // templates, which make use of the block. @@ -41,7 +40,7 @@ for ( const template of templates ) { test( `the content of the ${ template.title } page is correctly rendered in the ${ template.title } template`, async ( { page, admin, - editorUtils, + editor, frontendUtils, requestUtils, } ) => { @@ -58,12 +57,17 @@ for ( const template of templates ) { page.locator( template.blockClassName ) ).toBeVisible(); - await editorUtils.editor.insertBlock( { + await editor.insertBlock( { name: 'core/paragraph', attributes: { content: userText }, } ); - await editorUtils.updatePost(); + await page.getByRole( 'button', { name: 'Update' } ).click(); + + await page + .getByRole( 'button', { name: 'Dismiss this notice' } ) + .filter( { hasText: 'updated' } ) + .waitFor(); // Verify edits are in the template when viewed from the frontend. await template.visitPage( { frontendUtils } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/price-filter/price-filter.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/price-filter/price-filter.block_theme.spec.ts index bcb89cdab53..d97615f67ff 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/price-filter/price-filter.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/price-filter/price-filter.block_theme.spec.ts @@ -1,17 +1,15 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { BASE_URL, cli } from '@woocommerce/e2e-utils'; -import path from 'path'; +import { + test as base, + expect, + TemplateCompiler, + BASE_URL, + cli, +} from '@woocommerce/e2e-utils'; -const PRODUCT_CATALOG_LINK = '/shop'; -const TEMPLATE_PATH = path.join( - __dirname, - '../shared/filters-with-product-collection.handlebars' -); - -export const blockData = { +const blockData = { slug: 'woocommerce/price-filter', name: 'Filter by Price', mainClass: '.wc-block-price-filter', @@ -24,6 +22,15 @@ export const blockData = { placeholderUrl: `${ BASE_URL }/wp-content/plugins/woocommerce/assets/images/placeholder.png`, }; +const test = base.extend< { templateCompiler: TemplateCompiler } >( { + templateCompiler: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_filters-with-product-collection' + ); + await use( compiler ); + }, +} ); + test.describe( `${ blockData.name } Block - editor side`, () => { test.beforeEach( async ( { admin, editor } ) => { await admin.createNewPost(); @@ -50,10 +57,9 @@ test.describe( `${ blockData.name } Block - editor side`, () => { test( 'should allow changing the display style', async ( { page, - editorUtils, editor, } ) => { - const priceFilterControls = await editorUtils.getBlockByName( + const priceFilterControls = await editor.getBlockByName( 'woocommerce/price-filter' ); await editor.selectBlocks( priceFilterControls ); @@ -90,10 +96,9 @@ test.describe( `${ blockData.name } Block - editor side`, () => { test( 'should allow toggling the visibility of the filter button', async ( { page, - editorUtils, editor, } ) => { - const priceFilterControls = await editorUtils.getBlockByName( + const priceFilterControls = await editor.getBlockByName( blockData.slug ); await editor.selectBlocks( priceFilterControls ); @@ -116,7 +121,7 @@ test.describe( `${ blockData.name } Block - editor side`, () => { test.describe( `${ blockData.name } Block - with All products Block`, () => { test.beforeEach( async ( { admin, page, editor } ) => { - await admin.createNewPost( { legacyCanvas: true } ); + await admin.createNewPost(); await editor.insertBlock( { name: 'woocommerce/all-products' } ); await editor.insertBlock( { name: 'woocommerce/filter-wrapper', @@ -220,7 +225,7 @@ test.describe( `${ blockData.name } Block - with All products Block`, () => { } ); } ); test.describe( `${ blockData.name } Block - with PHP classic template`, () => { - test.beforeEach( async ( { admin, page, editor, editorUtils } ) => { + test.beforeEach( async ( { admin, page, editor } ) => { await cli( 'npm run wp-env run tests-cli -- wp option update wc_blocks_use_blockified_product_grid_block_as_template false' ); @@ -230,7 +235,7 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.insertBlock( { name: 'woocommerce/filter-wrapper', @@ -240,7 +245,7 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { }, } ); await editor.saveSiteEditorEntities(); - await page.goto( `/shop` ); + await page.goto( '/shop' ); } ); test( 'should show all products', async ( { frontendUtils } ) => { @@ -283,16 +288,10 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { } ); test.describe( `${ blockData.name } Block - with Product Collection`, () => { - test.beforeEach( async ( { requestUtils } ) => { - await requestUtils.updateTemplateContents( - 'woocommerce/woocommerce//archive-product', - TEMPLATE_PATH, - {} - ); - } ); + test( 'should show all products', async ( { page, templateCompiler } ) => { + await templateCompiler.compile(); - test( 'should show all products', async ( { page } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const products = page .locator( '.wp-block-woocommerce-product-template' ) .getByRole( 'listitem' ); @@ -303,8 +302,11 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { test( 'should show only products that match the filter', async ( { page, frontendUtils, + templateCompiler, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await templateCompiler.compile(); + + await page.goto( '/shop' ); const maxPriceInput = page.getByRole( 'textbox', { name: 'Filter products by maximum price', } ); @@ -327,16 +329,18 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { page, admin, editor, - editorUtils, + templateCompiler, } ) => { + const template = await templateCompiler.compile(); + await admin.visitSiteEditor( { - postId: 'woocommerce/woocommerce//archive-product', - postType: 'wp_template', + postId: template.id, + postType: template.type, } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); - const priceFilterControls = await editorUtils.getBlockByName( + const priceFilterControls = await editor.getBlockByName( blockData.slug ); await expect( priceFilterControls ).toBeVisible(); @@ -345,7 +349,7 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { await page.getByText( "Show 'Apply filters' button" ).click(); await editor.saveSiteEditorEntities(); - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const maxPriceInput = page.getByRole( 'textbox', { name: 'Filter products by maximum price', diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-best-sellers/product-best-sellers.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-best-sellers/product-best-sellers.block_theme.spec.ts index 51ffeb25650..f2625fe67d1 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-best-sellers/product-best-sellers.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-best-sellers/product-best-sellers.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Best Selling Products', @@ -10,16 +10,15 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await expect( blockLocator.getByRole( 'listitem' ) ).toHaveCount( 9 ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.spec.ts index b94435d10a0..eebc3df8328 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts index 21dacd98971..7c7b1d538cb 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts @@ -1,8 +1,11 @@ /** * External dependencies */ -import { CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; -import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; +import { + expect, + test as base, + CLASSIC_THEME_SLUG, +} from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -11,16 +14,11 @@ import { blockData } from './utils'; import ProductCollectionPage from '../product-collection/product-collection.page'; const test = base.extend< { productCollectionPage: ProductCollectionPage } >( { - productCollectionPage: async ( - { page, admin, editor, templateApiUtils, editorUtils }, - use - ) => { + productCollectionPage: async ( { page, admin, editor }, use ) => { const pageObject = new ProductCollectionPage( { page, admin, editor, - templateApiUtils, - editorUtils, } ); await use( pageObject ); }, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/utils.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/utils.ts index cbfaa892a44..6ed0388ef0b 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/utils.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/utils.ts @@ -2,7 +2,7 @@ * External dependencies */ import { Page } from '@playwright/test'; -import { Admin } from '@wordpress/e2e-test-utils-playwright'; +import { Admin } from '@woocommerce/e2e-utils'; export const blockData = { name: 'Product Button', diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-categories/product-categories.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-categories/product-categories.block_theme.spec.ts index f3d37e9a2c6..98dc2ba72be 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-categories/product-categories.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-categories/product-categories.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Product Categories List', @@ -10,16 +10,15 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await expect( blockLocator.getByRole( 'listitem' ) ).toHaveCount( 6 ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-category/product-category.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-category/product-category.block_theme.spec.ts index 4c6d82ae2ac..ad3c4823778 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-category/product-category.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-category/product-category.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Products by Category', @@ -10,18 +10,17 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await blockLocator.getByText( 'Accessories' ).click(); await blockLocator.getByText( 'Done' ).click(); await expect( blockLocator.getByRole( 'listitem' ) ).toHaveCount( 5 ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/compatibility-layer.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/compatibility-layer.block_theme.spec.ts index 4fdf4ea5afc..025cc45c3c1 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/compatibility-layer.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/compatibility-layer.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -76,16 +76,11 @@ const multipleOccurrenceScenarios: Scenario[] = [ ]; const test = base.extend< { pageObject: ProductCollectionPage } >( { - pageObject: async ( - { page, admin, editor, templateApiUtils, editorUtils }, - use - ) => { + pageObject: async ( { page, admin, editor }, use ) => { const pageObject = new ProductCollectionPage( { page, admin, editor, - templateApiUtils, - editorUtils, } ); await use( pageObject ); }, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts index df09e303b8a..00fb7de1f0b 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts @@ -1,8 +1,8 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; -import type { Request } from '@playwright/test'; +import { Request } from '@playwright/test'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -10,12 +10,11 @@ import type { Request } from '@playwright/test'; import ProductCollectionPage, { SELECTORS } from './product-collection.page'; const test = base.extend< { pageObject: ProductCollectionPage } >( { - pageObject: async ( { page, admin, editor, editorUtils }, use ) => { + pageObject: async ( { page, admin, editor }, use ) => { const pageObject = new ProductCollectionPage( { page, admin, editor, - editorUtils, } ); await use( pageObject ); }, @@ -881,7 +880,6 @@ test.describe( 'Product Collection', () => { page, admin, editor, - editorUtils, pageObject, } ) => { await admin.createNewPost(); @@ -891,11 +889,11 @@ test.describe( 'Product Collection', () => { await expect( paginations ).toHaveCount( 1 ); - const siblingBlock = await editorUtils.getBlockByName( + const siblingBlock = await editor.getBlockByName( 'woocommerce/product-template' ); await editor.selectBlocks( siblingBlock ); - await editorUtils.insertBlockUsingGlobalInserter( 'Pagination' ); + await editor.insertBlockUsingGlobalInserter( 'Pagination' ); await expect( paginations ).toHaveCount( 2 ); } ); @@ -953,19 +951,31 @@ test.describe( 'Product Collection', () => { }; test( 'as product in specific Single Product template', async ( { + admin, page, pageObject, - editorUtils, + editor, } ) => { - const productName = 'Cap'; - const productSlug = 'cap'; + await admin.visitSiteEditor( { path: '/wp_template' } ); - await editorUtils.openSpecificProductTemplate( - productName, - productSlug - ); + await page + .getByRole( 'button', { name: 'Add New Template' } ) + .click(); + await page + .getByRole( 'button', { name: 'Single Item: Product' } ) + .click(); + await page + .getByRole( 'option', { + name: `Cap http://localhost:8889/product/cap/`, + } ) + .click(); + await page + .getByRole( 'button', { + name: 'Skip', + } ) + .click(); - await editorUtils.insertBlockUsingGlobalInserter( + await editor.insertBlockUsingGlobalInserter( pageObject.BLOCK_NAME ); @@ -984,7 +994,7 @@ test.describe( 'Product Collection', () => { } ); test( 'as category in Products by Category template', async ( { admin, - editorUtils, + editor, pageObject, page, } ) => { @@ -992,8 +1002,8 @@ test.describe( 'Product Collection', () => { postId: `woocommerce/woocommerce//taxonomy-product_cat`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); - await editorUtils.insertBlockUsingGlobalInserter( + await editor.enterEditMode(); + await editor.insertBlockUsingGlobalInserter( pageObject.BLOCK_NAME ); @@ -1013,7 +1023,7 @@ test.describe( 'Product Collection', () => { test( 'as tag in Products by Tag template', async ( { admin, - editorUtils, + editor, pageObject, page, } ) => { @@ -1021,8 +1031,8 @@ test.describe( 'Product Collection', () => { postId: `woocommerce/woocommerce//taxonomy-product_tag`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); - await editorUtils.insertBlockUsingGlobalInserter( + await editor.enterEditMode(); + await editor.insertBlockUsingGlobalInserter( pageObject.BLOCK_NAME ); @@ -1042,12 +1052,12 @@ test.describe( 'Product Collection', () => { test( 'as site in post', async ( { admin, - editorUtils, + editor, pageObject, page, } ) => { await admin.createNewPost(); - await editorUtils.insertBlockUsingGlobalInserter( + await editor.insertBlockUsingGlobalInserter( pageObject.BLOCK_NAME ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.page.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.page.ts index b89189a7e0d..a2ac4494329 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.page.ts @@ -2,8 +2,8 @@ * External dependencies */ import { Locator, Page } from '@playwright/test'; -import { EditorUtils } from '@woocommerce/e2e-utils'; -import { expect, Editor, Admin } from '@wordpress/e2e-test-utils-playwright'; +import { Editor, Admin, expect } from '@woocommerce/e2e-utils'; +import { BlockRepresentation } from '@wordpress/e2e-test-utils-playwright/build-types/editor/insert-block'; /** * Internal dependencies @@ -78,7 +78,6 @@ class ProductCollectionPage { private page: Page; private admin: Admin; private editor: Editor; - private editorUtils: EditorUtils; BLOCK_NAME = 'Product Collection'; productTemplate!: Locator; products!: Locator; @@ -92,17 +91,14 @@ class ProductCollectionPage { page, admin, editor, - editorUtils, }: { page: Page; admin: Admin; editor: Editor; - editorUtils: EditorUtils; } ) { this.page = page; this.admin = admin; this.editor = editor; - this.editorUtils = editorUtils; } async chooseCollectionInPost( collection?: Collections ) { @@ -165,6 +161,33 @@ class ProductCollectionPage { await this.refreshLocators( 'frontend' ); } + async replaceBlockByBlockName( name: string, nameToInsert: string ) { + await this.page.evaluate( + ( { name: _name, nameToInsert: _nameToInsert } ) => { + const blocks = window.wp.data + .select( 'core/block-editor' ) + .getBlocks(); + const firstMatchingBlock = blocks + .flatMap( + ( { + innerBlocks, + }: { + innerBlocks: BlockRepresentation[]; + } ) => innerBlocks + ) + .find( + ( block: BlockRepresentation ) => block.name === _name + ); + const { clientId } = firstMatchingBlock; + const block = window.wp.blocks.createBlock( _nameToInsert ); + window.wp.data + .dispatch( 'core/block-editor' ) + .replaceBlock( clientId, block ); + }, + { name, nameToInsert } + ); + } + async replaceProductsWithProductCollectionInTemplate( template: string, collection?: Collections @@ -174,23 +197,20 @@ class ProductCollectionPage { postType: 'wp_template', } ); - await this.editorUtils.enterEditMode(); + await this.editor.enterEditMode(); await expect( this.editor.canvas.locator( `[data-type="core/query"]` ) ).toBeVisible(); - await this.editorUtils.replaceBlockByBlockName( - 'core/query', - this.BLOCK_SLUG - ); + await this.replaceBlockByBlockName( 'core/query', this.BLOCK_SLUG ); await this.chooseCollectionInTemplate( collection ); await this.refreshLocators( 'editor' ); await this.editor.saveSiteEditorEntities(); } async goToProductCatalogFrontend() { - await this.page.goto( `/shop` ); + await this.page.goto( '/shop' ); await this.refreshLocators( 'frontend' ); } @@ -211,7 +231,7 @@ class ProductCollectionPage { postId: template, postType: 'wp_template', } ); - await this.editorUtils.enterEditMode(); + await this.editor.enterEditMode(); await this.editor.canvas.locator( 'body' ).click(); await this.insertProductCollection(); await this.chooseCollectionInTemplate( collection ); @@ -535,36 +555,31 @@ class ProductCollectionPage { name: string; attributes: object; } ) { - const productTemplate = await this.editorUtils.getBlockByName( + const productTemplate = await this.editor.getBlockByName( 'woocommerce/product-template' ); const productTemplateId = ( await productTemplate.getAttribute( 'data-block' ) ) ?? ''; await this.editor.selectBlocks( productTemplate ); - await this.editorUtils.insertBlock( - block, - undefined, - productTemplateId - ); + await this.editor.insertBlock( block, { clientId: productTemplateId } ); } async insertProductCollectionInSingleProductBlock() { await this.insertSingleProductBlock(); - const siblingBlock = await this.editorUtils.getBlockByName( + const siblingBlock = await this.editor.getBlockByName( 'woocommerce/product-price' ); const clientId = ( await siblingBlock.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = - ( await this.editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await this.editor.getBlockRootClientId( clientId ) ) ?? ''; await this.editor.selectBlocks( siblingBlock ); - await this.editorUtils.insertBlock( + await this.editor.insertBlock( { name: this.BLOCK_SLUG }, - undefined, - parentClientId + { clientId: parentClientId } ); } @@ -590,7 +605,7 @@ class ProductCollectionPage { */ private async insertSingleProductBlock() { await this.editor.insertBlock( { name: 'woocommerce/single-product' } ); - const singleProductBlock = await this.editorUtils.getBlockByName( + const singleProductBlock = await this.editor.getBlockByName( 'woocommerce/single-product' ); await singleProductBlock diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.block_theme.spec.ts index dd812fec861..d60ed222ad7 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -22,19 +22,18 @@ const blockData = { }; const test = base.extend< { pageObject: ProductFiltersPage } >( { - pageObject: async ( { page, editor, frontendUtils, editorUtils }, use ) => { + pageObject: async ( { page, editor, frontendUtils }, use ) => { const pageObject = new ProductFiltersPage( { page, editor, frontendUtils, - editorUtils, } ); await use( pageObject ); }, } ); test.describe( `${ blockData.name }`, () => { - test.beforeEach( async ( { admin, editorUtils, requestUtils } ) => { + test.beforeEach( async ( { admin, editor, requestUtils } ) => { await requestUtils.activatePlugin( 'woocommerce-blocks-test-enable-experimental-features' ); @@ -42,7 +41,7 @@ test.describe( `${ blockData.name }`, () => { postId: `woocommerce/woocommerce//${ blockData.slug }`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); } ); test( 'should be visible and contain correct inner blocks', async ( { diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.page.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.page.ts index 7d0aa4bda0f..e688c1b737d 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.page.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-filters/product-filters.page.ts @@ -2,29 +2,25 @@ * External dependencies */ import { Page } from '@playwright/test'; -import { EditorUtils, FrontendUtils } from '@woocommerce/e2e-utils'; -import { Editor } from '@wordpress/e2e-test-utils-playwright'; +import { Editor, FrontendUtils } from '@woocommerce/e2e-utils'; export class ProductFiltersPage { editor: Editor; page: Page; frontendUtils: FrontendUtils; - editorUtils: EditorUtils; constructor( { editor, page, frontendUtils, - editorUtils, }: { editor: Editor; page: Page; frontendUtils: FrontendUtils; - editorUtils: EditorUtils; } ) { this.editor = editor; this.page = page; this.frontendUtils = frontendUtils; - this.editorUtils = editorUtils; + this.editor = editor; } async addProductFiltersBlock( { cleanContent = true } ) { @@ -45,6 +41,6 @@ export class ProductFiltersPage { has: this.page.locator( ':visible' ), } ); } - return this.editorUtils.getBlockByName( blockName ); + return this.editor.getBlockByName( blockName ); } } diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/product-gallery-large-image-next-previous.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/product-gallery-large-image-next-previous.block_theme.spec.ts index 4e7f45b9880..585b4b416aa 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/product-gallery-large-image-next-previous.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/product-gallery-large-image-next-previous.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -75,24 +75,23 @@ const getBoundingClientRect = async ( { }; const test = base.extend< { pageObject: ProductGalleryPage } >( { - pageObject: async ( { page, editor, frontendUtils, editorUtils }, use ) => { + pageObject: async ( { page, editor, frontendUtils }, use ) => { const pageObject = new ProductGalleryPage( { page, editor, frontendUtils, - editorUtils, } ); await use( pageObject ); }, } ); test.describe( `${ blockData.name }`, () => { - test.beforeEach( async ( { admin, editorUtils } ) => { + test.beforeEach( async ( { admin, editor } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//${ blockData.slug }`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); } ); // eslint-disable-next-line playwright/no-skipped-test @@ -114,12 +113,11 @@ test.describe( `${ blockData.name }`, () => { // eslint-disable-next-line playwright/no-skipped-test test.skip( 'Renders Next/Previous Button block on the frontend side', async ( { admin, - editorUtils, editor, page, pageObject, } ) => { - await addBlock( admin, editor, editorUtils ); + await addBlock( admin, editor ); await editor.saveSiteEditorEntities(); @@ -137,11 +135,10 @@ test.describe( `${ blockData.name }`, () => { test.skip( 'Hide correctly the arrows', async ( { page, editor, - editorUtils, pageObject, admin, } ) => { - await addBlock( admin, editor, editorUtils ); + await addBlock( admin, editor ); await ( await pageObject.getNextPreviousButtonsBlock( { page: 'editor', @@ -179,11 +176,10 @@ test.describe( `${ blockData.name }`, () => { test.skip( 'Show button outside of the image', async ( { page, editor, - editorUtils, pageObject, } ) => { // Currently we are adding the block under the related products block, but in the future we have to add replace the product gallery block with this block. - const parentBlock = await editorUtils.getBlockByName( + const parentBlock = await editor.getBlockByName( 'woocommerce/product-image-gallery' ); const clientId = @@ -191,13 +187,12 @@ test.describe( `${ blockData.name }`, () => { ( await parentBlock.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = // eslint-disable-next-line playwright/no-conditional-in-test - ( await editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await editor.getBlockRootClientId( clientId ) ) ?? ''; await editor.selectBlocks( parentBlock ); - await editorUtils.insertBlock( + await editor.insertBlock( { name: 'woocommerce/product-gallery' }, - undefined, - parentClientId + { clientId: parentClientId } ); await ( await pageObject.getNextPreviousButtonsBlock( { @@ -253,11 +248,10 @@ test.describe( `${ blockData.name }`, () => { test.skip( 'Show button inside of the image', async ( { page, editor, - editorUtils, pageObject, } ) => { // Currently we are adding the block under the related products block, but in the future we have to add replace the product gallery block with this block. - const parentBlock = await editorUtils.getBlockByName( + const parentBlock = await editor.getBlockByName( 'woocommerce/product-image-gallery' ); const clientId = @@ -265,13 +259,12 @@ test.describe( `${ blockData.name }`, () => { ( await parentBlock.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = // eslint-disable-next-line playwright/no-conditional-in-test - ( await editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await editor.getBlockRootClientId( clientId ) ) ?? ''; await editor.selectBlocks( parentBlock ); - await editorUtils.insertBlock( + await editor.insertBlock( { name: 'woocommerce/product-gallery' }, - undefined, - parentClientId + { clientId: parentClientId } ); await ( await pageObject.getNextPreviousButtonsBlock( { @@ -327,11 +320,10 @@ test.describe( `${ blockData.name }`, () => { test.skip( 'Show buttons at the top of the image', async ( { page, editor, - editorUtils, pageObject, } ) => { // Currently we are adding the block under the related products block, but in the future we have to add replace the product gallery block with this block. - const parentBlock = await editorUtils.getBlockByName( + const parentBlock = await editor.getBlockByName( 'woocommerce/product-image-gallery' ); const clientId = @@ -339,13 +331,12 @@ test.describe( `${ blockData.name }`, () => { ( await parentBlock.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = // eslint-disable-next-line playwright/no-conditional-in-test - ( await editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await editor.getBlockRootClientId( clientId ) ) ?? ''; await editor.selectBlocks( parentBlock ); - await editorUtils.insertBlock( + await editor.insertBlock( { name: 'woocommerce/product-gallery' }, - undefined, - parentClientId + { clientId: parentClientId } ); await ( await pageObject.getNextPreviousButtonsBlock( { @@ -353,7 +344,10 @@ test.describe( `${ blockData.name }`, () => { } ) ).click(); - await editorUtils.setLayoutOption( 'Align Top' ); + await page + .locator( "button[aria-label='Change vertical alignment']" ) + .click(); + await page.getByText( 'Align Top' ).click(); const block = await pageObject.getNextPreviousButtonsBlock( { page: 'editor', @@ -381,11 +375,10 @@ test.describe( `${ blockData.name }`, () => { test.skip( 'Show buttons at the middle of the image', async ( { page, editor, - editorUtils, pageObject, } ) => { // Currently we are adding the block under the related products block, but in the future we have to add replace the product gallery block with this block. - const parentBlock = await editorUtils.getBlockByName( + const parentBlock = await editor.getBlockByName( 'woocommerce/product-image-gallery' ); const clientId = @@ -393,13 +386,12 @@ test.describe( `${ blockData.name }`, () => { ( await parentBlock.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = // eslint-disable-next-line playwright/no-conditional-in-test - ( await editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await editor.getBlockRootClientId( clientId ) ) ?? ''; await editor.selectBlocks( parentBlock ); - await editorUtils.insertBlock( + await editor.insertBlock( { name: 'woocommerce/product-gallery' }, - undefined, - parentClientId + { clientId: parentClientId } ); await ( await pageObject.getNextPreviousButtonsBlock( { @@ -407,7 +399,10 @@ test.describe( `${ blockData.name }`, () => { } ) ).click(); - await editorUtils.setLayoutOption( 'Align Middle' ); + await page + .locator( "button[aria-label='Change vertical alignment']" ) + .click(); + await page.getByText( 'Align Middle' ).click(); const block = await pageObject.getNextPreviousButtonsBlock( { page: 'editor', @@ -432,11 +427,10 @@ test.describe( `${ blockData.name }`, () => { test.skip( 'Show buttons at the bottom of the image by default', async ( { page, editor, - editorUtils, pageObject, } ) => { // Currently we are adding the block under the related products block, but in the future we have to add replace the product gallery block with this block. - const parentBlock = await editorUtils.getBlockByName( + const parentBlock = await editor.getBlockByName( 'woocommerce/product-image-gallery' ); const clientId = @@ -444,13 +438,12 @@ test.describe( `${ blockData.name }`, () => { ( await parentBlock.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = // eslint-disable-next-line playwright/no-conditional-in-test - ( await editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await editor.getBlockRootClientId( clientId ) ) ?? ''; await editor.selectBlocks( parentBlock ); - await editorUtils.insertBlock( + await editor.insertBlock( { name: 'woocommerce/product-gallery' }, - undefined, - parentClientId + { clientId: parentClientId } ); await ( await pageObject.getNextPreviousButtonsBlock( { diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/utils.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/utils.ts index 481f0bc07f5..b83719cdd04 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/utils.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/utils.ts @@ -1,19 +1,14 @@ /** * External dependencies */ -import { EditorUtils } from '@woocommerce/e2e-utils'; -import { Admin, Editor } from '@wordpress/e2e-test-utils-playwright'; +import { Admin, Editor } from '@woocommerce/e2e-utils'; -export const addBlock = async ( - admin: Admin, - editor: Editor, - editorUtils: EditorUtils -) => { +export const addBlock = async ( admin: Admin, editor: Editor ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//single-product`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.insertBlock( { name: 'woocommerce/product-gallery', diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts index 711de8dbe04..1fb615eb29f 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -19,24 +19,23 @@ const blockData = { }; const test = base.extend< { pageObject: ProductGalleryPage } >( { - pageObject: async ( { page, editor, frontendUtils, editorUtils }, use ) => { + pageObject: async ( { page, editor, frontendUtils }, use ) => { const pageObject = new ProductGalleryPage( { page, editor, frontendUtils, - editorUtils, } ); await use( pageObject ); }, } ); test.describe( `${ blockData.name }`, () => { - test.beforeEach( async ( { admin, editorUtils, editor } ) => { + test.beforeEach( async ( { admin, editor } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//${ blockData.slug }`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.openDocumentSettingsSidebar(); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-pager/product-gallery-pager.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-pager/product-gallery-pager.block_theme.spec.ts index 746cca37d22..f2779024d9b 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-pager/product-gallery-pager.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-pager/product-gallery-pager.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -32,24 +32,23 @@ const blockData = { }; const test = base.extend< { pageObject: ProductGalleryPage } >( { - pageObject: async ( { page, editor, frontendUtils, editorUtils }, use ) => { + pageObject: async ( { page, editor, frontendUtils }, use ) => { const pageObject = new ProductGalleryPage( { page, editor, frontendUtils, - editorUtils, } ); await use( pageObject ); }, } ); test.describe( `${ blockData.name }`, () => { - test.beforeEach( async ( { admin, editorUtils, editor } ) => { + test.beforeEach( async ( { admin, editor } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//${ blockData.slug }`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.openDocumentSettingsSidebar(); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-thumbnails/product-gallery-thumbnails.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-thumbnails/product-gallery-thumbnails.block_theme.spec.ts index b2afbbd07d8..6489dd44ea9 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-thumbnails/product-gallery-thumbnails.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-thumbnails/product-gallery-thumbnails.block_theme.spec.ts @@ -1,8 +1,8 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; import { Locator, Page } from '@playwright/test'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -36,12 +36,11 @@ const changeNumberOfThumbnailsInputValue = async ( }; const test = base.extend< { pageObject: ProductGalleryPage } >( { - pageObject: async ( { page, editor, frontendUtils, editorUtils }, use ) => { + pageObject: async ( { page, editor, frontendUtils }, use ) => { const pageObject = new ProductGalleryPage( { page, editor, frontendUtils, - editorUtils, } ); await use( pageObject ); }, @@ -64,7 +63,6 @@ test.describe( `${ blockData.name }`, () => { page, editor, pageObject, - editorUtils, frontendUtils, } ) => { await editor.insertBlock( { @@ -80,13 +78,10 @@ test.describe( `${ blockData.name }`, () => { // Test the default (left) position of thumbnails by cross-checking: // - The Gallery block has the classes "is-layout-flex" and "is-nowrap". // - The Thumbnails block has a lower index than the Large Image block. - - const groupBlock = ( - await editorUtils.getBlockByTypeWithParent( - 'core/group', - 'woocommerce/product-gallery' - ) - ).first(); + const groupBlock = editor.canvas + .locator( '[data-type="woocommerce/product-gallery"]' ) + .locator( '[data-type="core/group"]' ) + .first(); const groupBlockClassAttribute = await groupBlock.getAttribute( 'class' @@ -94,7 +89,7 @@ test.describe( `${ blockData.name }`, () => { expect( groupBlockClassAttribute ).toContain( 'is-layout-flex' ); expect( groupBlockClassAttribute ).toContain( 'is-nowrap' ); - const isThumbnailsBlockEarlier = await editorUtils.isBlockEarlierThan( + const isThumbnailsBlockEarlier = await editor.isBlockEarlierThan( groupBlock, 'woocommerce/product-gallery-thumbnails', 'core/group' @@ -158,11 +153,10 @@ test.describe( `${ blockData.name }`, () => { test( 'Position thumbnails on the left of the large image', async ( { page, editor, - editorUtils, frontendUtils, } ) => { // Currently we are adding the block under the legacy Product Image Gallery block, but in the future we have to add replace the product gallery block with this block. - const parentBlock = await editorUtils.getBlockByName( + const parentBlock = await editor.getBlockByName( 'woocommerce/product-image-gallery' ); const clientId = @@ -170,17 +164,14 @@ test.describe( `${ blockData.name }`, () => { ( await parentBlock.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = // eslint-disable-next-line playwright/no-conditional-in-test - ( await editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await editor.getBlockRootClientId( clientId ) ) ?? ''; await editor.selectBlocks( parentBlock ); - await editorUtils.insertBlock( + await editor.insertBlock( { name: 'woocommerce/product-gallery' }, - undefined, - parentClientId + { clientId: parentClientId } ); - await ( - await editorUtils.getBlockByName( blockData.name ) - ).click(); + await ( await editor.getBlockByName( blockData.name ) ).click(); await editor.openDocumentSettingsSidebar(); await page @@ -189,12 +180,10 @@ test.describe( `${ blockData.name }`, () => { ) .click(); - const groupBlock = ( - await editorUtils.getBlockByTypeWithParent( - 'core/group', - 'woocommerce/product-gallery' - ) - ).first(); + const groupBlock = editor.canvas + .locator( '[data-type="woocommerce/product-gallery"]' ) + .locator( '[data-type="core/group"]' ) + .first(); const groupBlockClassAttribute = await groupBlock.getAttribute( 'class' @@ -202,12 +191,11 @@ test.describe( `${ blockData.name }`, () => { expect( groupBlockClassAttribute ).toContain( 'is-layout-flex' ); expect( groupBlockClassAttribute ).toContain( 'is-nowrap' ); - const isThumbnailsBlockEarlier = - await editorUtils.isBlockEarlierThan( - groupBlock, - 'woocommerce/product-gallery-thumbnails', - 'core/group' - ); + const isThumbnailsBlockEarlier = await editor.isBlockEarlierThan( + groupBlock, + 'woocommerce/product-gallery-thumbnails', + 'core/group' + ); expect( isThumbnailsBlockEarlier ).toBe( true ); @@ -244,11 +232,10 @@ test.describe( `${ blockData.name }`, () => { test( 'Position thumbnails on the bottom of the large image', async ( { page, editor, - editorUtils, frontendUtils, } ) => { // Currently we are adding the block under the legacy Product Image Gallery block, but in the future we have to add replace the product gallery block with this block. - const parentBlock = await editorUtils.getBlockByName( + const parentBlock = await editor.getBlockByName( 'woocommerce/product-image-gallery' ); const clientId = @@ -256,17 +243,14 @@ test.describe( `${ blockData.name }`, () => { ( await parentBlock.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = // eslint-disable-next-line playwright/no-conditional-in-test - ( await editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await editor.getBlockRootClientId( clientId ) ) ?? ''; await editor.selectBlocks( parentBlock ); - await editorUtils.insertBlock( + await editor.insertBlock( { name: 'woocommerce/product-gallery' }, - undefined, - parentClientId + { clientId: parentClientId } ); - await ( - await editorUtils.getBlockByName( blockData.name ) - ).click(); + await ( await editor.getBlockByName( blockData.name ) ).click(); await editor.openDocumentSettingsSidebar(); await page @@ -275,12 +259,10 @@ test.describe( `${ blockData.name }`, () => { ) .click(); - const groupBlock = ( - await editorUtils.getBlockByTypeWithParent( - 'core/group', - 'woocommerce/product-gallery' - ) - ).first(); + const groupBlock = editor.canvas + .locator( '[data-type="woocommerce/product-gallery"]' ) + .locator( '[data-type="core/group"]' ) + .first(); const groupBlockClassAttribute = await groupBlock.getAttribute( 'class' @@ -288,12 +270,11 @@ test.describe( `${ blockData.name }`, () => { expect( groupBlockClassAttribute ).toContain( 'is-layout-flex' ); expect( groupBlockClassAttribute ).toContain( 'is-vertical' ); - const isThumbnailsBlockEarlier = - await editorUtils.isBlockEarlierThan( - groupBlock, - 'woocommerce/product-gallery-thumbnails', - 'core/group' - ); + const isThumbnailsBlockEarlier = await editor.isBlockEarlierThan( + groupBlock, + 'woocommerce/product-gallery-thumbnails', + 'core/group' + ); expect( isThumbnailsBlockEarlier ).toBe( false ); @@ -331,11 +312,10 @@ test.describe( `${ blockData.name }`, () => { test( 'Position thumbnails on the right of the large image', async ( { page, editor, - editorUtils, frontendUtils, } ) => { // Currently we are adding the block under the legacy Product Image Gallery block, but in the future we have to add replace the product gallery block with this block. - const parentBlock = await editorUtils.getBlockByName( + const parentBlock = await editor.getBlockByName( 'woocommerce/product-image-gallery' ); const clientId = @@ -343,17 +323,14 @@ test.describe( `${ blockData.name }`, () => { ( await parentBlock.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = // eslint-disable-next-line playwright/no-conditional-in-test - ( await editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await editor.getBlockRootClientId( clientId ) ) ?? ''; await editor.selectBlocks( parentBlock ); - await editorUtils.insertBlock( + await editor.insertBlock( { name: 'woocommerce/product-gallery' }, - undefined, - parentClientId + { clientId: parentClientId } ); - await ( - await editorUtils.getBlockByName( blockData.name ) - ).click(); + await ( await editor.getBlockByName( blockData.name ) ).click(); await editor.openDocumentSettingsSidebar(); await page @@ -362,12 +339,10 @@ test.describe( `${ blockData.name }`, () => { ) .click(); - const groupBlock = ( - await editorUtils.getBlockByTypeWithParent( - 'core/group', - 'woocommerce/product-gallery' - ) - ).first(); + const groupBlock = editor.canvas + .locator( '[data-type="woocommerce/product-gallery"]' ) + .locator( '[data-type="core/group"]' ) + .first(); const groupBlockClassAttribute = await groupBlock.getAttribute( 'class' @@ -375,12 +350,11 @@ test.describe( `${ blockData.name }`, () => { expect( groupBlockClassAttribute ).toContain( 'is-layout-flex' ); expect( groupBlockClassAttribute ).toContain( 'is-nowrap' ); - const isThumbnailsBlockEarlier = - await editorUtils.isBlockEarlierThan( - groupBlock, - 'woocommerce/product-gallery-thumbnails', - 'core/group' - ); + const isThumbnailsBlockEarlier = await editor.isBlockEarlierThan( + groupBlock, + 'woocommerce/product-gallery-thumbnails', + 'core/group' + ); expect( isThumbnailsBlockEarlier ).toBe( false ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.block_theme.spec.ts index 12d6c4e7fd0..735be577c5d 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.block_theme.spec.ts @@ -1,8 +1,8 @@ /** * External dependencies */ -import { test as base, expect } from '@woocommerce/e2e-playwright-utils'; import { Locator } from '@playwright/test'; +import { test as base, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -26,12 +26,11 @@ const blockData = { }; const test = base.extend< { pageObject: ProductGalleryPage } >( { - pageObject: async ( { page, editor, frontendUtils, editorUtils }, use ) => { + pageObject: async ( { page, editor, frontendUtils }, use ) => { const pageObject = new ProductGalleryPage( { page, editor, frontendUtils, - editorUtils, } ); await use( pageObject ); }, @@ -520,9 +519,9 @@ test.describe( `${ blockData.name }`, () => { test.describe( 'block availability', () => { test( 'should be available on the Single Product Template', async ( { page, - editorUtils, + editor, } ) => { - await editorUtils.openGlobalBlockInserter(); + await editor.openGlobalBlockInserter(); await page.getByRole( 'tab', { name: 'Blocks' } ).click(); const productGalleryBlockOption = page .getByRole( 'listbox', { name: 'WooCommerce' } ) @@ -533,15 +532,15 @@ test.describe( `${ blockData.name }`, () => { test( 'should be available on the Product Gallery template part', async ( { admin, - editorUtils, + editor, page, } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//product-gallery`, postType: 'wp_template_part', } ); - await editorUtils.enterEditMode(); - await editorUtils.openGlobalBlockInserter(); + await editor.enterEditMode(); + await editor.openGlobalBlockInserter(); await page.getByRole( 'tab', { name: 'Blocks' } ).click(); const productGalleryBlockOption = page .getByRole( 'listbox', { name: 'WooCommerce' } ) @@ -553,10 +552,10 @@ test.describe( `${ blockData.name }`, () => { test( 'should be hidden on the post editor', async ( { admin, page, - editorUtils, + editor, } ) => { await admin.createNewPost(); - await editorUtils.openGlobalBlockInserter(); + await editor.openGlobalBlockInserter(); const productGalleryBlockOption = page .getByRole( 'listbox', { name: 'WooCommerce' } ) .getByRole( 'option', { name: blockData.title } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.page.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.page.ts index f2dbe29f2ff..aa0697e7b29 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.page.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.page.ts @@ -2,8 +2,7 @@ * External dependencies */ import { Page } from '@playwright/test'; -import { EditorUtils, FrontendUtils } from '@woocommerce/e2e-utils'; -import { Editor } from '@wordpress/e2e-test-utils-playwright'; +import { Editor, FrontendUtils } from '@woocommerce/e2e-utils'; const selectors = { editor: { @@ -18,22 +17,19 @@ export class ProductGalleryPage { editor: Editor; page: Page; frontendUtils: FrontendUtils; - editorUtils: EditorUtils; constructor( { editor, page, frontendUtils, - editorUtils, }: { editor: Editor; page: Page; frontendUtils: FrontendUtils; - editorUtils: EditorUtils; } ) { this.editor = editor; this.page = page; this.frontendUtils = frontendUtils; - this.editorUtils = editorUtils; + this.editor = editor; } async addProductGalleryBlock( { cleanContent = true } ) { @@ -96,7 +92,7 @@ export class ProductGalleryPage { has: this.page.locator( ':visible' ), } ); } - return this.editorUtils.getBlockByName( blockName ); + return this.editor.getBlockByName( blockName ); } async getThumbnailsBlock( { page }: { page: 'frontend' | 'editor' } ) { @@ -108,7 +104,7 @@ export class ProductGalleryPage { has: this.page.locator( ':visible' ), } ); } - return this.editorUtils.getBlockByName( blockName ); + return this.editor.getBlockByName( blockName ); } async getNextPreviousButtonsBlock( { @@ -125,7 +121,7 @@ export class ProductGalleryPage { has: this.page.locator( ':visible' ), } ); } - return this.editorUtils.getBlockByName( blockName ); + return this.editor.getBlockByName( blockName ); } async getPagerBlock( { page }: { page: 'frontend' | 'editor' } ) { @@ -137,7 +133,7 @@ export class ProductGalleryPage { has: this.page.locator( ':visible' ), } ); } - return this.editorUtils.getBlockByName( blockName ); + return this.editor.getBlockByName( blockName ); } async getBlock( { page }: { page: 'frontend' | 'editor' } ) { @@ -149,7 +145,7 @@ export class ProductGalleryPage { has: this.page.locator( ':visible' ), } ); } - return this.editorUtils.getBlockByName( blockName ); + return this.editor.getBlockByName( blockName ); } async getAddToCartWithOptionsBlock( { @@ -165,6 +161,6 @@ export class ProductGalleryPage { has: this.page.locator( ':visible' ), } ); } - return this.editorUtils.getBlockByName( blockName ); + return this.editor.getBlockByName( blockName ); } } diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-new/product-new.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-new/product-new.block_theme.spec.ts index fd07d08980d..83bc00f9af4 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-new/product-new.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-new/product-new.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Newest Products', @@ -10,16 +10,15 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await expect( blockLocator.getByRole( 'listitem' ) ).toHaveCount( 9 ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-on-sale/product-on-sale.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-on-sale/product-on-sale.block_theme.spec.ts index 7d2ea007ab9..7b763b1f7b9 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-on-sale/product-on-sale.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-on-sale/product-on-sale.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'On Sale Products', @@ -10,16 +10,15 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await expect( blockLocator.getByRole( 'listitem' ) ).toHaveCount( 6 ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-results-count/product-results-count.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-results-count/product-results-count.block_theme.spec.ts index 9c6c36f8b0e..52a0b4b903f 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-results-count/product-results-count.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-results-count/product-results-count.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Product Results Count', @@ -25,7 +25,6 @@ test.describe( `${ blockData.slug } Block`, () => { test( 'block can be inserted in the Site Editor', async ( { admin, requestUtils, - editorUtils, editor, } ) => { const template = await requestUtils.createTemplate( 'wp_template', { @@ -46,7 +45,7 @@ test.describe( `${ blockData.slug } Block`, () => { name: blockData.slug, } ); - const block = await editorUtils.getBlockByName( blockData.slug ); + const block = await editor.getBlockByName( blockData.slug ); await expect( block ).toHaveText( 'Showing 1-X of X results' ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-tag/product-tag.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-tag/product-tag.block_theme.spec.ts index afb5ef3ef4d..ff3b61da936 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-tag/product-tag.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-tag/product-tag.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Products by Tag', @@ -10,18 +10,17 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await blockLocator.getByText( 'Recommended' ).click(); await blockLocator.getByText( 'Done' ).click(); await expect( blockLocator.getByRole( 'listitem' ) ).toHaveCount( 2 ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-top-rated/product-top-rated.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-top-rated/product-top-rated.block_theme.spec.ts index 3b2abd7d130..9098975fa10 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-top-rated/product-top-rated.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-top-rated/product-top-rated.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Top Rated Products', @@ -10,16 +10,15 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await expect( blockLocator.getByRole( 'listitem' ) ).toHaveCount( 9 ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/products-by-attribute/products-by-attribute.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/products-by-attribute/products-by-attribute.block_theme.spec.ts index c38c5d736d4..0ca735b4af8 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/products-by-attribute/products-by-attribute.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/products-by-attribute/products-by-attribute.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; const blockData = { name: 'Products by Attribute', @@ -10,18 +10,17 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'can be inserted in Post Editor and it is visible on the frontend', async ( { - editorUtils, editor, admin, frontendUtils, } ) => { await admin.createNewPost(); await editor.insertBlock( { name: blockData.slug } ); - const blockLocator = await editorUtils.getBlockByName( blockData.slug ); + const blockLocator = await editor.getBlockByName( blockData.slug ); await blockLocator.getByText( 'Color' ).click(); await blockLocator.getByText( 'Done' ).click(); await expect( blockLocator.getByRole( 'listitem' ) ).toHaveCount( 9 ); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const blockLocatorFrontend = await frontendUtils.getBlockByName( blockData.slug ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/products/products.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/products/products.block_theme.spec.ts index 4c2590b6bca..6d39647599f 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/products/products.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/products/products.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { BlockData } from '@woocommerce/e2e-types'; -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect, BlockData } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -14,6 +13,7 @@ import { const blockData: BlockData = { name: 'core/query', + slug: '', mainClass: '.wc-block-price-filter', selectors: { frontend: {}, @@ -58,7 +58,6 @@ const templates = { test.describe( `${ blockData.name } Block `, () => { test( 'when Inherit Query from template is enabled all the settings that customize the query should be hidden', async ( { admin, - editorUtils, editor, page, } ) => { @@ -69,7 +68,7 @@ test.describe( `${ blockData.name } Block `, () => { await editor.canvas.locator( 'body' ).click(); - const block = await editorUtils.getBlockByName( blockData.name ); + const block = await editor.getBlockByName( blockData.name ); await editor.selectBlocks( block ); await editor.openDocumentSettingsSidebar(); @@ -86,7 +85,6 @@ test.describe( `${ blockData.name } Block `, () => { } ); test( 'when Inherit Query from template is disabled all the settings that customize the query should be visble', async ( { admin, - editorUtils, editor, page, } ) => { @@ -97,7 +95,7 @@ test.describe( `${ blockData.name } Block `, () => { await editor.canvas.locator( 'body' ).click(); - const block = await editorUtils.getBlockByName( blockData.name ); + const block = await editor.getBlockByName( blockData.name ); await editor.selectBlocks( block ); await editor.openDocumentSettingsSidebar(); @@ -127,7 +125,6 @@ for ( const { admin, editor, page, - editorUtils, } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//${ slug }`, @@ -135,17 +132,16 @@ for ( const { } ); await editor.canvas.locator( 'body' ).click(); - const block = await editorUtils.getBlockByName( blockData.name ); + const block = await editor.getBlockByName( blockData.name ); // eslint-disable-next-line playwright/no-conditional-in-test const clientId = ( await block.getAttribute( 'data-block' ) ) ?? ''; const parentClientId = // eslint-disable-next-line playwright/no-conditional-in-test - ( await editorUtils.getBlockRootClientId( clientId ) ) ?? ''; + ( await editor.getBlockRootClientId( clientId ) ) ?? ''; await editor.selectBlocks( block ); - await editorUtils.insertBlock( + await editor.insertBlock( { name: legacyBlockName }, - undefined, - parentClientId + { clientId: parentClientId } ); await editor.saveSiteEditorEntities(); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/rating-filter/rating-filter.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/rating-filter/rating-filter.block_theme.spec.ts index 879dd550e35..0f0deedefa9 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/rating-filter/rating-filter.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/rating-filter/rating-filter.block_theme.spec.ts @@ -1,15 +1,12 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { cli } from '@woocommerce/e2e-utils'; -import path from 'path'; - -const PRODUCT_CATALOG_LINK = '/shop'; -const TEMPLATE_PATH = path.join( - __dirname, - '../shared/filters-with-product-collection.handlebars' -); +import { + test as base, + expect, + cli, + TemplateCompiler, +} from '@woocommerce/e2e-utils'; const blockData = { name: 'Filter by Rating', @@ -17,6 +14,15 @@ const blockData = { urlSearchParamWhenFilterIsApplied: 'rating_filter=1', }; +const test = base.extend< { templateCompiler: TemplateCompiler } >( { + templateCompiler: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_filters-with-product-collection' + ); + await use( compiler ); + }, +} ); + test.describe( `${ blockData.name } Block`, () => { test.beforeEach( async ( { admin, editor } ) => { await admin.createNewPost(); @@ -43,10 +49,9 @@ test.describe( `${ blockData.name } Block`, () => { test( 'should allow changing the display style', async ( { page, - editorUtils, editor, } ) => { - const stockFilter = await editorUtils.getBlockByName( blockData.slug ); + const stockFilter = await editor.getBlockByName( blockData.slug ); await editor.selectBlocks( stockFilter ); await expect( @@ -70,10 +75,9 @@ test.describe( `${ blockData.name } Block`, () => { test( 'should allow toggling the visibility of the filter button', async ( { page, - editorUtils, editor, } ) => { - const priceFilterControls = await editorUtils.getBlockByName( + const priceFilterControls = await editor.getBlockByName( blockData.slug ); await editor.selectBlocks( priceFilterControls ); @@ -95,7 +99,7 @@ test.describe( `${ blockData.name } Block`, () => { } ); test.describe( `${ blockData.name } Block - with PHP classic template`, () => { - test.beforeEach( async ( { admin, page, editor, editorUtils } ) => { + test.beforeEach( async ( { admin, page, editor } ) => { await cli( 'npm run wp-env run tests-cli -- wp option update wc_blocks_use_blockified_product_grid_block_as_template false' ); @@ -105,7 +109,7 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.insertBlock( { name: 'woocommerce/filter-wrapper', @@ -115,8 +119,10 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { }, } ); + await page.keyboard.press( 'Escape' ); await editor.saveSiteEditorEntities(); - await page.goto( `/shop` ); + + await page.goto( '/shop' ); } ); test( 'should show all products', async ( { frontendUtils, page } ) => { @@ -160,16 +166,10 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { } ); test.describe( `${ blockData.name } Block - with Product Collection`, () => { - test.beforeEach( async ( { requestUtils } ) => { - await requestUtils.updateTemplateContents( - 'woocommerce/woocommerce//archive-product', - TEMPLATE_PATH, - {} - ); - } ); + test( 'should show all products', async ( { page, templateCompiler } ) => { + await templateCompiler.compile(); - test( 'should show all products', async ( { page } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const products = page .locator( '.wp-block-woocommerce-product-template' ) .getByRole( 'listitem' ); @@ -179,8 +179,11 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { test( 'should show only products that match the filter', async ( { page, + templateCompiler, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await templateCompiler.compile(); + + await page.goto( '/shop' ); await page .getByRole( 'checkbox', { name: 'Rated 1 out of 5' } ) .click(); @@ -200,16 +203,18 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { page, admin, editor, - editorUtils, + templateCompiler, } ) => { + const template = await templateCompiler.compile(); + await admin.visitSiteEditor( { - postId: 'woocommerce/woocommerce//archive-product', - postType: 'wp_template', + postId: template.id, + postType: template.type, } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); - const ratingFilterControls = await editorUtils.getBlockByName( + const ratingFilterControls = await editor.getBlockByName( 'woocommerce/rating-filter' ); await expect( ratingFilterControls ).toBeVisible(); @@ -218,7 +223,7 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { await page.getByText( "Show 'Apply filters' button" ).click(); await editor.saveSiteEditorEntities(); - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); await page .getByRole( 'checkbox', { name: 'Rated 1 out of 5' } ) diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/related-products/related-products.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/related-products/related-products.block_theme.spec.ts index c481639cc13..040d35e72c0 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/related-products/related-products.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/related-products/related-products.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { BlockData } from '@woocommerce/e2e-types'; -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect, BlockData } from '@woocommerce/e2e-utils'; const blockData: BlockData = { name: 'Related Products', @@ -28,13 +27,12 @@ test.describe( `${ blockData.name } Block`, () => { test( "can't be added in the Post Editor - Product Catalog Template", async ( { admin, editor, - editorUtils, } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//archive-product`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.setContent( '' ); @@ -45,25 +43,24 @@ test.describe( `${ blockData.name } Block`, () => { } await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toBeHidden(); } ); test( 'can be added in the Post Editor - Single Product Template', async ( { admin, editor, - editorUtils, } ) => { await admin.visitSiteEditor( { postId: `woocommerce/woocommerce//single-product`, postType: 'wp_template', } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.setContent( '' ); await editor.insertBlock( { name: blockData.slug } ); await expect( - await editorUtils.getBlockByName( blockData.slug ) + await editor.getBlockByName( blockData.slug ) ).toBeVisible(); } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/reviews-by-category/reviews-by-category.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/reviews-by-category/reviews-by-category.block_theme.spec.ts index 1af3fad9001..40e317d4694 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/reviews-by-category/reviews-by-category.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/reviews-by-category/reviews-by-category.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -28,7 +28,7 @@ test.describe( `${ BLOCK_NAME } Block`, () => { test( 'block can be inserted and it successfully renders a review in the editor and the frontend', async ( { page, - editorUtils, + editor, } ) => { const categoryCheckbox = page.getByLabel( 'Clothing' ); await categoryCheckbox.check(); @@ -40,7 +40,7 @@ test.describe( `${ BLOCK_NAME } Block`, () => { page.getByText( hoodieReviews[ 0 ].review ) ).toBeVisible(); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); await expect( page.getByText( hoodieReviews[ 0 ].review ) @@ -50,9 +50,9 @@ test.describe( `${ BLOCK_NAME } Block`, () => { test( 'sorts by most recent review by default and can sort by highest rating', async ( { page, frontendUtils, - editorUtils, + editor, } ) => { - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const block = await frontendUtils.getBlockByName( BLOCK_NAME ); @@ -71,9 +71,9 @@ test.describe( `${ BLOCK_NAME } Block`, () => { test( 'can sort by lowest rating', async ( { page, frontendUtils, - editorUtils, + editor, } ) => { - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const block = await frontendUtils.getBlockByName( BLOCK_NAME ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/reviews-by-product/reviews-by-product.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/reviews-by-product/reviews-by-product.block_theme.spec.ts index dc637556b55..3f4c7d4165a 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/reviews-by-product/reviews-by-product.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/reviews-by-product/reviews-by-product.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -28,7 +28,7 @@ test.describe( `${ BLOCK_NAME } Block`, () => { test( 'block can be inserted and it successfully renders a review in the editor and the frontend', async ( { page, - editorUtils, + editor, } ) => { const productCheckbox = page.getByLabel( 'Hoodie, has 2 reviews' ); await productCheckbox.check(); @@ -41,7 +41,7 @@ test.describe( `${ BLOCK_NAME } Block`, () => { page.getByText( hoodieReviews[ 0 ].review ) ).toBeVisible(); - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); await expect( page.getByText( hoodieReviews[ 0 ].review ) @@ -51,9 +51,9 @@ test.describe( `${ BLOCK_NAME } Block`, () => { test( 'sorts by most recent by default and can sort by highest rating', async ( { page, frontendUtils, - editorUtils, + editor, } ) => { - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const block = await frontendUtils.getBlockByName( BLOCK_NAME ); const reviews = block.locator( @@ -71,9 +71,9 @@ test.describe( `${ BLOCK_NAME } Block`, () => { test( 'can sort by lowest rating', async ( { page, frontendUtils, - editorUtils, + editor, } ) => { - await editorUtils.publishAndVisitPost(); + await editor.publishAndVisitPost(); const block = await frontendUtils.getBlockByName( BLOCK_NAME ); const reviews = block.locator( diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/single-product-details/single-product-details.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/single-product-details/single-product-details.block_theme.spec.ts index 376b188e20f..967ddf62d00 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/single-product-details/single-product-details.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/single-product-details/single-product-details.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -28,7 +28,6 @@ test.describe( `${ blockData.slug } Block`, () => { test( 'block can be inserted in the Site Editor', async ( { admin, requestUtils, - editorUtils, editor, } ) => { const template = await requestUtils.createTemplate( 'wp_template', { @@ -50,7 +49,7 @@ test.describe( `${ blockData.slug } Block`, () => { name: blockData.slug, } ); - const block = await editorUtils.getBlockByName( blockData.slug ); + const block = await editor.getBlockByName( blockData.slug ); await expect( block ).toHaveText( /This block lists description, attributes and reviews for a single product./ diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/single-product-template/single-product-template-compatibility-layer.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/single-product-template/single-product-template-compatibility-layer.spec.ts index d7ab1345def..3f217007a50 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/single-product-template/single-product-template-compatibility-layer.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/single-product-template/single-product-template-compatibility-layer.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect } from '@woocommerce/e2e-utils'; /** * Internal dependencies diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/single-product-template/single-product-template.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/single-product-template/single-product-template.block_theme.spec.ts index bf8fc6aa377..767e122d684 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/single-product-template/single-product-template.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/single-product-template/single-product-template.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect } from '@woocommerce/e2e-utils'; const products = [ { diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/stock-filter/stock-filter.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/stock-filter/stock-filter.block_theme.spec.ts index 8d80411df6b..8c859626b8a 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/stock-filter/stock-filter.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/stock-filter/stock-filter.block_theme.spec.ts @@ -1,15 +1,12 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { cli } from '@woocommerce/e2e-utils'; -import path from 'path'; - -const PRODUCT_CATALOG_LINK = '/shop'; -const TEMPLATE_PATH = path.join( - __dirname, - '../shared/filters-with-product-collection.handlebars' -); +import { + test as base, + expect, + TemplateCompiler, + cli, +} from '@woocommerce/e2e-utils'; export const blockData = { name: 'Filter by Stock', @@ -17,6 +14,15 @@ export const blockData = { urlSearchParamWhenFilterIsApplied: 'filter_stock_status=outofstock', }; +const test = base.extend< { templateCompiler: TemplateCompiler } >( { + templateCompiler: async ( { requestUtils }, use ) => { + const compiler = await requestUtils.createTemplateFromFile( + 'archive-product_filters-with-product-collection' + ); + await use( compiler ); + }, +} ); + test.describe( `${ blockData.name } Block`, () => { test.beforeEach( async ( { admin, editor } ) => { await admin.createNewPost(); @@ -44,10 +50,9 @@ test.describe( `${ blockData.name } Block`, () => { test( 'should allow changing the display style', async ( { page, - editorUtils, editor, } ) => { - const stockFilter = await editorUtils.getBlockByName( blockData.slug ); + const stockFilter = await editor.getBlockByName( blockData.slug ); await editor.selectBlocks( stockFilter ); await expect( @@ -81,10 +86,9 @@ test.describe( `${ blockData.name } Block`, () => { test( 'should allow toggling the visibility of the filter button', async ( { page, - editorUtils, editor, } ) => { - const priceFilterControls = await editorUtils.getBlockByName( + const priceFilterControls = await editor.getBlockByName( blockData.slug ); await editor.selectBlocks( priceFilterControls ); @@ -114,14 +118,9 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { await admin.visitSiteEditor( { postId: 'woocommerce/woocommerce//archive-product', postType: 'wp_template', - canvas: 'edit', } ); - await editor.canvas - .locator( - '.wp-block-woocommerce-classic-template__placeholder-image' - ) - .waitFor(); + await editor.enterEditMode(); await editor.insertBlock( { name: 'woocommerce/filter-wrapper', @@ -131,7 +130,7 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { }, } ); await editor.saveSiteEditorEntities(); - await page.goto( `/shop` ); + await page.goto( '/shop' ); } ); test( 'should show all products', async ( { frontendUtils } ) => { @@ -175,16 +174,10 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => { } ); test.describe( `${ blockData.name } Block - with Product Collection`, () => { - test.beforeEach( async ( { requestUtils } ) => { - await requestUtils.updateTemplateContents( - 'woocommerce/woocommerce//archive-product', - TEMPLATE_PATH, - {} - ); - } ); + test( 'should show all products', async ( { page, templateCompiler } ) => { + await templateCompiler.compile(); - test( 'should show all products', async ( { page } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); const products = page .locator( '.wp-block-woocommerce-product-template' ) .getByRole( 'listitem' ); @@ -194,8 +187,11 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { test( 'should show only products that match the filter', async ( { page, + templateCompiler, } ) => { - await page.goto( PRODUCT_CATALOG_LINK ); + await templateCompiler.compile(); + + await page.goto( '/shop' ); await page.getByText( 'Out of Stock' ).click(); await expect( page ).toHaveURL( @@ -213,15 +209,17 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { page, admin, editor, - editorUtils, + templateCompiler, } ) => { - await admin.visitSiteEditor( { - postId: 'woocommerce/woocommerce//archive-product', - postType: 'wp_template', - } ); + const template = await templateCompiler.compile(); - await editorUtils.enterEditMode(); - const stockFilterControls = await editorUtils.getBlockByName( + await admin.visitSiteEditor( { + postId: template.id, + postType: template.type, + } ); + await editor.enterEditMode(); + + const stockFilterControls = await editor.getBlockByName( blockData.slug ); await expect( stockFilterControls ).toBeVisible(); @@ -229,7 +227,7 @@ test.describe( `${ blockData.name } Block - with Product Collection`, () => { await editor.openDocumentSettingsSidebar(); await page.getByText( "Show 'Apply filters' button" ).click(); await editor.saveSiteEditorEntities(); - await page.goto( PRODUCT_CATALOG_LINK ); + await page.goto( '/shop' ); await page.getByText( 'Out of Stock' ).click(); await page.getByRole( 'button', { name: 'Apply' } ).click(); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/store-notices/store-notices.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/store-notices/store-notices.block_theme.spec.ts index 4f43670468e..5abe85d3435 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/store-notices/store-notices.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/store-notices/store-notices.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { expect, test } from '@woocommerce/e2e-playwright-utils'; +import { expect, test } from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -14,15 +14,15 @@ const blockData = { test.describe( `${ blockData.slug } Block`, () => { test( 'should be visible on the Product Catalog template', async ( { - editorUtils, + editor, admin, } ) => { await admin.visitSiteEditor( { postId: 'woocommerce/woocommerce//archive-product', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); - const block = await editorUtils.getBlockByName( blockData.slug ); + await editor.enterEditMode(); + const block = await editor.getBlockByName( blockData.slug ); await expect( block ).toBeVisible(); await expect( block ).toHaveText( 'Notices added by WooCommerce or extensions will show up here.' diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/cart-template.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/cart-template.block_theme.spec.ts index 254b965f97c..2df89cbd81a 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/cart-template.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/cart-template.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect } from '@woocommerce/e2e-utils'; const permalink = '/cart'; const templatePath = 'woocommerce/woocommerce//page-cart'; @@ -11,13 +11,12 @@ test.describe( 'Test the cart template', () => { test( 'Template can be opened in the site editor', async ( { admin, editor, - editorUtils, } ) => { await admin.visitSiteEditor( { postId: templatePath, postType: templateType, } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await expect( editor.canvas.getByLabel( 'Block: Title' ) ).toBeVisible(); @@ -27,13 +26,12 @@ test.describe( 'Test the cart template', () => { admin, editor, page, - editorUtils, } ) => { await admin.visitSiteEditor( { path: '/page' } ); await editor.page .getByRole( 'button', { name: 'Cart', exact: true } ) .click(); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await expect( editor.canvas.locator( 'h1:has-text("Cart")' ).first() @@ -60,14 +58,13 @@ test.describe( 'Test the cart template', () => { test.describe( 'Test editing the cart template', () => { test( 'Merchant can transform shortcode block into blocks', async ( { admin, - editorUtils, editor, } ) => { await admin.visitSiteEditor( { postId: templatePath, postType: templateType, } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.setContent( '' ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/checkout-template.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/checkout-template.block_theme.spec.ts index a615feacf2d..b2b845cc4fd 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/checkout-template.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/checkout-template.block_theme.spec.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect } from '@woocommerce/e2e-utils'; const permalink = '/checkout'; const templatePath = 'woocommerce/woocommerce//page-checkout'; @@ -11,13 +11,12 @@ test.describe( 'Test the checkout template', () => { test( 'Template can be opened in the site editor', async ( { admin, editor, - editorUtils, } ) => { await admin.visitSiteEditor( { postId: templatePath, postType: templateType, } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await expect( editor.canvas.getByRole( 'button', { name: 'Place Order Β· ', @@ -29,7 +28,6 @@ test.describe( 'Test the checkout template', () => { admin, editor, page, - editorUtils, } ) => { await admin.visitSiteEditor( { postId: templatePath, @@ -39,7 +37,7 @@ test.describe( 'Test the checkout template', () => { await editor.page .getByRole( 'button', { name: 'Checkout', exact: true } ) .click(); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await expect( editor.canvas.getByRole( 'button', { @@ -78,14 +76,13 @@ test.describe( 'Test the checkout template', () => { test.describe( 'Test editing the checkout template', () => { test( 'Merchant can transform shortcode block into blocks', async ( { admin, - editorUtils, editor, } ) => { await admin.visitSiteEditor( { postId: templatePath, postType: templateType, } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); await editor.setContent( '' ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/constants.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/constants.ts index 236814bc3b1..e06e5a9a8ed 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/constants.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/constants.ts @@ -9,7 +9,6 @@ import type { FrontendUtils } from '@woocommerce/e2e-utils'; */ import { SIMPLE_VIRTUAL_PRODUCT_NAME } from '../checkout/constants'; import { CheckoutPage } from '../checkout/checkout.page'; -import type { TemplateType } from '../../utils/types'; type TemplateCustomizationTest = { visitPage: ( props: { @@ -18,7 +17,7 @@ type TemplateCustomizationTest = { } ) => Promise< void | Response | null >; templateName: string; templatePath: string; - templateType: TemplateType; + templateType: string; fallbackTemplate?: { templateName: string; templatePath: string; diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/legacy-templates.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/legacy-templates.block_theme.spec.ts index bb22f83f99f..d7a0a5a1d05 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/legacy-templates.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/legacy-templates.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { cli } from '@woocommerce/e2e-utils'; +import { test, expect, cli } from '@woocommerce/e2e-utils'; test.describe( 'Legacy templates', () => { test( 'woocommerce//* slug is supported', async ( { diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/order-confirmation.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/order-confirmation.block_theme.spec.ts index 8421ebec359..33aaa30bbf0 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/order-confirmation.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/order-confirmation.block_theme.spec.ts @@ -1,20 +1,19 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect } from '@woocommerce/e2e-utils'; test.describe( 'Test the order confirmation template', () => { test( 'Template can be opened in the site editor', async ( { editor, - editorUtils, admin, } ) => { await admin.visitSiteEditor( { postId: 'woocommerce/woocommerce//order-confirmation', postType: 'wp_template', } ); - await editorUtils.enterEditMode(); - await editorUtils.transformIntoBlocks(); + await editor.enterEditMode(); + await editor.transformIntoBlocks(); await expect( editor.canvas.getByText( 'Thank you. Your order has been received.' diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/shop-page.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/shop-page.block_theme.spec.ts index 4a9650550bf..5bb1c0c549f 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/shop-page.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/shop-page.block_theme.spec.ts @@ -1,8 +1,7 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { cli } from '@woocommerce/e2e-utils'; +import { test, expect, cli } from '@woocommerce/e2e-utils'; test.describe( 'Shop page', () => { test( 'template selector is not visible in the Page editor', async ( { diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme.spec.ts index 8683feadf3c..68d99a60a54 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme.spec.ts @@ -1,13 +1,12 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { test, expect } from '@woocommerce/e2e-utils'; test.describe( 'Single Product template', () => { test( 'loads the Single Product template for a specific product', async ( { admin, editor, - editorUtils, page, } ) => { const testData = { @@ -43,15 +42,5 @@ test.describe( 'Single Product template', () => { // Verify edits are visible. await page.goto( testData.permalink ); await expect( page.getByText( userText ).first() ).toBeVisible(); - - // Revert edition. - await admin.visitSiteEditor( { - path: `/${ testData.templateType }/all`, - } ); - await editorUtils.revertTemplateCreation( testData.templateName ); - await page.goto( testData.permalink ); - - // Verify the edits are no longer visible. - await expect( page.getByText( userText ) ).toHaveCount( 0 ); } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme_with_templates.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme_with_templates.spec.ts index 4ee32982f35..9b79a50f0a2 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme_with_templates.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme_with_templates.spec.ts @@ -1,19 +1,17 @@ /** * External dependencies */ -import { BLOCK_THEME_WITH_TEMPLATES_SLUG } from '@woocommerce/e2e-utils'; -import { test, expect } from '@woocommerce/e2e-playwright-utils'; - -/** - * Internal dependencies - */ -import type { TemplateType } from '../../utils/types'; +import { + test, + expect, + BLOCK_THEME_WITH_TEMPLATES_SLUG, +} from '@woocommerce/e2e-utils'; const testData = { permalink: '/product/belt', templateName: 'Single Product Belt', templatePath: 'single-product-belt', - templateType: 'wp_template' as TemplateType, + templateType: 'wp_template', }; const userText = 'Hello World in the Belt template'; @@ -27,14 +25,15 @@ test.describe( 'Single Product Template', () => { test( 'loads the theme template for a specific product using the product slug and it can be customized', async ( { admin, editor, - editorUtils, page, } ) => { // Edit the theme template. - await editorUtils.visitTemplateEditor( - testData.templateName, - testData.templateType - ); + await admin.visitSiteEditor( { + postId: `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.templatePath }`, + postType: testData.templateType, + } ); + await editor.enterEditMode(); + await editor.insertBlock( { name: 'core/paragraph', attributes: { content: userText }, @@ -47,17 +46,5 @@ test.describe( 'Single Product Template', () => { page.getByText( themeTemplateText ).first() ).toBeVisible(); await expect( page.getByText( userText ).first() ).toBeVisible(); - - // Revert edition and verify the template from the theme is used. - await admin.visitSiteEditor( { - path: `/${ testData.templateType }/all`, - } ); - await editorUtils.revertTemplateCustomizations( testData.templateName ); - await page.goto( testData.permalink ); - - await expect( - page.getByText( themeTemplateText ).first() - ).toBeVisible(); - await expect( page.getByText( userText ) ).toHaveCount( 0 ); } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.spec.ts index bb1e9ab1202..b1086d22884 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.spec.ts @@ -1,8 +1,9 @@ /** * External dependencies */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; import { + test, + expect, BLOCK_THEME_SLUG, BLOCK_THEME_WITH_TEMPLATES_SLUG, } from '@woocommerce/e2e-utils'; @@ -26,14 +27,15 @@ test.describe( 'Template customization', () => { admin, frontendUtils, editor, - editorUtils, page, } ) => { - // Verify the template can be edited. - await editorUtils.visitTemplateEditor( - testData.templateName, - testData.templateType - ); + await admin.visitSiteEditor( { + postId: `woocommerce/woocommerce//${ testData.templatePath }`, + postType: testData.templateType, + } ); + + await editor.enterEditMode(); + await editor.insertBlock( { name: 'core/paragraph', attributes: { content: userText }, @@ -51,16 +53,6 @@ test.describe( 'Template customization', () => { await expect( page.getByText( userText ).first() ).toBeVisible(); - - // Verify the edition can be reverted. - await admin.visitSiteEditor( { - path: `/${ testData.templateType }/all`, - } ); - await editorUtils.revertTemplateCustomizations( - testData.templateName - ); - await testData.visitPage( { frontendUtils, page } ); - await expect( page.getByText( userText ) ).toHaveCount( 0 ); } ); if ( testData.fallbackTemplate ) { @@ -68,14 +60,16 @@ test.describe( 'Template customization', () => { admin, frontendUtils, editor, - editorUtils, page, } ) => { // Edit fallback template and verify changes are visible. - await editorUtils.visitTemplateEditor( - testData.fallbackTemplate?.templateName || '', - testData.templateType - ); + await admin.visitSiteEditor( { + postId: `woocommerce/woocommerce//${ testData.fallbackTemplate?.templatePath }`, + postType: testData.templateType, + } ); + + await editor.enterEditMode(); + await editor.insertBlock( { name: 'core/paragraph', attributes: { @@ -87,18 +81,6 @@ test.describe( 'Template customization', () => { await expect( page.getByText( fallbackTemplateUserText ).first() ).toBeVisible(); - - // Verify the edition can be reverted. - await admin.visitSiteEditor( { - path: `/${ testData.templateType }/all`, - } ); - await editorUtils.revertTemplateCustomizations( - testData.fallbackTemplate?.templateName || '' - ); - await testData.visitPage( { frontendUtils, page } ); - await expect( - page.getByText( fallbackTemplateUserText ) - ).toHaveCount( 0 ); } ); } } ); @@ -118,14 +100,15 @@ test.describe( 'Template customization', () => { admin, editor, requestUtils, - editorUtils, frontendUtils, } ) => { // Edit the WooCommerce default template - await editorUtils.visitTemplateEditor( - testData.templateName, - testData.templateType - ); + await admin.visitSiteEditor( { + postId: `woocommerce/woocommerce//${ testData.templatePath }`, + postType: testData.templateType, + } ); + await editor.enterEditMode(); + await editor.insertBlock( { name: 'core/paragraph', attributes: { content: woocommerceTemplateUserText }, @@ -143,9 +126,9 @@ test.describe( 'Template customization', () => { postId: `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.templatePath }`, postType: testData.templateType, } ); - await editorUtils.enterEditMode(); + await editor.enterEditMode(); - await editorUtils.editor.insertBlock( { + await editor.insertBlock( { name: 'core/paragraph', attributes: { content: userText }, } ); @@ -168,9 +151,31 @@ test.describe( 'Template customization', () => { await admin.visitSiteEditor( { path: `/${ testData.templateType }/all`, } ); - await editorUtils.revertTemplateCustomizations( - testData.templateName - ); + + await page + .getByPlaceholder( 'Search' ) + .fill( testData.templateName ); + + const templateRow = page.getByRole( 'row' ).filter( { + has: page.getByRole( 'link', { + name: testData.templateName, + exact: true, + } ), + } ); + const resetButton = templateRow.getByLabel( 'Reset', { + exact: true, + } ); + const revertedNotice = page + .getByLabel( 'Dismiss this notice' ) + .getByText( `"${ testData.templateName }" reverted.` ); + const savedButton = page.getByRole( 'button', { + name: 'Saved', + } ); + + await resetButton.click(); + + await expect( revertedNotice ).toBeVisible(); + await expect( savedButton ).toBeVisible(); await testData.visitPage( { frontendUtils, page } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme_with_templates.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme_with_templates.spec.ts index 9a50287abf3..c99e84ca0ea 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme_with_templates.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme_with_templates.spec.ts @@ -1,8 +1,11 @@ /** * External dependencies */ -import { BLOCK_THEME_WITH_TEMPLATES_SLUG } from '@woocommerce/e2e-utils'; -import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { + test, + expect, + BLOCK_THEME_WITH_TEMPLATES_SLUG, +} from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -29,15 +32,16 @@ test.describe( 'Template customization', () => { test( "theme template has priority over WooCommerce's and can be modified", async ( { admin, editor, - editorUtils, frontendUtils, page, } ) => { // Edit the theme template. - await editorUtils.visitTemplateEditor( - testData.templateName, - testData.templateType - ); + await admin.visitSiteEditor( { + postId: `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.templatePath }`, + postType: testData.templateType, + } ); + await editor.enterEditMode(); + await editor.insertBlock( { name: 'core/paragraph', attributes: { content: userText }, @@ -56,24 +60,6 @@ test.describe( 'Template customization', () => { await expect( page.getByText( userText ).first() ).toBeVisible(); - - // Revert edition and verify the template from the theme is used. - await admin.visitSiteEditor( { - path: `/${ testData.templateType }/all`, - } ); - await editorUtils.revertTemplateCustomizations( - testData.templateName - ); - await testData.visitPage( { frontendUtils, page } ); - - await expect( - page - .getByText( - `${ testData.templateName } template loaded from theme` - ) - .first() - ).toBeVisible(); - await expect( page.getByText( userText ) ).toHaveCount( 0 ); } ); if ( testData.fallbackTemplate ) { @@ -81,14 +67,16 @@ test.describe( 'Template customization', () => { admin, frontendUtils, editor, - editorUtils, page, } ) => { - // Edit default template and verify changes are not visible, as the theme template has priority. - await editorUtils.visitTemplateEditor( - testData.fallbackTemplate?.templateName || '', - testData.templateType - ); + // Edit default template and verify changes are not visible, + // as the theme template has priority. + await admin.visitSiteEditor( { + postId: `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.fallbackTemplate?.templatePath }`, + postType: testData.templateType, + } ); + await editor.enterEditMode(); + await editor.insertBlock( { name: 'core/paragraph', attributes: { @@ -100,14 +88,6 @@ test.describe( 'Template customization', () => { await expect( page.getByText( fallbackTemplateUserText ) ).toHaveCount( 0 ); - - // Revert the edit. - await admin.visitSiteEditor( { - path: `/${ testData.templateType }/all`, - } ); - await editorUtils.revertTemplateCustomizations( - testData.fallbackTemplate?.templateName || '' - ); } ); } } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/types/block-data.ts b/plugins/woocommerce-blocks/tests/e2e/types/block-data.ts deleted file mode 100644 index f80df3679a2..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/types/block-data.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type BlockData< T = unknown > = { - name: string; - slug: string; - mainClass: string; - selectors: Record< 'editor' | 'frontend', Record< string, unknown > >; -} & ( T extends undefined ? Record< string, never > : T ); diff --git a/plugins/woocommerce-blocks/tests/e2e/types/e2e-test-utils-playwright.ts b/plugins/woocommerce-blocks/tests/e2e/types/e2e-test-utils-playwright.ts deleted file mode 100644 index e6015fef683..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/types/e2e-test-utils-playwright.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Missing or not exported types from @wordpress/e2e-test-utils-playwright - */ - -// import { type Template} from '@wordpress/e2e-test-utils-playwright/build-types/request-utils/templates -export interface Template { - wp_id: number; - id: string; -} -export type ExtendedTemplate = Template & { link: string }; diff --git a/plugins/woocommerce-blocks/tests/e2e/types/index.ts b/plugins/woocommerce-blocks/tests/e2e/types/index.ts deleted file mode 100644 index 49a29e1ff75..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './block-data'; diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/admin/index.ts b/plugins/woocommerce-blocks/tests/e2e/utils/admin/index.ts new file mode 100644 index 00000000000..ea52d869842 --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e/utils/admin/index.ts @@ -0,0 +1,14 @@ +/** + * External dependencies + */ +import { Admin as CoreAdmin } from '@wordpress/e2e-test-utils-playwright'; + +export class Admin extends CoreAdmin { + async visitWidgetEditor() { + await this.page.goto( '/wp-admin/widgets.php' ); + await this.page + .getByLabel( 'Welcome to block Widgets' ) + .getByRole( 'button', { name: 'Close' } ) + .click(); + } +} diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/api/index.ts b/plugins/woocommerce-blocks/tests/e2e/utils/api/index.ts deleted file mode 100644 index 9c1e96b0294..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/utils/api/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './template-api-utils.page'; diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/api/template-api-utils.page.ts b/plugins/woocommerce-blocks/tests/e2e/utils/api/template-api-utils.page.ts deleted file mode 100644 index 65317ab9a2d..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/utils/api/template-api-utils.page.ts +++ /dev/null @@ -1,75 +0,0 @@ -/** - * External dependencies - */ -import { request as req } from '@playwright/test'; -import fs from 'fs/promises'; - -/** - * Internal dependencies - */ -import { BASE_URL, STORAGE_STATE_PATH } from '../constants'; - -export class TemplateApiUtils { - request: typeof req; - constructor( request: typeof req ) { - this.request = request; - } - async revertTemplate( slug: string ) { - const storageState = JSON.parse( - await fs.readFile( STORAGE_STATE_PATH, 'utf-8' ) - ); - const requestUtils = await this.request.newContext( { - baseURL: BASE_URL, - storageState: storageState && { - cookies: storageState.cookies, - origins: [], - }, - } ); - - const response = await requestUtils.get( - `/wp-json/wp/v2/templates/${ slug }?context=edit&source=theme&_locale=user`, - { - headers: { - 'X-WP-Nonce': storageState.nonce, - }, - } - ); - - const { content } = await response.json(); - - await requestUtils.post( - `wp-json/wp/v2/templates/${ slug }?_locale=user`, - { - data: { - id: slug, - content: content?.raw, - source: 'theme', - }, - headers: { - 'X-WP-Nonce': storageState.nonce, - }, - } - ); - } - - async getTemplates() { - const storageState = JSON.parse( - await fs.readFile( STORAGE_STATE_PATH, 'utf-8' ) - ); - - const requestUtils = await this.request.newContext( { - baseURL: BASE_URL, - storageState: storageState && { - cookies: storageState.cookies, - origins: [], - }, - } ); - const response = await requestUtils.get( `/wp-json/wp/v2/templates`, { - headers: { - 'X-WP-Nonce': storageState.nonce, - }, - } ); - - return await response.json(); - } -} diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/create-dynamic-content.ts b/plugins/woocommerce-blocks/tests/e2e/utils/create-dynamic-content.ts deleted file mode 100644 index 802936802ea..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/utils/create-dynamic-content.ts +++ /dev/null @@ -1,85 +0,0 @@ -/** - * External dependencies - */ -import { readFile } from 'fs/promises'; -import Handlebars from 'handlebars'; -import { CreatePostPayload } from '@wordpress/e2e-test-utils-playwright/build-types/request-utils/posts'; -import { RequestUtils } from '@wordpress/e2e-test-utils-playwright'; - -Handlebars.registerPartial( - 'wp-block', - ` - -{{> @partial-block }} - -` -); - -Handlebars.registerHelper( 'stringify', function ( context ) { - return JSON.stringify( context ); -} ); - -export const deletePost = async ( requestUtils: RequestUtils, id: number ) => { - return requestUtils.rest( { - method: 'DELETE', - path: `/wp/v2/posts/${ id }`, - params: { - force: true, - }, - } ); -}; - -const createPost = async ( - requestUtils: RequestUtils, - payload: CreatePostPayload -) => { - // The underlying createPost method passes the payload as URI params, triggering URI too long errors - // if you pass long blog post content. - const post = await requestUtils.rest( { - method: 'POST', - path: `/wp/v2/posts`, - data: { ...payload }, - } ); - return post; -}; - -export type PostPayload = Partial< CreatePostPayload >; - -export const createPostFromTemplate = async ( - requestUtils: RequestUtils, - post: PostPayload, - templatePath: string, - data: unknown -) => { - const templateContent = await readFile( templatePath, 'utf8' ); - const content = Handlebars.compile( templateContent )( data ); - - const payload: CreatePostPayload = { - status: 'publish', - date_gmt: new Date().toISOString(), - content, - ...post, - }; - - return createPost( requestUtils, payload ); -}; - -export const updateTemplateContents = async ( - requestUtils: RequestUtils, - templateId: string, - templatePath: string, - data: unknown -) => { - const templateContent = await readFile( templatePath, 'utf8' ); - const content = Handlebars.compile( templateContent )( data ); - - const payload = { - content, - }; - - return requestUtils.rest( { - method: 'POST', - path: `/wp/v2/templates/${ templateId }`, - data: { ...payload }, - } ); -}; diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/editor/editor-utils.page.ts b/plugins/woocommerce-blocks/tests/e2e/utils/editor/editor-utils.page.ts index 528a1d596d1..3c2543166aa 100644 --- a/plugins/woocommerce-blocks/tests/e2e/utils/editor/editor-utils.page.ts +++ b/plugins/woocommerce-blocks/tests/e2e/utils/editor/editor-utils.page.ts @@ -1,178 +1,24 @@ /** * External dependencies */ -import { Page } from '@playwright/test'; -import { Editor, expect, Admin } from '@wordpress/e2e-test-utils-playwright'; -import { BlockRepresentation } from '@wordpress/e2e-test-utils-playwright/build-types/editor/insert-block'; - -/** - * Internal dependencies - */ -import type { TemplateType } from '../../utils/types'; - -export class EditorUtils { - editor: Editor; - page: Page; - admin: Admin; - constructor( editor: Editor, page: Page, admin: Admin ) { - this.editor = editor; - this.page = page; - this.admin = admin; - } - - /** - * Check to see if there are any errors in the editor. - */ - async ensureNoErrorsOnBlockPage() { - const errorMessages = [ - /This block contains unexpected or invalid content/gi, - /Your site doesn’t include support for/gi, - /There was an error whilst rendering/gi, - /This block has encountered an error and cannot be previewed/gi, - ]; - - for ( const error of errorMessages ) { - if ( ( await this.editor.canvas.getByText( error ).count() ) > 0 ) { - return false; - } - } - return true; - } - - /** - * Checks if the editor is inside an iframe. - */ - private async isEditorInsideIframe() { - try { - return ( await this.editor.canvas.locator( '*' ).count() ) > 0; - } catch ( e ) { - return false; - } - } +import { Editor as CoreEditor } from '@wordpress/e2e-test-utils-playwright'; +export class Editor extends CoreEditor { async getBlockByName( name: string ) { - if ( await this.isEditorInsideIframe() ) { - return this.editor.canvas.locator( `[data-type="${ name }"]` ); + const blockSelector = `[data-type="${ name }"]`; + const canvasLocator = this.page + .locator( '.editor-styles-wrapper, iframe[name=editor-canvas]' ) + .first(); + + const isFramed = await canvasLocator.evaluate( + ( node ) => node.tagName === 'IFRAME' + ); + + if ( isFramed ) { + return this.canvas.locator( blockSelector ); } - return this.page.locator( `[data-type="${ name }"]` ); - } - async getBlockByTypeWithParent( name: string, parentName: string ) { - const parentBlock = await this.getBlockByName( parentName ); - if ( ! parentBlock ) { - throw new Error( `Parent block "${ parentName }" not found.` ); - } - const block = parentBlock.locator( `[data-type="${ name }"]` ); - return block; - } - - // todo: Make a PR to @wordpress/e2e-test-utils-playwright to add this method. - /** - * Inserts a block inside a given client ID. - * - */ - async insertBlock( - blockRepresentation: BlockRepresentation, - index?: string, - rootClientId?: string - ) { - await this.page.evaluate( - ( { - blockRepresentation: _blockRepresentation, - index: _index, - rootClientId: _rootClientId, - } ) => { - function recursiveCreateBlock( { - name, - attributes = {}, - innerBlocks = [], - }: BlockRepresentation ): BlockRepresentation { - return window.wp.blocks.createBlock( - name, - attributes, - innerBlocks.map( ( innerBlock ) => - recursiveCreateBlock( innerBlock ) - ) - ); - } - const block = recursiveCreateBlock( _blockRepresentation ); - - window.wp.data - .dispatch( 'core/block-editor' ) - .insertBlock( block, _index, _rootClientId ); - }, - { blockRepresentation, index, rootClientId } - ); - } - - async removeBlocks( { name }: { name: string } ) { - await this.page.evaluate( - ( { name: _name } ) => { - const blocks = window.wp.data - .select( 'core/block-editor' ) - .getBlocks() as ( BlockRepresentation & { - clientId: string; - } )[]; - const matchingBlocksClientIds = blocks - .filter( ( block ) => { - return block && block.name === _name; - } ) - .map( ( block ) => block?.clientId ); - window.wp.data - .dispatch( 'core/block-editor' ) - .removeBlocks( matchingBlocksClientIds ); - }, - { name } - ); - } - - async removeBlockByClientId( clientId: string ) { - await this.page.evaluate( - ( { clientId: _clientId } ) => { - window.wp.data - .dispatch( 'core/block-editor' ) - .removeBlocks( _clientId ); - }, - { clientId } - ); - } - - async closeModalByName( name: string ) { - const isModalOpen = await this.page.getByLabel( name ).isVisible(); - - // eslint-disable-next-line playwright/no-conditional-in-test - if ( isModalOpen ) { - await this.page - .getByLabel( name ) - .getByRole( 'button', { name: 'Close' } ) - .click(); - } - } - async replaceBlockByBlockName( name: string, nameToInsert: string ) { - await this.page.evaluate( - ( { name: _name, nameToInsert: _nameToInsert } ) => { - const blocks = window.wp.data - .select( 'core/block-editor' ) - .getBlocks(); - const firstMatchingBlock = blocks - .flatMap( - ( { - innerBlocks, - }: { - innerBlocks: BlockRepresentation[]; - } ) => innerBlocks - ) - .find( - ( block: BlockRepresentation ) => block.name === _name - ); - const { clientId } = firstMatchingBlock; - const block = window.wp.blocks.createBlock( _nameToInsert ); - window.wp.data - .dispatch( 'core/block-editor' ) - .replaceBlock( clientId, block ); - }, - { name, nameToInsert } - ); + return this.page.locator( blockSelector ); } async getBlockRootClientId( clientId: string ) { @@ -183,40 +29,24 @@ export class EditorUtils { }, clientId ); } - /** - * Toggles the global inserter. - */ - async toggleGlobalBlockInserter() { - await this.page - .getByRole( 'button', { name: 'Toggle block inserter' } ) - .click(); - } - - /** - * Checks if the global inserter is open. - * - * @return {Promise} Whether the inserter is open or not. - */ - async isGlobalInserterOpen() { - const button = this.page.getByRole( 'button', { - name: 'Toggle block inserter', - } ); - - return ( await button.getAttribute( 'aria-pressed' ) ) === 'true'; - } - /** * Opens the global inserter. */ async openGlobalBlockInserter() { - if ( ! ( await this.isGlobalInserterOpen() ) ) { - await this.toggleGlobalBlockInserter(); + const toggleButton = this.page.getByRole( 'button', { + name: 'Toggle block inserter', + } ); + const isOpen = + ( await toggleButton.getAttribute( 'aria-pressed' ) ) === 'true'; + + if ( ! isOpen ) { + await toggleButton.click(); await this.page.locator( '.block-editor-inserter__menu' ).waitFor(); } } async enterEditMode() { - await this.editor.page + await this.page .getByRole( 'button', { name: 'Edit', exact: true, @@ -279,76 +109,9 @@ export class EditorUtils { return firstBlockIndex < secondBlockIndex; } - async setLayoutOption( - option: - | 'Align Top' - | 'Align Bottom' - | 'Align Middle' - | 'Stretch to Fill' - ) { - const button = this.page.locator( - "button[aria-label='Change vertical alignment']" - ); - - await button.click(); - - await this.page.getByText( option ).click(); - } - - async setAlignOption( - option: 'Align Left' | 'Align Center' | 'Align Right' | 'None' - ) { - const button = this.page.locator( "button[aria-label='Align']" ); - - await button.click(); - - await this.page.getByText( option ).click(); - } - - async closeWelcomeGuideModal() { - await this.page.waitForFunction( () => { - return ( - window.wp && - window.wp.data && - window.wp.data.dispatch( 'core/preferences' ) - ); - } ); - - // Disable the welcome guide for the site editor. - await this.page.evaluate( () => { - return Promise.all( [ - window.wp.data - .dispatch( 'core/preferences' ) - .set( 'core/edit-site', 'welcomeGuide', false ), - window.wp.data - .dispatch( 'core/preferences' ) - .set( 'core/edit-site', 'welcomeGuideStyles', false ), - window.wp.data - .dispatch( 'core/preferences' ) - .set( 'core/edit-site', 'welcomeGuidePage', false ), - window.wp.data - .dispatch( 'core/preferences' ) - .set( 'core/edit-site', 'welcomeGuideTemplate', false ), - window.wp.data - .dispatch( 'core/preferences' ) - .set( 'core/edit-post', 'welcomeGuide', false ), - window.wp.data - .dispatch( 'core/preferences' ) - .set( 'core/edit-post', 'welcomeGuideStyles', false ), - window.wp.data - .dispatch( 'core/preferences' ) - .set( 'core/edit-post', 'welcomeGuidePage', false ), - - window.wp.data - .dispatch( 'core/preferences' ) - .set( 'core/edit-post', 'welcomeGuideTemplate', false ), - ] ); - } ); - } - async transformIntoBlocks() { // Select the block, so the button is visible. - const block = this.editor.canvas + const block = this.canvas .locator( `[data-type="woocommerce/legacy-template"]` ) .first(); @@ -356,7 +119,7 @@ export class EditorUtils { return; } - await this.editor.selectBlocks( block ); + await this.selectBlocks( block ); const transformButton = block.getByRole( 'button', { name: 'Transform into blocks', @@ -370,130 +133,9 @@ export class EditorUtils { } } - // This method is the same as the one in @wordpress/e2e-test-utils-playwright. But for some reason - // it doesn't work as expected when imported from there. For its first run we get the following error: - // Error: locator.waitFor: Target closed - async saveSiteEditorEntities() { - const editorTopBar = this.page.getByRole( 'region', { - name: 'Editor top bar', - } ); - const savePanel = this.page.getByRole( 'region', { - name: 'Save panel', - } ); - - // First Save button in the top bar. - await editorTopBar - .getByRole( 'button', { name: 'Save', exact: true } ) - .click(); - - // Second Save button in the entities panel. - await savePanel - .getByRole( 'button', { name: 'Save', exact: true } ) - .click(); - - await this.page - .getByRole( 'button', { name: 'Dismiss this notice' } ) - .getByText( 'Site updated.' ) - .waitFor(); - } - - async visitTemplateEditor( - templateName: string, - templateType: TemplateType - ) { - if ( templateType === 'wp_template_part' ) { - await this.admin.visitSiteEditor( { - path: `/${ templateType }/all`, - } ); - const templateLink = this.page.getByRole( 'link', { - name: templateName, - exact: true, - } ); - await templateLink.click(); - } else { - await this.admin.visitSiteEditor( { - path: '/' + templateType, - } ); - const templateButton = this.page.getByRole( 'button', { - name: templateName, - exact: true, - } ); - await templateButton.click(); - } - - await this.enterEditMode(); - - // Verify we are editing the correct template and it has the correct title. - const templateTypeName = - templateType === 'wp_template' ? 'template' : 'template part'; - await this.page - .getByRole( 'heading', { - name: `Editing ${ templateTypeName }: ${ templateName }`, - } ) - .waitFor(); - } - - async revertTemplateCreation( templateName: string ) { - await this.page.getByPlaceholder( 'Search' ).fill( templateName ); - - const templateRow = this.page.getByRole( 'row' ).filter( { - has: this.page.getByRole( 'link', { - name: templateName, - exact: true, - } ), - } ); - await templateRow.getByRole( 'button', { name: 'Delete' } ).click(); - await this.page - .getByRole( 'button', { - name: 'Delete', - } ) - .click(); - await this.page - .getByRole( 'button', { name: 'Dismiss this notice' } ) - .getByText( `"${ templateName }" deleted.` ) - .waitFor(); - } - - async revertTemplateCustomizations( templateName: string ) { - await this.page.getByPlaceholder( 'Search' ).fill( templateName ); - - const templateRow = this.page.getByRole( 'row' ).filter( { - has: this.page.getByRole( 'link', { - name: templateName, - exact: true, - } ), - } ); - const resetButton = templateRow.getByLabel( 'Reset', { exact: true } ); - const revertedNotice = this.page - .getByLabel( 'Dismiss this notice' ) - .getByText( `"${ templateName }" reverted.` ); - const savedButton = this.page.getByRole( 'button', { name: 'Saved' } ); - - await resetButton.click(); - - await expect( revertedNotice ).toBeVisible(); - await expect( savedButton ).toBeVisible(); - } - - async updatePost() { - await this.page.getByRole( 'button', { name: 'Update' } ).click(); - - await this.page - .getByRole( 'button', { name: 'Dismiss this notice' } ) - .filter( { hasText: 'updated' } ) - .waitFor(); - } - async publishAndVisitPost() { - await this.editor.publishPost(); - const url = new URL( this.page.url() ); - const postId = url.searchParams.get( 'post' ); - await this.page.goto( `/?p=${ postId }`, { waitUntil: 'commit' } ); - } - - async openWidgetEditor() { - await this.page.goto( '/wp-admin/widgets.php' ); - await this.closeModalByName( 'Welcome to block Widgets' ); + const postId = await this.publishPost(); + await this.page.goto( `/?p=${ postId }` ); } /** @@ -514,45 +156,4 @@ export class EditorUtils { .first() .click(); } - - /** - * Opens a specific Single Product template. - */ - async openSpecificProductTemplate( - productName: string, - productSlug: string, - createIfDoesntExist = true - ) { - await this.admin.visitSiteEditor(); - await this.page.getByRole( 'button', { name: 'Templates' } ).click(); - - const templateButton = this.page.getByRole( 'button', { - name: `Product: ${ productName }`, - } ); - - // Template can be created only once. Go to template if exists, - // otherwise create one. - if ( await templateButton.isVisible() ) { - await templateButton.click(); - await this.enterEditMode(); - } else if ( createIfDoesntExist ) { - await this.page - .getByRole( 'button', { name: 'Add New Template' } ) - .click(); - await this.page - .getByRole( 'button', { name: 'Single Item: Product' } ) - .click(); - await this.page - .getByRole( 'option', { - name: `${ productName } http://localhost:8889/product/${ productSlug }/`, - } ) - .click(); - await this.page - .getByRole( 'button', { - name: 'Skip', - } ) - .click(); - } - await this.closeWelcomeGuideModal(); - } } diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/index.ts b/plugins/woocommerce-blocks/tests/e2e/utils/index.ts index 26441a300c1..1ab72f6e5b8 100644 --- a/plugins/woocommerce-blocks/tests/e2e/utils/index.ts +++ b/plugins/woocommerce-blocks/tests/e2e/utils/index.ts @@ -1,11 +1,18 @@ -export * from './api'; +export { PageUtils } from '@wordpress/e2e-test-utils-playwright'; + export * from './cli'; export * from './constants'; +export * from './admin'; export * from './editor'; export * from './frontend'; export * from './local-pickup'; export * from './mini-cart'; export * from './performance'; +export * from './request-utils'; export * from './shipping'; export * from './storeApi'; export * from './wpCli'; + +export * from './test'; + +export * from './types'; diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/local-pickup/local-pickup-utils.page.ts b/plugins/woocommerce-blocks/tests/e2e/utils/local-pickup/local-pickup-utils.page.ts index f6ace641b58..51a9eae5002 100644 --- a/plugins/woocommerce-blocks/tests/e2e/utils/local-pickup/local-pickup-utils.page.ts +++ b/plugins/woocommerce-blocks/tests/e2e/utils/local-pickup/local-pickup-utils.page.ts @@ -1,10 +1,9 @@ /** * External dependencies */ -import { Page } from '@playwright/test'; -import { Admin } from '@wordpress/e2e-test-utils-playwright'; -import { cli } from '@woocommerce/e2e-utils'; import { Notice } from '@wordpress/notices'; +import { Page } from '@playwright/test'; +import { Admin, cli } from '@woocommerce/e2e-utils'; type Location = { name: string; diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/navigation/navigation.ts b/plugins/woocommerce-blocks/tests/e2e/utils/navigation/navigation.ts index 3b25813c082..731c56d9213 100644 --- a/plugins/woocommerce-blocks/tests/e2e/utils/navigation/navigation.ts +++ b/plugins/woocommerce-blocks/tests/e2e/utils/navigation/navigation.ts @@ -2,7 +2,7 @@ * External dependencies */ import { Page, PlaywrightTestArgs } from '@playwright/test'; -import { BlockData } from '@woocommerce/e2e-types'; +import { BlockData } from '@woocommerce/e2e-utils'; /** * Closes any modals in the editor if they are open. diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/index.ts b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/index.ts new file mode 100644 index 00000000000..2c437a6cbe4 --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/index.ts @@ -0,0 +1,57 @@ +/** + * External dependencies + */ +import { RequestUtils as CoreRequestUtils } from '@wordpress/e2e-test-utils-playwright'; + +/** + * Internal dependencies + */ +import { createPostFromFile, PostCompiler } from './posts'; +import { + getTemplates, + revertTemplate, + createTemplateFromFile, + TemplateCompiler, +} from './templates'; + +export class RequestUtils extends CoreRequestUtils { + // The `setup` override is necessary only until + // https://github.com/WordPress/gutenberg/pull/59362 is merged. + static async setup( ...args: Parameters< typeof CoreRequestUtils.setup > ) { + const { request, user, storageState, storageStatePath, baseURL } = + await CoreRequestUtils.setup( ...args ); + + // We need those checks to satisfy TypeScript. + if ( ! storageState ) { + throw new Error( 'Storage state is required' ); + } + + if ( ! storageStatePath ) { + throw new Error( 'Storage state path is required' ); + } + + if ( ! baseURL ) { + throw new Error( 'Base URL is required' ); + } + + return new this( request, { + user, + storageState, + storageStatePath, + baseURL, + } ); + } + + /** @borrows getTemplates as this.getTemplates */ + getTemplates: typeof getTemplates = getTemplates.bind( this ); + /** @borrows revertTemplate as this.revertTemplate */ + revertTemplate: typeof revertTemplate = revertTemplate.bind( this ); + /** @borrows createPostFromFile as this.createPostFromFile */ + createPostFromFile: typeof createPostFromFile = + createPostFromFile.bind( this ); + /** @borrows createTemplateFromFile as this.createTemplateFromFile */ + createTemplateFromFile: typeof createTemplateFromFile = + createTemplateFromFile.bind( this ); +} + +export { TemplateCompiler, PostCompiler }; diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/posts.ts b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/posts.ts new file mode 100644 index 00000000000..d7bcc51bfd7 --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/posts.ts @@ -0,0 +1,67 @@ +/** + * External dependencies + */ +import path from 'path'; +import { readFile } from 'fs/promises'; +import Handlebars from 'handlebars'; +import { Post } from '@wordpress/e2e-test-utils-playwright/build-types/request-utils/posts'; + +/** + * Internal dependencies + */ +import type { RequestUtils } from './index'; + +export interface PostCompiler { + compile: ( data?: unknown ) => Promise< Post >; +} + +/** + * Creates a post from a Handlebars template file located in the + * tests/e2e/content-templates directory. + */ +export async function createPostFromFile( this: RequestUtils, name: string ) { + const filePrefix = 'post'; + const filePath = path.resolve( + __dirname, + '../../content-templates', + `${ filePrefix }_${ name }.handlebars` // e.g. post_with-custom-filters.handlebars + ); + + const fileContent = await readFile( filePath, 'utf8' ); + + Handlebars.registerPartial( + 'wp-block', + ` + + {{> @partial-block }} + + ` + ); + + Handlebars.registerHelper( 'stringify', function ( context ) { + return JSON.stringify( context ); + } ); + + const compiledTemplate = Handlebars.compile( fileContent ); + + return { + compile: async ( data: unknown ) => { + const content = compiledTemplate( data ); + + // We're calling the posts endpoint directly until we can use the + // createPost method. + // See https://github.com/WordPress/gutenberg/pull/59463 for more + // details. + return await this.rest( { + method: 'POST', + path: `/wp/v2/posts`, + data: { + status: 'publish', + date_gmt: new Date().toISOString(), + content, + title: name, + }, + } ); + }, + }; +} diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/templates.ts b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/templates.ts new file mode 100644 index 00000000000..4a5fbd8c060 --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e/utils/request-utils/templates.ts @@ -0,0 +1,111 @@ +/** + * External dependencies + */ +import path from 'path'; +import { readFile } from 'fs/promises'; +import Handlebars from 'handlebars'; + +/** + * Internal dependencies + */ +import type { RequestUtils } from './index'; + +// We need to re-define the Template and TemplateType interfaces under a +// different names because of the conflicts caused by the core E2E +// utils already defining, but not exporting them. +// @todo: Remove this when the core E2E utils export these interfaces and we can +// use them directly. +export type WPTemplateType = 'wp_template' | 'wp_template_part'; +export interface WPTemplate { + wp_id: number; + id: string; + type: WPTemplateType; +} + +export interface TemplateCompiler { + compile: ( data?: unknown ) => Promise< WPTemplate >; +} + +/** + * Retrieves all available templates. + */ +export async function getTemplates( this: RequestUtils ) { + const templates = await this.rest< WPTemplate[] >( { + method: 'GET', + path: '/wp/v2/templates', + } ); + + return templates; +} + +/** + * Reverts a template to its original state. + */ +export async function revertTemplate( this: RequestUtils, slug: string ) { + const restPath = `/wp/v2/templates/${ slug }`; + + const template = await this.rest( { + method: 'GET', + path: restPath, + } ); + + await this.rest( { + method: 'POST', + path: restPath, + data: { + id: slug, + content: template.content.raw, + source: 'theme', + }, + } ); +} + +/** + * Creates a WP template from a Handlebars template file located in the + * tests/e2e/content-templates directory. + */ +export async function createTemplateFromFile( + this: RequestUtils, + name: string +) { + const [ slug, title ] = name.split( '_' ); + if ( ! slug || ! title ) { + throw new Error( '`name` must be in the format "_"' ); + } + + const filePrefix = 'template'; + const filePath = path.resolve( + __dirname, + '../../content-templates', + `${ filePrefix }_${ name }.handlebars` // e.g. template_product-archive_with-custom-filters.handlebars + ); + + const fileContent = await readFile( filePath, 'utf8' ); + + Handlebars.registerPartial( + 'wp-block', + ` + <!-- wp:{{blockName}} {{{stringify attributes}}} --> + {{> @partial-block }} + <!-- /wp:{{blockName}} --> + ` + ); + + Handlebars.registerHelper( 'stringify', function ( context ) { + return JSON.stringify( context ); + } ); + + const compiledTemplate = Handlebars.compile( fileContent ); + + return <TemplateCompiler>{ + compile: async ( data = {} ) => { + const content = compiledTemplate( data ); + + return await this.createTemplate( 'wp_template', { + slug, + title, + content, + } ); + }, + }; +} diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/shipping/shipping-utils.page.ts b/plugins/woocommerce-blocks/tests/e2e/utils/shipping/shipping-utils.page.ts index 2623ed13f7c..9296902a221 100644 --- a/plugins/woocommerce-blocks/tests/e2e/utils/shipping/shipping-utils.page.ts +++ b/plugins/woocommerce-blocks/tests/e2e/utils/shipping/shipping-utils.page.ts @@ -2,7 +2,7 @@ * External dependencies */ import { Page } from '@playwright/test'; -import { Admin } from '@wordpress/e2e-test-utils-playwright'; +import { Admin } from '@woocommerce/e2e-utils'; export class ShippingUtils { private page: Page; diff --git a/plugins/woocommerce-blocks/tests/e2e/playwright-utils/test.ts b/plugins/woocommerce-blocks/tests/e2e/utils/test.ts similarity index 71% rename from plugins/woocommerce-blocks/tests/e2e/playwright-utils/test.ts rename to plugins/woocommerce-blocks/tests/e2e/utils/test.ts index 1148772aab4..88b908f2800 100644 --- a/plugins/woocommerce-blocks/tests/e2e/playwright-utils/test.ts +++ b/plugins/woocommerce-blocks/tests/e2e/utils/test.ts @@ -2,40 +2,23 @@ /** * External dependencies */ -import { test as base, expect, request as baseRequest } from '@playwright/test'; -import type { ConsoleMessage } from '@playwright/test'; +import { test as base, expect, ConsoleMessage } from '@playwright/test'; import { - Admin, - Editor, - PageUtils, - RequestUtils, -} from '@wordpress/e2e-test-utils-playwright'; -import { - TemplateApiUtils, STORAGE_STATE_PATH, DB_EXPORT_FILE, - EditorUtils, + cli, + WPCLIUtils, + Admin, + Editor, FrontendUtils, - StoreApiUtils, - PerformanceUtils, - ShippingUtils, LocalPickupUtils, MiniCartUtils, - WPCLIUtils, - cli, + PageUtils, + PerformanceUtils, + RequestUtils, + ShippingUtils, + StoreApiUtils, } from '@woocommerce/e2e-utils'; -import { Post } from '@wordpress/e2e-test-utils-playwright/build-types/request-utils/posts'; - -/** - * Internal dependencies - */ -import { - type PostPayload, - createPostFromTemplate, - updateTemplateContents, - deletePost, -} from '../utils/create-dynamic-content'; -import type { ExtendedTemplate } from '../types/e2e-test-utils-playwright'; /** * Set of console logging types observed to protect against unexpected yet @@ -125,8 +108,6 @@ const test = base.extend< admin: Admin; editor: Editor; pageUtils: PageUtils; - templateApiUtils: TemplateApiUtils; - editorUtils: EditorUtils; frontendUtils: FrontendUtils; storeApiUtils: StoreApiUtils; performanceUtils: PerformanceUtils; @@ -137,19 +118,7 @@ const test = base.extend< wpCliUtils: WPCLIUtils; }, { - requestUtils: RequestUtils & { - createPostFromTemplate: ( - post: PostPayload, - templatePath: string, - data: unknown - ) => Promise< Post >; - deletePost: ( id: number ) => Promise< void >; - updateTemplateContents: ( - templateId: string, - templatePath: string, - data: unknown - ) => Promise< ExtendedTemplate >; - }; + requestUtils: RequestUtils; } >( { admin: async ( { page, pageUtils, editor }, use ) => { @@ -175,11 +144,6 @@ const test = base.extend< pageUtils: async ( { page }, use ) => { await use( new PageUtils( { page } ) ); }, - templateApiUtils: async ( {}, use ) => - await use( new TemplateApiUtils( baseRequest ) ), - editorUtils: async ( { editor, page, admin }, use ) => { - await use( new EditorUtils( editor, page, admin ) ); - }, frontendUtils: async ( { page, requestUtils }, use ) => { await use( new FrontendUtils( page, requestUtils ) ); }, @@ -204,43 +168,11 @@ const test = base.extend< requestUtils: [ async ( {}, use, workerInfo ) => { const requestUtils = await RequestUtils.setup( { - baseURL: workerInfo.project.use.baseURL, + baseURL: workerInfo.project.use.baseURL as string, storageStatePath: STORAGE_STATE_PATH, } ); - const utilCreatePostFromTemplate = ( - post: Partial< PostPayload >, - templatePath: string, - data: unknown - ) => - createPostFromTemplate( - requestUtils, - post, - templatePath, - data - ); - - const utilDeletePost = ( id: number ) => - deletePost( requestUtils, id ); - - const utilUpdateTemplateContents = ( - templateId: string, - templatePath: string, - data: unknown - ) => - updateTemplateContents( - requestUtils, - templateId, - templatePath, - data - ); - - await use( { - ...requestUtils, - createPostFromTemplate: utilCreatePostFromTemplate, - updateTemplateContents: utilUpdateTemplateContents, - deletePost: utilDeletePost, - } ); + await use( requestUtils ); }, { scope: 'worker', auto: true }, ], diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/types.ts b/plugins/woocommerce-blocks/tests/e2e/utils/types.ts index 1ae02e7f577..f80df3679a2 100644 --- a/plugins/woocommerce-blocks/tests/e2e/utils/types.ts +++ b/plugins/woocommerce-blocks/tests/e2e/utils/types.ts @@ -1 +1,6 @@ -export type TemplateType = 'wp_template' | 'wp_template_part'; +export type BlockData< T = unknown > = { + name: string; + slug: string; + mainClass: string; + selectors: Record< 'editor' | 'frontend', Record< string, unknown > >; +} & ( T extends undefined ? Record< string, never > : T ); diff --git a/plugins/woocommerce-blocks/tsconfig.base.json b/plugins/woocommerce-blocks/tsconfig.base.json index 28b91a9b6fa..1c55286df4a 100644 --- a/plugins/woocommerce-blocks/tsconfig.base.json +++ b/plugins/woocommerce-blocks/tsconfig.base.json @@ -68,9 +68,6 @@ "@woocommerce/storybook-controls": [ "storybook/custom-controls" ], "@woocommerce/utils": [ "assets/js/utils" ], "@woocommerce/e2e-utils": [ "tests/e2e/utils" ], - "@woocommerce/e2e-types": [ "tests/e2e/types" ], - "@woocommerce/e2e-playwright-utils": [ "tests/e2e/playwright-utils" ], - "@woocommerce/e2e-mocks/*": [ "tests/e2e/mocks/*" ], "@woocommerce/templates/*": [ "assets/js/templates/*" ] } } diff --git a/plugins/woocommerce/changelog/47660-refactor-core-e2e-utils-implementation b/plugins/woocommerce/changelog/47660-refactor-core-e2e-utils-implementation new file mode 100644 index 00000000000..14b4e9eba67 --- /dev/null +++ b/plugins/woocommerce/changelog/47660-refactor-core-e2e-utils-implementation @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Streamline the implementation of the Blocks' E2E utilities.