pomwright 0.0.6 → 0.0.8
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 +12 -0
- package/README.md +248 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +13 -3
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,2 +1,249 @@
|
|
|
1
1
|
# POMWright
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
    
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
POMWright is a TypeScript-based framework that implements the Page Object Model Design Pattern, designed specifically to augment Playwright's testing capabilities.
|
|
7
|
+
|
|
8
|
+
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.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
**Easy Creation of Page Object Classes:**
|
|
13
|
+
Extend a class with POMwright to create a Page Object Class (POC).
|
|
14
|
+
|
|
15
|
+
**Support for Multiple Domains/BaseURLs:**
|
|
16
|
+
Extend an abstract class with POMWright with a given BaseUrl, then create POCs for that BaseUrl by extending the abstract class.
|
|
17
|
+
|
|
18
|
+
**Custom Playwright Fixture Integration:** Create custom Playwright Fixtures from your POMWright POCs by extending test as POMWrightTestFixture.
|
|
19
|
+
|
|
20
|
+
**LocatorSchema Interface:** Offers a way to define and structure comprehensive locators per POC and share common locators between them.
|
|
21
|
+
|
|
22
|
+
**Advanced Locator Management:** Enables retrieval and automatic chaining of locators using LocatorSchemaPath.
|
|
23
|
+
|
|
24
|
+
**LocatorSchema Update/Updatess:** Allows updating single locators aswell as each locator a chained locator consist of, dynamically throughout a test.
|
|
25
|
+
|
|
26
|
+
**Deep Copy of LocatorSchemas:** Ensures original LocatorSchemas are reusable in tests.
|
|
27
|
+
|
|
28
|
+
**Custom HTML Logger:** Provides detailed logs for nested locators, aiding in debugging and integration with Playwright's HTML report.
|
|
29
|
+
|
|
30
|
+
**SessionStorage Handling:** Includes methods for managing sessionStorage, complementing Playwright's capabilities.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install pomwright --save-dev
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
**Simple example of creating a Page Object Class:**
|
|
41
|
+
|
|
42
|
+
```TS
|
|
43
|
+
import { Page, TestInfo } from "@playwright/test";
|
|
44
|
+
import { POMWright, POMWrightLogger } from "pomwright";
|
|
45
|
+
|
|
46
|
+
type LocatorSchemaPath =
|
|
47
|
+
| "content"
|
|
48
|
+
| "content.heading"
|
|
49
|
+
| "content.region.details"
|
|
50
|
+
| "content.region.details.button.edit";
|
|
51
|
+
|
|
52
|
+
export default class Profile extends POMWright<LocatorSchemaPath> {
|
|
53
|
+
constructor(page: Page, testInfo: TestInfo, pwrl: POMWrightLogger) {
|
|
54
|
+
super(page, testInfo, "https://someDomain.com", "/profile", Profile.name, pwrl);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected initLocatorSchemas() {
|
|
58
|
+
this.locators.addSchema("content", {
|
|
59
|
+
locator: ".main-content",
|
|
60
|
+
locatorMethod: GetByMethod.locator
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
this.locators.addSchema("content.heading", {
|
|
64
|
+
role: "heading",
|
|
65
|
+
roleOptions: {
|
|
66
|
+
name: "Your Profile"
|
|
67
|
+
}
|
|
68
|
+
locatorMethod: GetByMethod.role
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
this.locators.addSchema("content.region.details", {
|
|
72
|
+
role: "region",
|
|
73
|
+
roleOptions: {
|
|
74
|
+
name: "Profile Details"
|
|
75
|
+
}
|
|
76
|
+
locatorMethod: GetByMethod.role
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
this.locators.addSchema("content.region.details.button.edit", {
|
|
80
|
+
role: "button",
|
|
81
|
+
roleOptions: {
|
|
82
|
+
name: "Edit"
|
|
83
|
+
}
|
|
84
|
+
locatorMethod: GetByMethod.role
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// add your helper methods here...
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Creating a Custom Playwright Fixture for the Profile POC:**
|
|
93
|
+
|
|
94
|
+
```TS
|
|
95
|
+
import { POMWrightTestFixture as base } from "pomwright";
|
|
96
|
+
import Profile from "...";
|
|
97
|
+
|
|
98
|
+
type fixtures = {
|
|
99
|
+
profile: Profile;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export const test = base.extend<fixtures>({
|
|
103
|
+
profile: async ({ page, log }, use, testInfo) => {
|
|
104
|
+
const profile = new Profile(page, testInfo, log);
|
|
105
|
+
await use(profile);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Using the fixture in a Playwright tests:**
|
|
111
|
+
|
|
112
|
+
```TS
|
|
113
|
+
import { test } from ".../fixtures";
|
|
114
|
+
|
|
115
|
+
test("click edit button with a single locator", async ({ profile }) => {
|
|
116
|
+
// perform setup/navigation...
|
|
117
|
+
|
|
118
|
+
await profile.page.waitForURL(profile.fullUrl);
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* returns the locator resolving to the full locatorSchemaPath
|
|
122
|
+
*/
|
|
123
|
+
const editBtn = await profile.getLocator("content.region.details.button.edit");
|
|
124
|
+
|
|
125
|
+
await editBtn.click();
|
|
126
|
+
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```TS
|
|
131
|
+
import { test } from ".../fixtures";
|
|
132
|
+
|
|
133
|
+
test("click edit button with a nested locator", async ({ profile }) => {
|
|
134
|
+
// perform setup/navigation...
|
|
135
|
+
|
|
136
|
+
await profile.page.waitForURL(profile.fullUrl);
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* returns a nested/chained locator consisting of the 3 locators:
|
|
140
|
+
* content,
|
|
141
|
+
* content.region.details
|
|
142
|
+
* content.region.details.button.edit
|
|
143
|
+
*/
|
|
144
|
+
const editBtn = await profile.getNestedLocator("content.region.details.button.edit");
|
|
145
|
+
|
|
146
|
+
await editBtn.click();
|
|
147
|
+
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
```TS
|
|
152
|
+
import { test } from ".../fixtures";
|
|
153
|
+
|
|
154
|
+
test("specify index for nested locator(s)", async ({ profile }) => {
|
|
155
|
+
// perform setup/navigation...
|
|
156
|
+
|
|
157
|
+
await profile.page.waitForURL(profile.fullUrl);
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* returns a nested/chained locator consisting of the 3 locators:
|
|
161
|
+
* content
|
|
162
|
+
* content.region.details with .first()
|
|
163
|
+
* content.region.details.button.edit with .nth(1)
|
|
164
|
+
*/
|
|
165
|
+
const editBtn = await profile.getNestedLocator("content.region.details.button.edit", {
|
|
166
|
+
3: 0, 4: 1
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
await editBtn.click();
|
|
170
|
+
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
```TS
|
|
175
|
+
import { test } from ".../fixtures";
|
|
176
|
+
|
|
177
|
+
test("update a locator before use", async ({ profile }) => {
|
|
178
|
+
// perform setup/navigation...
|
|
179
|
+
|
|
180
|
+
await profile.page.waitForURL(profile.fullUrl);
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* returns a nested/chained locator consisting of the 3 locators:
|
|
184
|
+
* content,
|
|
185
|
+
* content.region.details
|
|
186
|
+
* content.region.details.button.edit (updated)
|
|
187
|
+
*/
|
|
188
|
+
const editBtn = await profile.getLocatorSchema("content.region.details.button.edit")
|
|
189
|
+
.update({ roleOptions: { name: "Edit details" }})
|
|
190
|
+
.getNestedLocator();
|
|
191
|
+
|
|
192
|
+
await editBtn.click();
|
|
193
|
+
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```TS
|
|
198
|
+
import { test } from ".../fixtures";
|
|
199
|
+
|
|
200
|
+
test("update a nested locator before use", async ({ profile }) => {
|
|
201
|
+
// perform setup/navigation...
|
|
202
|
+
|
|
203
|
+
await profile.page.waitForURL(profile.fullUrl);
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* returns a nested/chained locator consisting of the 3 locators:
|
|
207
|
+
* content,
|
|
208
|
+
* content.region.details (updated)
|
|
209
|
+
* content.region.details.button.edit
|
|
210
|
+
*/
|
|
211
|
+
const editBtn = await profile.getLocatorSchema("content.region.details.button.edit")
|
|
212
|
+
.updates({
|
|
213
|
+
2: { // content.region.details
|
|
214
|
+
locator: ".profile-details",
|
|
215
|
+
locatorMethod: GetByMethod.locator
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
.getNestedLocator();
|
|
219
|
+
|
|
220
|
+
await editBtn.click();
|
|
221
|
+
|
|
222
|
+
});
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```TS
|
|
226
|
+
import { test } from ".../fixtures";
|
|
227
|
+
|
|
228
|
+
test("make multiple versions of a locator", async ({ profile }) => {
|
|
229
|
+
// perform setup/navigation...
|
|
230
|
+
|
|
231
|
+
await profile.page.waitForURL(profile.fullUrl);
|
|
232
|
+
|
|
233
|
+
const editBtnSchema = profile.getLocatorSchema("content.region.details.button.edit");
|
|
234
|
+
|
|
235
|
+
const editBtn = await editBtnSchema.getLocator();
|
|
236
|
+
await editBtn.click();
|
|
237
|
+
|
|
238
|
+
editBtnSchema.update({ roleOptions: { name: "Edit details" }});
|
|
239
|
+
|
|
240
|
+
const editBtnUpdated = await editBtnSchema.getNestedLocator();
|
|
241
|
+
await editBtnUpdated.click();
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Calling profile.getLocatorSchema("content.region.details.button.edit") again
|
|
245
|
+
* will return a new deepCopy of the original LocatorSchema
|
|
246
|
+
*/
|
|
247
|
+
|
|
248
|
+
});
|
|
249
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -1085,7 +1085,7 @@ var BasePage2 = class {
|
|
|
1085
1085
|
// src/fixture/base.fixtures.ts
|
|
1086
1086
|
var import_test5 = require("@playwright/test");
|
|
1087
1087
|
var test3 = import_test5.test.extend({
|
|
1088
|
-
// biome-ignore lint/correctness/noEmptyPattern: <
|
|
1088
|
+
// biome-ignore lint/correctness/noEmptyPattern: <Playwright does not support the use of _, thus we must provide an empty object {}>
|
|
1089
1089
|
log: async ({}, use, testInfo) => {
|
|
1090
1090
|
const contextName = "TestCase";
|
|
1091
1091
|
const sharedLogEntry = [];
|
package/dist/index.mjs
CHANGED
|
@@ -1056,7 +1056,7 @@ var BasePage2 = class {
|
|
|
1056
1056
|
// src/fixture/base.fixtures.ts
|
|
1057
1057
|
import { test as base } from "@playwright/test";
|
|
1058
1058
|
var test3 = base.extend({
|
|
1059
|
-
// biome-ignore lint/correctness/noEmptyPattern: <
|
|
1059
|
+
// biome-ignore lint/correctness/noEmptyPattern: <Playwright does not support the use of _, thus we must provide an empty object {}>
|
|
1060
1060
|
log: async ({}, use, testInfo) => {
|
|
1061
1061
|
const contextName = "TestCase";
|
|
1062
1062
|
const sharedLogEntry = [];
|
package/package.json
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pomwright",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "POMWright is a complementary test framework for Playwright written in TypeScript.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/DyHex/POMWright"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/DyHex/POMWright#readme",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/DyHex/POMWright/issues"
|
|
12
|
+
},
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "Magnus Blütecher Dysthe"
|
|
15
|
+
},
|
|
16
|
+
"license": "Apache 2.0",
|
|
5
17
|
"main": "dist/index.js",
|
|
6
18
|
"module": "dist/index.mjs",
|
|
7
19
|
"types": "dist/index.d.ts",
|
|
@@ -11,8 +23,6 @@
|
|
|
11
23
|
"Page Object Model",
|
|
12
24
|
"Test Framework"
|
|
13
25
|
],
|
|
14
|
-
"author": "Magnus Blütecher Dysthe",
|
|
15
|
-
"license": "Apache 2.0",
|
|
16
26
|
"devDependencies": {
|
|
17
27
|
"@biomejs/biome": "^1.5.1",
|
|
18
28
|
"@changesets/cli": "^2.27.1",
|