elgentos Magento 2 Playwright BDD E2E Testing Suite

April 29, 2026 · View on GitHub

This package contains an end-to-end (E2E) testing suite for Magento 2, powered by Playwright. It enables you to quickly set up, run, and extend automated browser tests for your Magento 2 store. Installation is simple via npm, allowing you to seamlessly integrate robust testing into your development workflow.

⚠️ Please note: if you’re not sure what each test does, then you should only run this in a testing environment! Some tests involve the database, and the suite's setup project (init.setup.ts) will disable the CAPTCHA of your webshop on first run.

🏃Just want to install and get going?

If you’re simply looking to install, check the prerequisites and then go to 🧪 Installing the suite.


Table of contents


Prerequisites

  • This testing suite has been designed to work within a Hyvä theme in Magento 2, but can work with other themes.
  • Magento 2 instance: A running instance of Magento 2 for testing purposes. Elgentos sponsors a Hyvä demo website for this project.

🧪 Installing the suite

  1. Create a playwright/ directory inside your theme’s /web folder

Navigate to the web folder of your theme. This is usually located in app/design/frontend/{vendor}/{theme}/web. Within this folder, create a playwright folder, then navigate to it:

cd app/design/frontend/demo-store/demo-theme/web
mkdir playwright
cd playwright
  1. Initialize an npm project:
npm init -y
  1. Install the test suite package

Lastly, simply run the command to install the elgentos Magento2 Playwright package, and the installation script will set things up for you!

npm install @elgentos/magento2-playwright
  1. Generate .env file and add playwright to .gitignore (optional)

Normally, you should be prompted to provide values for the .env variables during installation. Each variable also comes with sensible default values.

⚠️ Due to limitations in how npm runs dependency install scripts, the install.js script is not executed automatically when this package is installed as a dependency.

If you want to (re)generate the .env file and configure your environment variables, run the following command manually from your playwright root folder:

node node_modules/@elgentos/magento2-playwright/install.js

After running the command, you will be asked:

  • Do you want to customize environment variables? (y/N)
  • Do you want to add lines to the .gitignore of your project? (y/N)

⏸️ Before you run

After the installation, a variety of folders will have been created. Most notable in these are base-tests, which contain the tests without alteration, and tests. You should never make changes directly to the base-tests folder, as thisx may break functionality. However, note that the base-tests can be updated when you upgrade the package, so always review any changes after an update.

If you want to make changes to your iteration of the testing suite such as making changes to how the test works, updating element identifiers etc., see the section ‘Customizing the testing suite’ below.


🤖 Running the suite

npx playwright test is all you need:

npx playwright test --trace on

npx playwright test always runs the setup project first — Playwright wires this in automatically as a project dependency. Setup disables the admin login CAPTCHA, creates the test accounts, and ensures the coupon codes exist before any browser test starts. The setup steps are idempotent, so re-running on an already-configured environment is safe.

You can run a subset by adding --project=, --grep, or a filename:

npx playwright test login.spec.ts
npx playwright test --grep "@hot"
npx playwright test --project=chromium

In every case Playwright pulls the setup project in automatically as a dependency.


🔁 Migrating from 6.x

Version 7.0 moves setup from a tagged spec (setup.spec.ts) to a Playwright project dependency (init.setup.ts). For existing installs:

  1. Open playwright.config.example.ts (refreshed by the new package). Copy these into your own playwright.config.ts:
    • the getSetupFiles() helper
    • the EXCLUDED_SPEC_FILES set inside getTestFiles()
    • the setup project block at the top of projects:
    • the dependencies: [‘setup’] line on each browser project
  2. Add a coupon.codes block to your tests/config/input-values.json, keyed by uppercase browser name (e.g. "CHROMIUM": "CHROMIUM321"). One entry per browser project in your playwright.config.ts.
  3. Remove MAGENTO_COUPON_CODE_CHROMIUM, _FIREFOX, and _WEBKIT from your .env — they are no longer read.
  4. If you had a custom tests/setup.spec.ts, port its contents into a new tests/init.setup.ts.

After these changes, npx playwright test runs setup automatically and you no longer need a separate --grep "@setup" invocation.


🌐 Generate Translations

The Magento 2 Playwright Testing Suite supports translations, allowing you to run tests in multiple languages. This is particularly useful for international stores with multilingual sites.

