@zohodesk/testinglibrary 0.0.42-n20-experimental → 0.0.44-n20-experimental
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/build/core/dataGenerator/DataGenerator.js +17 -12
- package/build/core/dataGenerator/validateGenerators.js +80 -0
- package/build/core/playwright/validateFeature.js +11 -0
- package/build/lib/cli.js +0 -7
- package/build/utils/commonUtils.js +0 -12
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/.github/agents/StepDefinitionValidator.agent.md +0 -49
- package/.github/agents/assertion-generator.agent.md +0 -37
- package/.github/agents/pom-generator.agent.md +0 -50
- package/.github/agents/selector-generator.agent.md +0 -47
- package/.github/agents/selector-recorder.agent.md +0 -99
- package/.github/agents/step-definition-generator.agent.md +0 -55
- package/.github/agents/steps-generation-orchestrator.agent.md +0 -75
- package/.github/copilot-instructions.md +0 -95
- package/.github/instructions/assertions.instructions.md +0 -36
- package/.github/instructions/dom-selectors.instructions.md +0 -33
- package/.github/instructions/pom-files.instructions.md +0 -48
- package/.github/instructions/step-definitions.instructions.md +0 -44
- package/.github/styleGuides/DomSelectors_README.md +0 -72
- package/.github/styleGuides/POM_README.md +0 -602
- package/.github/styleGuides/Steps_README.md +0 -653
- package/.vscode/mcp.json +0 -9
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
# Copilot Instructions — Desk Client App Test Automation
|
|
2
|
-
|
|
3
|
-
## Project Overview
|
|
4
|
-
|
|
5
|
-
This is a **BDD test automation** project for Zoho Desk using **Playwright** and a custom Cucumber-based framework (`@zohodesk/testinglibrary`). Tests live under `jsapps/supportapp/test-slices/uat/modules/`.
|
|
6
|
-
|
|
7
|
-
## Core Framework
|
|
8
|
-
|
|
9
|
-
- **Library**: `@zohodesk/testinglibrary` — provides `createBdd()` which returns `{ Given, When, Then, And }`
|
|
10
|
-
- **All steps are async**: every browser interaction must be `await`ed
|
|
11
|
-
- **Page automation**: Playwright `page` object from context
|
|
12
|
-
|
|
13
|
-
## Module Folder Structure (Mandatory)
|
|
14
|
-
|
|
15
|
-
Every module must follow this hierarchy:
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
modules/
|
|
19
|
-
<ModuleName>/
|
|
20
|
-
index.js # Barrel exports for the module
|
|
21
|
-
steps/
|
|
22
|
-
<FeatureName>.spec.js # Step definitions
|
|
23
|
-
feature-files/
|
|
24
|
-
<FeatureName>.feature # Gherkin scenarios
|
|
25
|
-
data-generators/
|
|
26
|
-
generators.json # Test data
|
|
27
|
-
page-object-model/
|
|
28
|
-
<PageName>.js # Page objects (factory functions)
|
|
29
|
-
index.js # POM barrel re-exports
|
|
30
|
-
assertions/
|
|
31
|
-
<ModuleName>Assertions.js # Module-specific assertions
|
|
32
|
-
dom-selectors/
|
|
33
|
-
<moduleName>Selectors.js # Centralized selector constants
|
|
34
|
-
utils/
|
|
35
|
-
<moduleName>Utils.js # Helper functions
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## File Naming Conventions
|
|
39
|
-
|
|
40
|
-
| Artifact | Convention | Example |
|
|
41
|
-
|-------------------|---------------------|------------------------------|
|
|
42
|
-
| Module folders | PascalCase | `Ticket/`, `CustomModule/` |
|
|
43
|
-
| Spec files | PascalCase `.spec.js` | `SetupNavigation.spec.js` |
|
|
44
|
-
| Feature files | PascalCase `.feature` | `TicketsCRUD.feature` |
|
|
45
|
-
| POM files | PascalCase `.js` | `TicketDetailView.js` |
|
|
46
|
-
| Assertion files | PascalCase + `Assertions` | `SetupAssertions.js` |
|
|
47
|
-
| Selector files | PascalCase + `Selectors` | `TicketSelectors.js` |
|
|
48
|
-
| Utility files | PascalCase + `Utils` | `TicketUtils.js` |
|
|
49
|
-
| Barrel files | `index.js` | `index.js` |
|
|
50
|
-
|
|
51
|
-
## Step Definition Rules
|
|
52
|
-
|
|
53
|
-
1. **Import pattern**: Always start with `import { createBdd } from '@zohodesk/testinglibrary'`
|
|
54
|
-
2. **Import order**: framework → cross-module → local POM (via barrel) → assertions → constants → BDD destructuring
|
|
55
|
-
3. **Given/When/Then separation**: Given = setup, When = action, Then = assertion only
|
|
56
|
-
4. **No branching logic** (`if/else`, `switch`, ternary) inside step bodies — delegates to POM
|
|
57
|
-
5. **Use `{string}` parameters** for dynamic values
|
|
58
|
-
6. **Context destructuring**: only destructure what you use (`page`, `i18N`, `getMetaInfo`, `cacheLayer`, `context`, `executionContext`, `actorContext`)
|
|
59
|
-
7. **Then steps are assertions only** — no clicks, fills, or navigation
|
|
60
|
-
8. **No hardcoded English strings** — use `i18N()` (async function, always await)
|
|
61
|
-
9. **No hardcoded locators** in step files — all DOM access via POM methods
|
|
62
|
-
10. **Use `cacheLayer`** for data sharing between steps (not globals or `process.env`)
|
|
63
|
-
|
|
64
|
-
## POM Rules
|
|
65
|
-
|
|
66
|
-
1. **Factory functions only** — no classes, `this`, `new`, or `constructor`
|
|
67
|
-
2. **One factory per page/panel** — destructure only needed context properties
|
|
68
|
-
3. **Keep assertions outside POM** — POMs return locators/values, never validate
|
|
69
|
-
4. **Import selectors from `dom-selectors/`** — no raw locators in POM methods
|
|
70
|
-
5. **Validate DOM readiness** with `waitFor()` before every action
|
|
71
|
-
6. **Use `i18N`** for all user-facing strings
|
|
72
|
-
7. **No arbitrary waits** — never use `page.waitForTimeout()`
|
|
73
|
-
8. **Export via barrel** — `page-object-model/index.js` re-exports all POMs
|
|
74
|
-
|
|
75
|
-
## Selector Rules
|
|
76
|
-
|
|
77
|
-
1. **Pure constants only** — no Playwright actions, assertions, or business logic
|
|
78
|
-
2. **SCREAMING_SNAKE_CASE** for static selectors, **camelCase** for builder helpers
|
|
79
|
-
3. **Prefer stable selectors**: `data-test-id` > `data-id` > `id` > `name` > ARIA > labels
|
|
80
|
-
4. **No duplication** of selector strings
|
|
81
|
-
5. **Step files never import selectors directly** — always access via POM
|
|
82
|
-
|
|
83
|
-
## Assertion Rules
|
|
84
|
-
|
|
85
|
-
1. **Use `Assertions` library** from `../../_assertions/Assertions`
|
|
86
|
-
2. **Module-specific assertions** in `assertions/<ModuleName>Assertions.js` when reused across 2+ spec files
|
|
87
|
-
3. **No assertions in POM files** — assertion files receive locators/values from POMs
|
|
88
|
-
4. **Prefer Playwright auto-waiting assertions** over plain JS comparison
|
|
89
|
-
|
|
90
|
-
## Style Guides
|
|
91
|
-
|
|
92
|
-
Detailed rules are in `.github/styleGuides/`:
|
|
93
|
-
- `Steps_README.md` — step definition patterns
|
|
94
|
-
- `POM_README.md` — page object model patterns
|
|
95
|
-
- `DomSelectors_README.md` — selector file patterns
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
applyTo: "**/test-slices/**/assertions/*.js"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Assertions Layer
|
|
6
|
-
|
|
7
|
-
Module-level assertion files contain reusable validation helpers built by composing methods from the central `Assertion.js` library.
|
|
8
|
-
|
|
9
|
-
## File Pattern
|
|
10
|
-
|
|
11
|
-
```javascript
|
|
12
|
-
// assertions/TicketAssertions.js
|
|
13
|
-
import Assertions from '../../_assertions/Assertions';
|
|
14
|
-
|
|
15
|
-
const TicketAssertions = {
|
|
16
|
-
async verifyTicketSubject(subjectElem, expectedSubject) {
|
|
17
|
-
await Assertions.isElementVisible(subjectElem);
|
|
18
|
-
await Assertions.isElementHaveText(subjectElem, expectedSubject);
|
|
19
|
-
},
|
|
20
|
-
|
|
21
|
-
async verifyCommentAuthored(authorElem, expectedName) {
|
|
22
|
-
await Assertions.isElementVisible(authorElem);
|
|
23
|
-
await Assertions.isElementContainText(authorElem, expectedName);
|
|
24
|
-
},
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export default TicketAssertions;
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Strict Rules
|
|
31
|
-
|
|
32
|
-
- **No Actions:** Assertion files must never click, fill, or navigate.
|
|
33
|
-
|
|
34
|
-
- **No POM Imports:** Assertion files must never import POMs. They receive locators as arguments.
|
|
35
|
-
|
|
36
|
-
- **Central First:** Always prefer Assertions.* over raw expect().
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
applyTo: "**/test-slices/**/dom-selectors/*.js"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Dom Selectors Layer
|
|
6
|
-
|
|
7
|
-
Selector files are the single source of truth for all raw locator strings. Nothing else.
|
|
8
|
-
|
|
9
|
-
## File Format
|
|
10
|
-
|
|
11
|
-
```javascript
|
|
12
|
-
// dom-selectors/TicketSelectors.js
|
|
13
|
-
|
|
14
|
-
export const TicketSelectors = {
|
|
15
|
-
// Static — SCREAMING_SNAKE_CASE
|
|
16
|
-
COMMENT_INPUT: '[data-test-id="comment-input"]',
|
|
17
|
-
SAVE_COMMENT: '[data-test-id="save-comment-btn"]',
|
|
18
|
-
TICKET_ROW: '[data-id^="ticket_"]',
|
|
19
|
-
|
|
20
|
-
// Dynamic builder — camelCase arrow function
|
|
21
|
-
ticketRowById: (ticketId) => `[data-id="table_${ticketId}"]`,
|
|
22
|
-
ticketsByStatus: (status) => `[data-test-id="ticket-${status}"]`,
|
|
23
|
-
};
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Rules
|
|
27
|
-
|
|
28
|
-
- **Pure constants only** — no Playwright actions, assertions, waits, or business logic
|
|
29
|
-
- **SCREAMING_SNAKE_CASE** for static selector keys
|
|
30
|
-
- **camelCase** for dynamic builder helper functions
|
|
31
|
-
- **No duplication** of selector strings
|
|
32
|
-
- **Prefer stable selectors**: `data-test-id` > `data-id` > `id` > `name` > ARIA > labels
|
|
33
|
-
- **Step files never import selectors** — only POMs consume these files
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
applyTo: "**/test-slices/**/page-object-model/*.js"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Page Object Model Layer
|
|
6
|
-
|
|
7
|
-
POM files contain all reusable UI interaction logic. Each file exports a single **factory function** (never a class).
|
|
8
|
-
|
|
9
|
-
## Factory Function Pattern
|
|
10
|
-
|
|
11
|
-
```javascript
|
|
12
|
-
import { MySelectors } from '../dom-selectors/MySelectors';
|
|
13
|
-
|
|
14
|
-
const MyPagePOM = ({ page, i18N, getMetaInfo }) => {
|
|
15
|
-
// Getter — synchronous, returns Locator
|
|
16
|
-
const getSubmitButton = () => page.locator(MySelectors.SUBMIT_BTN);
|
|
17
|
-
|
|
18
|
-
// Action — async, waitFor() before every interaction
|
|
19
|
-
const clickSubmit = async () => {
|
|
20
|
-
const btn = getSubmitButton();
|
|
21
|
-
await btn.waitFor();
|
|
22
|
-
await btn.click();
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
// i18N usage
|
|
26
|
-
const getElementByLabel = async (labelKey) => {
|
|
27
|
-
const label = await i18N(labelKey);
|
|
28
|
-
return page.getByText(label, { exact: true });
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
return { getSubmitButton, clickSubmit, getElementByLabel };
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export { MyPagePOM };
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Rules
|
|
38
|
-
|
|
39
|
-
- **Factory functions only** — no classes, `this`, `new`, `constructor`
|
|
40
|
-
- **Destructure only needed context** from `({ page, i18N, getMetaInfo, cacheLayer, executionContext, actorContext })`
|
|
41
|
-
- **Import selectors** from `../dom-selectors/` — no raw locator strings
|
|
42
|
-
- **Getter methods** return Playwright Locators (synchronous, no `await`)
|
|
43
|
-
- **Action methods** are async with `await` on Playwright actions
|
|
44
|
-
- **DOM readiness**: call `element.waitFor()` before every action
|
|
45
|
-
- **Use `await i18N('key')`** for all user-facing strings
|
|
46
|
-
- **No assertions** — POMs return locators/values, never validate
|
|
47
|
-
- **No `page.waitForTimeout()`** — use element-based waits only
|
|
48
|
-
- **No `.first()` or `.last()`** for ambiguity — use unique identifiers
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
applyTo: "**/test-slices/**/steps/*.spec.js"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Step Definitions Layer
|
|
6
|
-
|
|
7
|
-
BDD step definition files live in each module's `steps/` folder. They are the **thin wiring layer** between Gherkin feature files and POM factory functions.
|
|
8
|
-
|
|
9
|
-
## Standard File Structure
|
|
10
|
-
|
|
11
|
-
```javascript
|
|
12
|
-
import { createBdd } from '@zohodesk/testinglibrary';
|
|
13
|
-
import { XyzPOM, AbcPOM } from '../index';
|
|
14
|
-
import Assertions from '../../_assertions/Assertions';
|
|
15
|
-
|
|
16
|
-
const { Given, When, Then } = createBdd();
|
|
17
|
-
|
|
18
|
-
Given('the user is in {string} department', async ({ page, i18N }, department) => {
|
|
19
|
-
// navigation / precondition only
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
When('the user clicks {string} button', async ({ page, i18N }, buttonLabel) => {
|
|
23
|
-
const pom = XyzPOM({ page, i18N });
|
|
24
|
-
await pom.clickButton(buttonLabel);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
Then('the {string} element should be visible', async ({ page, i18N }, label) => {
|
|
28
|
-
const pom = XyzPOM({ page, i18N });
|
|
29
|
-
const elem = await pom.getElement(label);
|
|
30
|
-
await Assertions.isElementVisible(elem);
|
|
31
|
-
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Step Rules
|
|
35
|
-
|
|
36
|
-
- **Given** = setup only (navigation, preconditions)
|
|
37
|
-
- **When** = user actions only (clicks, fills, submissions)
|
|
38
|
-
- **Then** = assertions ONLY (no clicks, fills, navigation)
|
|
39
|
-
- **No branching** (`if/else`, `switch`, ternary) in step bodies — delegate to POM
|
|
40
|
-
- Use `{string}` for dynamic values
|
|
41
|
-
- Destructure only needed context properties
|
|
42
|
-
- Use `await i18N('key')` for all user-facing strings
|
|
43
|
-
- Use `cacheLayer` for sharing data between steps
|
|
44
|
-
- All DOM access via POM methods — no raw selectors
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# DOM Selectors Structure Guide
|
|
2
|
-
|
|
3
|
-
## Purpose
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
This document describes the strict rules and naming conventions for selector files used in the `dom-selectors/` folder of each test module. Selector files are the **single source of truth** for all raw locator strings.
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## What `dom-selectors/` Should Contain
|
|
11
|
-
|
|
12
|
-
Store selector constants and selector builder helpers here.
|
|
13
|
-
|
|
14
|
-
Examples:
|
|
15
|
-
|
|
16
|
-
- one file per major page, panel, or UI responsibility
|
|
17
|
-
- grouped selector constants exported as a single object
|
|
18
|
-
- selector builder helpers for dynamic locators
|
|
19
|
-
|
|
20
|
-
This keeps selector updates centralized and prevents raw locator strings from spreading across POM files and step files.
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## 1. Naming Conventions (Strict)
|
|
25
|
-
|
|
26
|
-
To ensure consistency across the framework, you must strictly adhere to these casing rules:
|
|
27
|
-
|
|
28
|
-
* **Files:** Must use **PascalCase** and end in `Selectors.js` (e.g., `TicketSelectors.js`).
|
|
29
|
-
* **Exported Object:** Must match the file name exactly in **PascalCase** (e.g., `export const TicketSelectors`).
|
|
30
|
-
* **Static Keys:** Must use **SCREAMING_SNAKE_CASE** (e.g., `COMMENT_INPUT: '[data-test-id="comment"]'`).
|
|
31
|
-
* **Dynamic Builder Functions:** Must use **camelCase** (e.g., `ticketRowById: (id) => ...`).
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## 2. The Selector Priority Hierarchy (For UI Inspection)
|
|
36
|
-
|
|
37
|
-
When capturing live selectors (e.g., via Playwright MCP) or writing new ones, you MUST prefer stable identifiers in this exact order:
|
|
38
|
-
|
|
39
|
-
1. `data-test-id` (Highest Priority)
|
|
40
|
-
2. `data-id`
|
|
41
|
-
3. `id`
|
|
42
|
-
4. `name`
|
|
43
|
-
5. ARIA roles
|
|
44
|
-
6. Labels / Placeholders (Lowest acceptable)
|
|
45
|
-
|
|
46
|
-
**Absolutely Forbidden Selectors:**
|
|
47
|
-
|
|
48
|
-
- Deep, brittle CSS chains (`div > div > span > ul > li > a`).
|
|
49
|
-
- Index-based locators (`nth-child`, `.first()`, `.last()`) when a stable identifier is available.
|
|
50
|
-
- Selectors tied to text content that changes across locales/translations.
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## 3. Architectural Isolation Rules
|
|
55
|
-
|
|
56
|
-
* **Rule 1: Keep it Pure.** Selector files must ONLY contain locator strings and dynamic locator functions. They must NEVER contain Playwright actions (`click()`), assertions (`expect()`), waits, or business logic.
|
|
57
|
-
|
|
58
|
-
* **Rule 2: No Duplication.** Never repeat the same raw selector string twice.
|
|
59
|
-
|
|
60
|
-
* **Rule 3: No Step File Imports.** Step files (`.spec.js`) are strictly forbidden from importing from `dom-selectors/`. The flow is always: **Step File → POM → Selector File**.
|
|
61
|
-
|
|
62
|
-
## Validation Checklist
|
|
63
|
-
*To be used by the Step Definition Validator Agent:*
|
|
64
|
-
|
|
65
|
-
1. [ ] Is the file placed in the correct `dom-selectors/` folder?
|
|
66
|
-
2. [ ] Does the file name and exported object use `PascalCase` (e.g., `TicketSelectors`)?
|
|
67
|
-
3. [ ] Are static keys `SCREAMING_SNAKE_CASE` and dynamic functions `camelCase`?
|
|
68
|
-
4. [ ] Are there ZERO Playwright actions, assertions, or `page.` calls in the file?
|
|
69
|
-
5. [ ] Are stable selectors (`data-test-id`) used instead of brittle DOM paths (`nth-child`)?
|
|
70
|
-
6. [ ] Is the framework free of Step files directly importing this selector file?
|
|
71
|
-
|
|
72
|
-
---
|