write-playwright-campaigns
Read @.ai/Component/Playwright/CONTEXT.md for conventions (testIdentifier, baseContext, Mocha structure, POM usage).
1. Directory and naming
Place campaigns in tests/UI/campaigns/functional/BO/{XX_section}/{XX_subsection}/:
- Follow existing numbering convention (
XX_ prefix)
- Each campaign file:
XX_descriptiveName.ts
- CRUD is typically
01_, filter is 02_, bulk is 03_, position is 04_, tab-specific start at 05_
2. Campaign boilerplate
Every campaign follows this structure:
import testContext from '@utils/testContext';
import {expect} from 'chai';
import {
boDashboardPage, boLoginPage, bo{Domain}Page, bo{Domain}CreatePage,
type BrowserContext, Faker{Domain}, type Page, utilsPlaywright,
} from '@prestashop-core/ui-testing';
const baseContext: string = 'functional_BO_{section}_{subsection}_{campaignName}';
describe('BO - {Section} : {Campaign description}', async () => {
let browserContext: BrowserContext;
let page: Page;
before(async function () {
browserContext = await utilsPlaywright.createBrowserContext(this.browser);
page = await utilsPlaywright.newTab(browserContext);
});
after(async () => {
await utilsPlaywright.closeBrowserContext(browserContext);
});
it('should login in BO', async function () {
await testContext.addContextItem(this, 'testIdentifier', 'loginBO', baseContext);
// ...login steps...
});
// ... test steps ...
});
3. CRUD campaign (01_CRUD{Domain}.ts)
- Create: navigate to add page, fill fields using
Faker{Domain}, save, assert success message
- Verify in list: navigate to index, assert entity visible in grid
- Edit: navigate to edit, change fields, save, assert success message
- Verify edit: confirm updated values in grid
- Delete: click delete row action, confirm modal, assert entity removed
4. Filter/sort campaign (02_filterSort{Domain}s.ts)
- Create entities with distinct values for each filterable field
- For each filter: apply → assert matching rows → reset → assert all rows
- For each sortable column: sort ascending → verify order → sort descending → verify reverse
- Use data-driven patterns with
forEach for multiple filter tests
5. Bulk actions campaign (03_quickEditAndBulkActions.ts)
Conditional — only if bulk actions exist:
- Create multiple entities
- Quick-edit toggle: click toggle switch, verify status changed without page reload (AJAX)
- Bulk enable/disable: select rows, click bulk action, verify status change
- Bulk delete: select rows, click bulk delete, confirm modal, verify removed
6. Position campaign (04_changePosition.ts)
Conditional — only if entity has PositionColumn:
- Create entities with distinct names
- Read initial order
- Drag row to new position using
page.dragAndDrop()
- Verify new order in DOM
- Reload page and verify persistence — critical to confirm DB was updated
7. Per-tab campaigns (05_tabName.ts, 06_tabName.ts, ...)
Conditional — only for multi-tab forms:
- One campaign per form tab
- Create entity with minimal data
- Navigate to edit, switch to target tab
- Fill every field in that tab
- Save, reload, verify each field persisted
- Test multilingual fields in at least 2 languages
8. Common tests (reusable blocks)
Check tests/UI/commonTests/BO/ for existing reusable describe blocks:
import {createProductTest, deleteProductTest} from '@commonTests/BO/catalog/product';
// Use as pre/post test setup
createProductTest(productData, baseContext);
// ... your test ...
deleteProductTest(productData, baseContext);
Import and reuse these instead of duplicating setup/teardown logic.
Rules
Conventions (testIdentifier, function() not arrow, feature flag setup, toggle AJAX, drag-and-drop, per-tab campaigns, campaign numbering) are in Playwright/CONTEXT.md. Skill-specific reminders:
- Assert success flash after every create/edit/delete — never assume success
- Use page object methods for interactions — never write raw selectors in campaigns
- Campaigns import from
@prestashop-core/ui-testing — page objects and data are in the external library
1---
2name: write-playwright-campaigns
3description: >
4 Write Playwright test campaigns for a migrated entity: CRUD lifecycle, bulk actions,
5 filter/sort, position reorder, and per-tab field verification. Campaigns live in
6 the core repo and import page objects from ui-testing-library. Trigger:
7 "write Playwright tests for {Domain}".
8needs: [create-playwright-page-objects, create-playwright-test-data, create-admin-routing]
9produces: "Test campaign files in tests/UI/campaigns/functional/BO/{section}/{subsection}/"
10subagent: optional
11---
12
13# write-playwright-campaigns
14
15Read `@.ai/Component/Playwright/CONTEXT.md` for conventions (testIdentifier, baseContext, Mocha structure, POM usage).
16
17## 1. Directory and naming
18
19Place campaigns in `tests/UI/campaigns/functional/BO/{XX_section}/{XX_subsection}/`:
20
21- Follow existing numbering convention (`XX_` prefix)
22- Each campaign file: `XX_descriptiveName.ts`
23- CRUD is typically `01_`, filter is `02_`, bulk is `03_`, position is `04_`, tab-specific start at `05_`
24
25## 2. Campaign boilerplate
26
27Every campaign follows this structure:
28
29```typescript
30import testContext from '@utils/testContext';
31import {expect} from 'chai';
32import {
33 boDashboardPage, boLoginPage, bo{Domain}Page, bo{Domain}CreatePage,
34 type BrowserContext, Faker{Domain}, type Page, utilsPlaywright,
35} from '@prestashop-core/ui-testing';
36
37const baseContext: string = 'functional_BO_{section}_{subsection}_{campaignName}';
38
39describe('BO - {Section} : {Campaign description}', async () => {
40 let browserContext: BrowserContext;
41 let page: Page;
42
43 before(async function () {
44 browserContext = await utilsPlaywright.createBrowserContext(this.browser);
45 page = await utilsPlaywright.newTab(browserContext);
46 });
47
48 after(async () => {
49 await utilsPlaywright.closeBrowserContext(browserContext);
50 });
51
52 it('should login in BO', async function () {
53 await testContext.addContextItem(this, 'testIdentifier', 'loginBO', baseContext);
54 // ...login steps...
55 });
56
57 // ... test steps ...
58});
59```
60
61## 3. CRUD campaign (`01_CRUD{Domain}.ts`)
62
63- **Create:** navigate to add page, fill fields using `Faker{Domain}`, save, assert success message
64- **Verify in list:** navigate to index, assert entity visible in grid
65- **Edit:** navigate to edit, change fields, save, assert success message
66- **Verify edit:** confirm updated values in grid
67- **Delete:** click delete row action, confirm modal, assert entity removed
68
69## 4. Filter/sort campaign (`02_filterSort{Domain}s.ts`)
70
71- Create entities with distinct values for each filterable field
72- For each filter: apply → assert matching rows → reset → assert all rows
73- For each sortable column: sort ascending → verify order → sort descending → verify reverse
74- Use data-driven patterns with `forEach` for multiple filter tests
75
76## 5. Bulk actions campaign (`03_quickEditAndBulkActions.ts`)
77
78Conditional — only if bulk actions exist:
79
80- Create multiple entities
81- **Quick-edit toggle:** click toggle switch, verify status changed without page reload (AJAX)
82- **Bulk enable/disable:** select rows, click bulk action, verify status change
83- **Bulk delete:** select rows, click bulk delete, confirm modal, verify removed
84
85## 6. Position campaign (`04_changePosition.ts`)
86
87Conditional — only if entity has PositionColumn:
88
89- Create entities with distinct names
90- Read initial order
91- Drag row to new position using `page.dragAndDrop()`
92- Verify new order in DOM
93- **Reload page and verify persistence** — critical to confirm DB was updated
94
95## 7. Per-tab campaigns (`05_tabName.ts`, `06_tabName.ts`, ...)
96
97Conditional — only for multi-tab forms:
98
99- One campaign per form tab
100- Create entity with minimal data
101- Navigate to edit, switch to target tab
102- Fill every field in that tab
103- Save, reload, verify each field persisted
104- Test multilingual fields in at least 2 languages
105
106## 8. Common tests (reusable blocks)
107
108Check `tests/UI/commonTests/BO/` for existing reusable describe blocks:
109
110```typescript
111import {createProductTest, deleteProductTest} from '@commonTests/BO/catalog/product';
112
113// Use as pre/post test setup
114createProductTest(productData, baseContext);
115// ... your test ...
116deleteProductTest(productData, baseContext);
117```
118
119Import and reuse these instead of duplicating setup/teardown logic.
120
121## Rules
122
123Conventions (testIdentifier, `function()` not arrow, feature flag setup, toggle AJAX, drag-and-drop, per-tab campaigns, campaign numbering) are in [Playwright/CONTEXT.md](../../CONTEXT.md). Skill-specific reminders:
124
125- Assert success flash after every create/edit/delete — never assume success
126- Use page object methods for interactions — never write raw selectors in campaigns
127- Campaigns import from `@prestashop-core/ui-testing` — page objects and data are in the external library