Setting Up Translations

  1. Directory Structure: Ensure your playwright suite is located in the app/design/Vendor/theme/web/playwright directory within your Magento installation. This is crucial for the Playwright suite to locate and utilize the correct files from magento.

  2. (Optional) Create Test Files: Go to step 3 when this is the NPM installed package. Create the following directories and file:

    • i18n/app/nl_NL.csv
    • i18n/vendor/

    After creating these, populate nl_NL.csv with entries that match texts from ./config/element-identifiers.json. For instance, you might add "Password", "Wachtwoord". Alternatively, you can copy a translation file from Magento into the i18n/app directory.

  3. Generate translation files: run following command: node translate-json.js nl_NL. nl_NL is the language you want to translate to. For example; it will look for nl_NL.csv

  4. Configuration: Add or Update MAGENTO_THEME_LOCALE configuration in your .env file to specify which translations to use during testing.

By following these steps, you can seamlessly integrate language support into your testing workflow, ensuring that your Magento 2 store is thoroughly tested across different languages.

Troubleshooting

When getting the following error:

Translating file:  i18n/nl_NL.csv
Error: Invalid Record Length: expect 2, got 1 on line 284

Go to line 284 to find what is wrong in your csv file.


🚀 How to use the testing suite

The Testing Suite offers a variety of tests for your Magento 2 application in Chromium, Firefox, and Webkit.

Running tests

To run all tests, run the following command:

npx playwright test

This command will run all tests located in the base-tests directory. If you have custom tests in the tests folder, these will be used instead of their base-tests counterpart.

You can also run a specific test file:

npx playwright test example.spec.ts

The above commands will run your tests, then offer a report. You can also use the UI mode to see what the tests are doing, which is helpful for debugging. To open up UI mode, run this command:

npx playwright test --ui

Playwright also offers a trace view. While using the UI mode is seen as the default for developing and debugging tests, you may want to run the tests and collect a trace instead. This can be done with the following command:

npx playwright test --trace on

Skipping specific tests

Use --grep and --grep-invert to run subsets by tag. For example, to skip coupon-related tests:

npx playwright test --grep-invert @coupon-code

Setup tests no longer need to be skipped — they run as a project dependency, not as part of the regular suite. (See "Running the suite" above.)

Tags and Annotations

Most tests have been provided with a tag. This allows the user to run specific groups of tests, or skip specific tests. For example, tests that check the functionality of coupon codes are provided with the tag ‘@coupon-code’. To run only these tests, use:


npx playwright test –-grep @coupon-code

You can also run multiple tags with logic operators:


npx playwright test –-grep ”@coupon-code|@cart”

Use --grep-invert to run all tests except the tests with the specified test. Playwright docs offer more information: Playwright: Tag Annotations. The following command, for example, skips all tests with the tag ‘@coupon-code’.


npx playwright test –-grep-invert @coupon-code

Customizing the testing suite

The newly created tests folder will become your base of operations. In here, you should use the same folder structure that you see in base-tests. For example, if your login page works slightly differently from the demo website version, create a copy of login.page.ts and place it tests/poms/frontend/ and make your edits in this file. The next time you run the testing suite, it will automatically use these custom files.

Module Imports

To keep the project structure clean and maintainable, we use TypeScript path aliases via tsconfig.json. This allows you to use the @ prefix in imports instead of relative paths like ../../../.

Guidelines

Always use @ imports when importing from one of the core module folders, such as:

  • @poms – Page Object Models
  • @config – Test configuration and data
  • @utils – Shared utility functions
  • @steps – Common step definitions
  • @features – (Optional) Gherkin feature files

Correct Usage

import { UIReference } from '@config';
import { requireEnv } from '@utils/env.utils';

import HomePage from '@poms/frontend/home.page';

Wrong Usage

// ❌ Don't use relative paths
import { UIReference } from '../config';
import { requireEnv } from '../utils/env.utils';

import HomePage from '../poms/frontend/home.page';

Examples

Below are some example tests to illustrate how to write and structure your tests.

User registration test:


/**
 * @feature User Registration
 *   @scenario User successfully registers on the website
 *     @given I am on the registration page
 *     @when I fill in the registration form with valid data
 *     @and I submit the form
 *     @then I should see a confirmation message
 */
