Using Playwright in a Multistore Setup
Different stores often require different testing setups. This can be due to:
- Store-specific features: Unique layouts, flows, or functionality that don’t apply to other stores.
- Independent QA teams: Each brand might have its own testing standards and workflows.
- Different testing strategies: One store may run a full regression suite, another just smoke tests.
To support this, each store in the Alokai Storefront can have its own Playwright configuration. Configs, mocks, and test files can be overridden per store — without affecting others.
This guide outlines how to:
- Override Playwright configuration per store
- Customize or extend mocked API endpoints
- Conditionally skip tests per store
- Understand the
.out
directory in context of test debugging
Overriding Playwright Configuration per Store
Overriding files follows File Override System described before.
Each store can define its own Playwright setup by creating a playwright
directory within its store folder. Configuration files like playwright.config.ts
, mocks, or helper modules placed here will override or extend the parent configuration.
The structure follows a nested pattern:
apps/
├── playwright/ # Base shared code
└── stores/
├── fashion-brand/
│ ├── playwright/ # Playwright customizations
│ │ └── playwright.config.ts # Custom playwright config
This approach allows each store to tailor test behavior, such as custom baseURLs, retries, timeouts, or test directories.
Mocked Endpoints
The Alokai Storefront provides a built-in mechanism for mocking API endpoints. apps/playwright/mocks
directory houses mocks for the specific middleware integrations your frontend applications use to make API calls.
Each middleware integration you're mocking has its own subdirectory within mocks. Currently, the structure looks like this:
apps/
└── playwright/
└── mocks/
├── cms/ # CMS Mocks
│ ├── data/ # Contains methods for defining mocked data within an in-memory database
│ └── endpoints # Mocked endpoints that retrieve data from in-memory database and send responses for your tests
└── unified/ # Unified API for E-commerce Mocks (directory contents are the same as for cms mocks)
Overriding and Extending Mocked Endpoints
In this section we'll go through the process of customizing mocked /getCategory
endpoint in child store named fashion-store
. The goal is to add a custom field products
to the mocked category entity. This field will hold all products that are supposed to be available within mocked category.
First, we'll copy over the original endpoint file from apps/playwright/mocks/unified/endpoints/getCategory.ts
to apps/stores/fashion-store/playwright/mocks/unified/endpoints/getCategory.ts
.
Next, we're adding support for custom products
field to get endpoint handler:
import type { MockFactoryContext } from '@core';
import { defineEventHandler } from 'h3';
-import { getCategory } from '@/mocks/unified/data';
+import { getCategory, getProducts } from '@/mocks/unified/data';
export default function ({ router }: MockFactoryContext) {
return router
.post(
`/getCategory`,
defineEventHandler(async () => {
return await getCategory();
}),
)
.get(
`/getCategory`,
defineEventHandler(async () => {
- return await getCategory();
+ const category = await getCategory();
+ (category as Record<string, unknown>).products = await getProducts();
+ return category;
}),
);
}
Done! Now when /getCategory
endpoint is fetched by the app then running Playwright integration tests it will respond with additional products
field.
Skipping Tests for Specific Stores
Certain tests might not apply to all stores due to differences in features or configurations. To skip a single test you can use File Override System described before.
Let's consider a scenario: in store named fashion-store
we're removed breadcrumbs from category page and we need to update tests for this store to reflect that change.
First, we need to copy the original test file from apps/playwright/tests/category.test.ts
to apps/stores/fashion-store/playwright/tests/category.test.ts
. Then, we can update it in one of two ways depending on our needs.
Removing test for the store completely
Removing tests is as simple as removing it's code
/* ... */
- test('should navigate with breadcrumbs', async ({ categoryPage }) => {
- await categoryPage.goto();
-
- await categoryPage.clickCategoryTreeItem();
- await categoryPage.hasLayoutWithCurrentCategory();
-
- await categoryPage.clickBreadcrumb('All products');
- await categoryPage.hasURLChangedTo('/category');
-
- await categoryPage.clickBreadcrumb('Home');
- await categoryPage.hasURLChangedTo('/');
- });
/* ... */
Skipping the test temporarily
For temporal test-skip, we can use .skip()
method from Playwright:
/* ... */
- test('should navigate with breadcrumbs', async ({ categoryPage }) => {
+ test.skip('should navigate with breadcrumbs', async ({ categoryPage }) => {
await categoryPage.goto();
await categoryPage.clickCategoryTreeItem();
await categoryPage.hasLayoutWithCurrentCategory();
await categoryPage.clickBreadcrumb('All products');
await categoryPage.hasURLChangedTo('/category');
await categoryPage.clickBreadcrumb('Home');
await categoryPage.hasURLChangedTo('/');
});
/* ... */
Now, the breadcrumbs test won't be running for store fashion-store
anymore~
Playwright tests debugging
The most important tool to debug integration tests is the Playwright UI mode. In multistore setup, it can be run with command:
yarn store test --ui
You can use --store-id
flag to run the tests only for a single store you're working on:
yarn store test --ui --store-id=fashion-store
The debug
option that is enabled by default, turns on the request logging for the fake middleware server.
This logs details of each incoming request to the console, helping you verify requests sent to your mocked endpoints.
Using Debugger in VS Code
Playwright allows user to debug the test files directly in VS Code IDE. If you'd like to use it, please remember: debugger should be set in the .out
directory.
Every yarn store
command moves necessary files to .out
directory in order to run the development applications and/or tests from there. That's why these are the files you'd like to set your debugger with.