pomwright 1.1.1 → 1.3.0
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/CHANGELOG.md +612 -0
- package/README.md +41 -312
- package/dist/index.d.mts +528 -128
- package/dist/index.d.ts +528 -128
- package/dist/index.js +333 -125
- package/dist/index.mjs +330 -122
- package/docs/BaseApi-explanation.md +63 -0
- package/docs/BasePage-explanation.md +96 -0
- package/docs/LocatorSchema-explanation.md +271 -0
- package/docs/LocatorSchemaPath-explanation.md +165 -0
- package/docs/PlaywrightReportLogger-explanation.md +56 -0
- package/docs/get-locator-methods-explanation.md +266 -0
- package/docs/intro-to-using-pomwright.md +899 -0
- package/docs/sessionStorage-methods-explanation.md +38 -0
- package/docs/tips-folder-structure.md +38 -0
- package/index.ts +2 -2
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -1,338 +1,67 @@
|
|
|
1
1
|
# POMWright
|
|
2
2
|
|
|
3
|
-

|
|
3
|
+

|
|
4
|
+
[](https://www.npmjs.com/package/pomwright)
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
[](https://www.npmjs.com/package/playwright)
|
|
8
|
+
[](https://www.ice.no/)
|
|
4
9
|
|
|
5
|
-
POMWright is a TypeScript
|
|
10
|
+
POMWright is a lightweight TypeScript framework that layers the Page Object Model on top of Playwright. It keeps locators, page objects, and fixtures organised so that UI tests stay readable and maintainable.
|
|
6
11
|
|
|
7
|
-
POMWright provides a way of abstracting the implementation details of a web page and encapsulating them into a reusable page object. This approach makes the tests easier to read, write and maintain, and helps reduce duplicated code by breaking down the code into smaller, reusable components, making the code more maintainable and organized.
|
|
12
|
+
POMWright provides a way of abstracting the implementation details of a web page and encapsulating them into a reusable page object. This approach makes the tests easier to read, write, and maintain, and helps reduce duplicated code by breaking down the code into smaller, reusable components, making the code more maintainable and organized.
|
|
8
13
|
|
|
9
|
-
##
|
|
14
|
+
## Key capabilities
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
- Quickly build maintainable Page Object Classes.
|
|
17
|
+
- Define any Playwright Locator through type-safe LocatorSchemas.
|
|
18
|
+
- Automatic chaining of locators with dot-delimited paths that map directly to Playwright locator methods.
|
|
19
|
+
- Auto-completion of LocatorSchemaPaths and sub-paths.
|
|
20
|
+
- Adjust locators on the fly without mutating the original definitions.
|
|
21
|
+
- Attach structured logs directly to the Playwright HTML report.
|
|
22
|
+
- Manage `sessionStorage` for browser setup and state hand‑off.
|
|
23
|
+
- Multiple Domains/BaseURLs
|
|
24
|
+
- Validate elements position in DOM through chaining
|
|
12
25
|
|
|
13
|
-
|
|
26
|
+
## Why POMWright?
|
|
14
27
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
### Custom Playwright Fixture Integration
|
|
20
|
-
|
|
21
|
-
Seamlessly integrate custom Playwright Fixtures with your POMWright POCs.
|
|
22
|
-
|
|
23
|
-
### LocatorSchema Interface
|
|
24
|
-
|
|
25
|
-
Define comprehensive locators for each POC and share common locators between them.
|
|
26
|
-
|
|
27
|
-
### Advanced Locator Management
|
|
28
|
-
|
|
29
|
-
Efficiently manage and chain locators through LocatorSchemaPaths.
|
|
30
|
-
|
|
31
|
-
### Dynamic Locator Schema Updates
|
|
32
|
-
|
|
33
|
-
Modify single or multiple locators within a chained locator dynamically during tests.
|
|
34
|
-
|
|
35
|
-
### Deep Copy of LocatorSchemas
|
|
36
|
-
|
|
37
|
-
Ensure that original LocatorSchemas remain immutable and reusable across tests.
|
|
38
|
-
|
|
39
|
-
### Custom HTML Logger
|
|
40
|
-
|
|
41
|
-
Gain insights with detailed logs for nested locators, integrated with Playwright's HTML report. Or use the Log fixture throughout your own POCs and tests to easily attach them to the HTML report based on log levels.
|
|
42
|
-
|
|
43
|
-
### SessionStorage Handling
|
|
44
|
-
|
|
45
|
-
Enhance your tests with advanced sessionStorage handling capabilities.
|
|
28
|
+
- **Stronger reliability** – centralised locator definitions reduce brittle inline selectors and make refactors visible at compile time.
|
|
29
|
+
- **Faster authoring** – strongly typed schema paths provide instant auto-complete, even for deeply nested segments and reusable fragments.
|
|
30
|
+
- **Easier maintenance** – shared helper patterns keep page objects, fixtures, and API clients aligned so teams can extend coverage without duplicating boilerplate.
|
|
31
|
+
- **Incremental adoption** – each helper sits on top of Playwright primitives, making it straightforward to migrate existing tests component by component.
|
|
46
32
|
|
|
47
33
|
## Installation
|
|
48
34
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
npm install pomwright --save-dev
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
or
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
pnpm i -D pomwright
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Playwright Example Project
|
|
62
|
-
|
|
63
|
-
Explore POMWright in action by diving into the example project located in the "example" folder. Follow these steps to get started:
|
|
64
|
-
|
|
65
|
-
### Install
|
|
66
|
-
|
|
67
|
-
Navigate to the "example" folder and install the necessary dependencies:
|
|
35
|
+
Install POMWright alongside Playwright:
|
|
68
36
|
|
|
69
37
|
```bash
|
|
70
|
-
pnpm
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
### Playwright browsers
|
|
74
|
-
|
|
75
|
-
Install or update Playwright browsers:
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
pnpm playwright install --with-deps
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Run tests
|
|
82
|
-
|
|
83
|
-
Execute tests across chromium, firefox, and webkit:
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
pnpm playwright test
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Parallelism
|
|
90
|
-
|
|
91
|
-
Control parallel test execution. By default, up to 4 tests run in parallel. Modify this setting as needed:
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
pnpm playwright test --workers 2 # Set the number of parallel workers
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Reports
|
|
98
|
-
|
|
99
|
-
After the tests complete, a Playwright HTML report is available in ./example/playwright-report. Open the index.html file in your browser to view the results.
|
|
100
|
-
|
|
101
|
-
## Usage
|
|
102
|
-
|
|
103
|
-
Dive into using POMWright with these examples:
|
|
104
|
-
|
|
105
|
-
### Create a Page Object Class (POC)
|
|
106
|
-
|
|
107
|
-
```TS
|
|
108
|
-
import { Page, TestInfo } from "@playwright/test";
|
|
109
|
-
import { BasePage, PlaywrightReportLogger, GetByMethod } from "pomwright";
|
|
110
|
-
|
|
111
|
-
type LocatorSchemaPath =
|
|
112
|
-
| "content"
|
|
113
|
-
| "content.heading"
|
|
114
|
-
| "content.region.details"
|
|
115
|
-
| "content.region.details.button.edit";
|
|
116
|
-
|
|
117
|
-
export default class Profile extends BasePage<LocatorSchemaPath> {
|
|
118
|
-
constructor(page: Page, testInfo: TestInfo, pwrl: PlaywrightReportLogger) {
|
|
119
|
-
super(page, testInfo, "https://someDomain.com", "/profile", Profile.name, pwrl);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
protected initLocatorSchemas() {
|
|
123
|
-
this.locators.addSchema("content", {
|
|
124
|
-
locator: ".main-content",
|
|
125
|
-
locatorMethod: GetByMethod.locator
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
this.locators.addSchema("content.heading", {
|
|
129
|
-
role: "heading",
|
|
130
|
-
roleOptions: {
|
|
131
|
-
name: "Your Profile"
|
|
132
|
-
},
|
|
133
|
-
locatorMethod: GetByMethod.role
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
this.locators.addSchema("content.region.details", {
|
|
137
|
-
role: "region",
|
|
138
|
-
roleOptions: {
|
|
139
|
-
name: "Profile Details"
|
|
140
|
-
},
|
|
141
|
-
locatorMethod: GetByMethod.role
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
this.locators.addSchema("content.region.details.button.edit", {
|
|
145
|
-
role: "button",
|
|
146
|
-
roleOptions: {
|
|
147
|
-
name: "Edit"
|
|
148
|
-
},
|
|
149
|
-
locatorMethod: GetByMethod.role
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// add your helper methods here...
|
|
154
|
-
}
|
|
38
|
+
pnpm add -D pomwright
|
|
39
|
+
# or
|
|
40
|
+
npm install --save-dev pomwright
|
|
155
41
|
```
|
|
156
42
|
|
|
157
|
-
|
|
43
|
+
## Documentation
|
|
158
44
|
|
|
159
|
-
|
|
160
|
-
import { test as base } from "pomwright";
|
|
161
|
-
import Profile from "...";
|
|
45
|
+
Start with the introduction and continue through the topics:
|
|
162
46
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
});
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Using the fixture in a Playwright tests
|
|
176
|
-
|
|
177
|
-
#### Click edit button with a single locator
|
|
178
|
-
|
|
179
|
-
```TS
|
|
180
|
-
import { test } from ".../fixtures";
|
|
181
|
-
|
|
182
|
-
test("click edit button with a single locator", async ({ profile }) => {
|
|
183
|
-
// perform setup/navigation...
|
|
184
|
-
|
|
185
|
-
await profile.page.waitForURL(profile.fullUrl);
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* returns the locator resolving to the full locatorSchemaPath
|
|
189
|
-
*/
|
|
190
|
-
const editBtn = await profile.getLocator("content.region.details.button.edit");
|
|
191
|
-
|
|
192
|
-
await editBtn.click();
|
|
193
|
-
|
|
194
|
-
});
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
#### Click edit button with a nested locator
|
|
198
|
-
|
|
199
|
-
```TS
|
|
200
|
-
import { test } from ".../fixtures";
|
|
201
|
-
|
|
202
|
-
test("click edit button with a nested locator", async ({ profile }) => {
|
|
203
|
-
// perform setup/navigation...
|
|
204
|
-
|
|
205
|
-
await profile.page.waitForURL(profile.fullUrl);
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* returns a nested/chained locator consisting of the 3 locators:
|
|
209
|
-
* content,
|
|
210
|
-
* content.region.details
|
|
211
|
-
* content.region.details.button.edit
|
|
212
|
-
*/
|
|
213
|
-
const editBtn = await profile.getNestedLocator("content.region.details.button.edit");
|
|
214
|
-
|
|
215
|
-
await editBtn.click();
|
|
216
|
-
|
|
217
|
-
});
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
#### Specify index for nested locator(s)
|
|
221
|
-
|
|
222
|
-
```TS
|
|
223
|
-
import { test } from ".../fixtures";
|
|
224
|
-
|
|
225
|
-
test("specify index for nested locator(s)", async ({ profile }) => {
|
|
226
|
-
// perform setup/navigation...
|
|
227
|
-
|
|
228
|
-
await profile.page.waitForURL(profile.fullUrl);
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* returns a nested/chained locator consisting of the 3 locators:
|
|
232
|
-
* content
|
|
233
|
-
* content.region.details with .first()
|
|
234
|
-
* content.region.details.button.edit with .nth(1)
|
|
235
|
-
*/
|
|
236
|
-
const editBtn = await profile.getNestedLocator("content.region.details.button.edit", {
|
|
237
|
-
3: 0, 4: 1
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
await editBtn.click();
|
|
241
|
-
|
|
242
|
-
});
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
#### Update a locator before use
|
|
246
|
-
|
|
247
|
-
```TS
|
|
248
|
-
import { test } from ".../fixtures";
|
|
249
|
-
|
|
250
|
-
test("update a locator before use", async ({ profile }) => {
|
|
251
|
-
// perform setup/navigation...
|
|
252
|
-
|
|
253
|
-
await profile.page.waitForURL(profile.fullUrl);
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* returns a nested/chained locator consisting of the 3 locators:
|
|
257
|
-
* content,
|
|
258
|
-
* content.region.details
|
|
259
|
-
* content.region.details.button.edit (updated)
|
|
260
|
-
*/
|
|
261
|
-
const editBtn = await profile.getLocatorSchema("content.region.details.button.edit")
|
|
262
|
-
.update({ roleOptions: { name: "Edit details" }})
|
|
263
|
-
.getNestedLocator();
|
|
264
|
-
|
|
265
|
-
await editBtn.click();
|
|
266
|
-
|
|
267
|
-
});
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
#### Update a nested locator before use
|
|
271
|
-
|
|
272
|
-
```TS
|
|
273
|
-
import { test } from ".../fixtures";
|
|
274
|
-
|
|
275
|
-
test("update a nested locator before use", async ({ profile }) => {
|
|
276
|
-
// perform setup/navigation...
|
|
277
|
-
|
|
278
|
-
await profile.page.waitForURL(profile.fullUrl);
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* returns a nested/chained locator consisting of the 3 locators:
|
|
282
|
-
* content,
|
|
283
|
-
* content.region.details (updated)
|
|
284
|
-
* content.region.details.button.edit
|
|
285
|
-
*/
|
|
286
|
-
const editBtn = await profile.getLocatorSchema("content.region.details.button.edit")
|
|
287
|
-
.updates({
|
|
288
|
-
2: { // content.region.details
|
|
289
|
-
locator: ".profile-details",
|
|
290
|
-
locatorMethod: GetByMethod.locator
|
|
291
|
-
}
|
|
292
|
-
})
|
|
293
|
-
.getNestedLocator();
|
|
294
|
-
|
|
295
|
-
await editBtn.click();
|
|
296
|
-
|
|
297
|
-
});
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
#### Make multiple versions of a locator
|
|
301
|
-
|
|
302
|
-
```TS
|
|
303
|
-
import { test } from ".../fixtures";
|
|
304
|
-
|
|
305
|
-
test("make multiple versions of a locator", async ({ profile }) => {
|
|
306
|
-
// perform setup/navigation...
|
|
307
|
-
|
|
308
|
-
await profile.page.waitForURL(profile.fullUrl);
|
|
309
|
-
|
|
310
|
-
const editBtnSchema = profile.getLocatorSchema("content.region.details.button.edit");
|
|
311
|
-
|
|
312
|
-
const editBtn = await editBtnSchema.getLocator();
|
|
313
|
-
await editBtn.click();
|
|
314
|
-
|
|
315
|
-
editBtnSchema.update({ roleOptions: { name: "Edit details" }});
|
|
316
|
-
|
|
317
|
-
const editBtnUpdated = await editBtnSchema.getNestedLocator();
|
|
318
|
-
await editBtnUpdated.click();
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Calling profile.getLocatorSchema("content.region.details.button.edit") again
|
|
322
|
-
* will return a new deepCopy of the original LocatorSchema
|
|
323
|
-
*/
|
|
324
|
-
|
|
325
|
-
});
|
|
326
|
-
```
|
|
47
|
+
1. [Intro to using POMWright](./docs/intro-to-using-pomwright.md)
|
|
48
|
+
2. [BasePage](./docs/BasePage-explanation.md)
|
|
49
|
+
3. [LocatorSchemaPath](./docs/LocatorSchemaPath-explanation.md)
|
|
50
|
+
4. [LocatorSchema](./docs/LocatorSchema-explanation.md)
|
|
51
|
+
5. [Locator schema helper methods](./docs/get-locator-methods-explanation.md)
|
|
52
|
+
6. [BaseApi](./docs/BaseApi-explanation.md)
|
|
53
|
+
7. [PlaywrightReportLogger](./docs/PlaywrightReportLogger-explanation.md)
|
|
54
|
+
8. [Session storage helpers](./docs/sessionStorage-methods-explanation.md)
|
|
55
|
+
9. [Tips for structuring locator files](./docs/tips-folder-structure.md)
|
|
327
56
|
|
|
328
57
|
## Troubleshooting and Support
|
|
329
58
|
|
|
330
|
-
If you encounter any issues or have questions, please check our issues page or reach out to us directly.
|
|
59
|
+
If you encounter any issues or have questions, please check our [issues page](https://github.com/DyHex/POMWright/issues) or reach out to us directly.
|
|
331
60
|
|
|
332
61
|
## Contributing
|
|
333
62
|
|
|
334
|
-
Pull Requests are welcome!
|
|
63
|
+
Pull Requests are welcome! Please open an issue or submit a pull request for any enhancements or bug fixes.
|
|
335
64
|
|
|
336
65
|
## License
|
|
337
66
|
|
|
338
|
-
POMWright is open-source software licensed under the Apache-2.0 license
|
|
67
|
+
POMWright is open-source software licensed under the [Apache-2.0 license](https://github.com/DyHex/POMWright/blob/main/LICENSE).
|