test('user_can_register_an_account', async ({ page }) => {
  // Implementation details
});

Checkout process test:

/**
 * @feature Product Checkout
 *   @scenario User completes a purchase
 *     @given I have a product in my cart
 *     @when I proceed to checkout
 *     @and I complete the checkout process
 *     @then I should receive an order confirmation
 */
test('User can complete the checkout process', async ({ page }) => {
  // Implementation details
});

Troubleshooting

If an @ import doesn’t work, make sure your local tsconfig.json matches the one provided by the npm package.


How to help

This package, and therefore the testing suite, is part of our open-source initiative to create an extensive library of end-to-end tests for Magento 2 stores. Do you want to help? Check out the elgentos Magento 2 Playwright repo on Github.

Scenarios

Up-to-date as of the [Unreleased] CHANGELOG entry.

Spec fileGroupTest
account.spec.tsAccount information actions:heavy_check_mark: Change_password
:heavy_check_mark:️ Update_my_e-mail_address
Account address book actions:heavy_check_mark: Add_an_address
:heavy_check_mark: Edit_existing_address
:heavy_check_mark: Missing_required_field_prevents_creation
:heavy_check_mark: Delete_an_address
Newsletter actions:heavy_check_mark: Update_newsletter_subscription
category.spec.ts:heavy_check_mark: Filter_category_on_size
:heavy_check_mark: Sort_category_by_price
:heavy_check_mark: Change_amount_of_products_shown
:heavy_check_mark: Switch_from_grid_to_list_view
footer.spec.tsFooter:heavy_check_mark: Footer_is_available
:heavy_check_mark: Footer_switch_currency
:heavy_check_mark: Footer_newsletter_subscription
mainmenu.spec.tsGuest tests (not logged in):heavy_check_mark: User_navigates_to_login
:heavy_check_mark: User_navigates_to_create_account
:heavy_check_mark: Navigate_to_category_page
:heavy_check_mark: Navigate_to_subcategory_page
:heavy_check_mark: Open_the_minicart
:heavy_check_mark: User_searches_for_product
User tests (logged in):heavy_check_mark: User_logs_out
:heavy_check_mark: Navigate_to_account_page
:heavy_check_mark: Navigate_to_wishlist
:heavy_check_mark: Navigate_to_orders
:heavy_check_mark: Navigate_to_address_book
healthcheck.spec.tsPage health checks:heavy_check_mark: Homepage_returns_200
:heavy_check_mark: Plp_returns_200
:heavy_check_mark: Pdp_returns_200
:heavy_check_mark: Checkout_returns_200
login.spec.ts:heavy_check_mark: User_logs_in_with_valid_credentials
:heavy_check_mark: Invalid_credentials_are_rejected
:heavy_check_mark: Login_fails_with_missing_password
home.spec.ts:heavy_check_mark: Add_product_on_homepage_to_cart
checkout.spec.tsCheckout (login required):heavy_check_mark: Address_is_pre_filled_in_checkout
:heavy_check_mark: Place_order_for_simple_product
Checkout (guest):heavy_check_mark: Add_coupon_code_in_checkout
:heavy_check_mark: Verify_price_calculations_in_checkout
:heavy_check_mark: Remove_coupon_code_from_checkout
:heavy_check_mark: Invalid_coupon_code_in_checkout_is_rejected
:heavy_check_mark: Guest_can_select_payment_methods
minicart.spec.tsMinicart (simple products):heavy_check_mark: Add_product_to_minicart_and_go_to_checkout
:heavy_check_mark: Add_product_to_minicart_and_go_to_cart
:heavy_check_mark: Change_product_quantity_in_minicart
:heavy_check_mark: Delete_product_from_minicart
:heavy_check_mark: Pdp_price_matches_minicart_price
Minicart (configurable products):heavy_check_mark: Configurable_pdp_price_matches_minicart_price
orderhistory.spec.tsOrder history tests:heavy_check_mark: Recent_order_is_visible_in_history
compare.spec.ts:heavy_check_mark: Add_product_to_cart_from_comparison_page
:heavy_check_mark: Guests_can_not_add_a_product_to_their_wishlist
:heavy_check_mark: Add_product_to_wishlist_from_comparison_page
contact.spec.ts:heavy_check_mark: Send_message_through_contact_form
shoppingcart.spec.tsCart functionalities (guest):heavy_check_mark: Add_product_to_cart
:heavy_check_mark: Product_remains_in_cart_after_login
:heavy_check_mark: Remove_product_from_cart
:heavy_check_mark: Change_product_quantity_in_cart
:heavy_check_mark: Add_coupon_code_in_cart
:heavy_check_mark: Remove_coupon_code_from_cart
:heavy_check_mark: Invalid_coupon_code_is_rejected
Price checking tests:heavy_check_mark: Simple_product_cart_data_consistent_from_PDP_to_checkout
:heavy_check_mark: Configurable_product_cart_data_consistent_from_PDP_to_checkout
register.spec.ts:heavy_check_mark: User_registers_an_account
product.spec.tsProduct page tests:heavy_check_mark: Add_product_to_compare
:warning: Add_product_to_wishlist (fixme: causes regular timeouts)
:warning: Leave a product review (Test currently fails due to error on website)
:heavy_check_mark: Open_pictures_in_lightbox_and_scroll
:heavy_check_mark: Change_number_of_reviews_shown_on_product_page
search.spec.tsSearch functionality:heavy_check_mark: Search_query_returns_multiple_results
:heavy_check_mark: User_can_find_a_specific_product_and_navigate_to_its_page
:heavy_check_mark: No_results_message_is_shown_for_unknown_query
init.setup.tsSetting up the testing environment:heavy_check_mark: Disable_login_captcha_and_enable_multiple_login
:heavy_check_mark: Set_coupon_codes
:heavy_check_mark: Create_test_accounts

Roadmap

The list below shows tests that will be written in the future. The list is subject to change and priorities/names are merely indicative.

Spec fileGroupTestPriority
account.spec.tsAccount overviewAccount_overview_shows_customer_nameLow
Customer_can_change_their_nameMedium
PasswordUser_can_reset_passwordHigh
OtherAll_account_subpage_show_correct_titlesLow
orderhistory.spec.tsOrder historyEmpty_order_history_can_be_viewedMedium
wishlist.spec.tsWishlist Item ActionsRemove_product_from_wishlistHigh
Update_quantity_of_item_in_wishlistMedium
Add_comment_to_item_in_wishlistMedium
User_can_share_wishlistLow
Add_all_wishlist_item_to_cartHigh
shoppingcart.spec.tsGuest to userCarts_are_merged_from_guest_to_userMedium
checkout.spec.tsLogin_from_checkout_keeps_cartMedium
All_payment_methods_workMedium
All_shipping_methods_workMedium
User_receives_confirmation_mail_after_orderHigh
User_receives_invoice_after_orderMedium
category.spec.tsGeneralBreadcrumbs_are_displayed_correctlyLow
Pagination_works_correctlyLow
home.spec.tsGeneralNavigate_to_homeLow
Cookiebanner_is_shown_if_no_cookiesMedium
Cookies_can_be_accepted_if_cookiebannerMedium
backend.spec.tsOrdersPlaced_orders_show_up_in_backendMedium
Order_can_be_editedMedium
Order_status_can_be_updatedMedium
product.spec.tsGeneralProduct_page_shows_title_and_imageLow
Product_page_shows_priceLow
Breadcrumbs_are_displayed_correctlyLow
User_can_see_reviewsLow
Place_reviewHigh
Product_page_indicates_in_stock_statusHigh
Product_cannot_be_added_to_cart_if_not_in_stockHigh
Configurable productNon_configured_products_cant_be_added_to_cartLow
Bundled productProduct_name_is_renderedLow
Price_goes_to_zero_when_all_associated_products_qty_is_zeroLow
Price_is_correct_sum_of_partsLow
Qty_of_products_in_bundle_are_shownLow
Add_bundled_product_to_cartLow
product.spec.tsSimple productSimple_tests_will_be_added_laterLow
product.spec.tsConfigurable productConfigurable_tests_will_be_added_laterLow
cmspages.spec.tsGeneralDefault_404_is_shown_on_nonexistent_urlMedium
contact.spec.tsGeneralForm_cannot_be_submitted_with_missing_fieldMedium
contact.spec.tsGeneralForm_cannot_be_submitted_with_incorrect_emailaddress_formatMedium