pomwright 1.5.0 → 2.0.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.
Files changed (117) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +5 -5
  3. package/dist/index.d.mts +91 -989
  4. package/dist/index.d.ts +91 -989
  5. package/dist/index.js +627 -1887
  6. package/dist/index.mjs +633 -1888
  7. package/package.json +9 -11
  8. package/AGENTS.md +0 -37
  9. package/docs/v1/BaseApi-explanation.md +0 -63
  10. package/docs/v1/BasePage-explanation.md +0 -96
  11. package/docs/v1/LocatorSchema-explanation.md +0 -271
  12. package/docs/v1/LocatorSchemaPath-explanation.md +0 -165
  13. package/docs/v1/PlaywrightReportLogger-explanation.md +0 -56
  14. package/docs/v1/get-locator-methods-explanation.md +0 -250
  15. package/docs/v1/intro-to-using-pomwright.md +0 -899
  16. package/docs/v1/sessionStorage-methods-explanation.md +0 -38
  17. package/docs/v1/tips-folder-structure.md +0 -38
  18. package/docs/v1-to-v2-migration/bridge-migration-guide.md +0 -159
  19. package/docs/v1-to-v2-migration/direct-migration-guide.md +0 -238
  20. package/docs/v1-to-v2-migration/v1-to-v2-comparison.md +0 -547
  21. package/docs/v2/PageObject.md +0 -293
  22. package/docs/v2/composing-locator-modules.md +0 -93
  23. package/docs/v2/locator-registry.md +0 -693
  24. package/docs/v2/logging.md +0 -168
  25. package/docs/v2/overview.md +0 -515
  26. package/docs/v2/session-storage.md +0 -160
  27. package/index.ts +0 -75
  28. package/intTestV2/.env +0 -0
  29. package/intTestV2/fixtures/testApp.fixtures.ts +0 -43
  30. package/intTestV2/package.json +0 -22
  31. package/intTestV2/page-object-models/testApp/pages/iframe/iframe.locatorSchema.ts +0 -24
  32. package/intTestV2/page-object-models/testApp/pages/iframe/iframe.page.ts +0 -17
  33. package/intTestV2/page-object-models/testApp/pages/testPage.locatorSchema.ts +0 -32
  34. package/intTestV2/page-object-models/testApp/pages/testPage.page.ts +0 -119
  35. package/intTestV2/page-object-models/testApp/pages/testPath/[color]/color.locatorSchema.ts +0 -29
  36. package/intTestV2/page-object-models/testApp/pages/testPath/[color]/color.page.ts +0 -48
  37. package/intTestV2/page-object-models/testApp/pages/testPath/testPath.locatorSchema.ts +0 -9
  38. package/intTestV2/page-object-models/testApp/pages/testPath/testPath.page.ts +0 -23
  39. package/intTestV2/page-object-models/testApp/pages/testfilters/testfilters.locatorSchema.ts +0 -114
  40. package/intTestV2/page-object-models/testApp/pages/testfilters/testfilters.page.ts +0 -23
  41. package/intTestV2/page-object-models/testApp/testApp.base.ts +0 -20
  42. package/intTestV2/playwright.config.ts +0 -54
  43. package/intTestV2/server.js +0 -216
  44. package/intTestV2/test-data/staticPage/index.html +0 -280
  45. package/intTestV2/test-data/staticPage/w3images/avatar2.png +0 -0
  46. package/intTestV2/test-data/staticPage/w3images/avatar3.png +0 -0
  47. package/intTestV2/test-data/staticPage/w3images/avatar5.png +0 -0
  48. package/intTestV2/test-data/staticPage/w3images/avatar6.png +0 -0
  49. package/intTestV2/test-data/staticPage/w3images/forest.jpg +0 -0
  50. package/intTestV2/test-data/staticPage/w3images/lights.jpg +0 -0
  51. package/intTestV2/test-data/staticPage/w3images/mountains.jpg +0 -0
  52. package/intTestV2/test-data/staticPage/w3images/nature.jpg +0 -0
  53. package/intTestV2/test-data/staticPage/w3images/snow.jpg +0 -0
  54. package/intTestV2/tests/locatorRegistry/add/add.describe.spec.ts +0 -54
  55. package/intTestV2/tests/locatorRegistry/add/add.filter.spec.ts +0 -143
  56. package/intTestV2/tests/locatorRegistry/add/add.frameLocator.spec.ts +0 -23
  57. package/intTestV2/tests/locatorRegistry/add/add.getByAltText.spec.ts +0 -23
  58. package/intTestV2/tests/locatorRegistry/add/add.getById.spec.ts +0 -45
  59. package/intTestV2/tests/locatorRegistry/add/add.getByLabel.spec.ts +0 -23
  60. package/intTestV2/tests/locatorRegistry/add/add.getByPlaceholder.spec.ts +0 -23
  61. package/intTestV2/tests/locatorRegistry/add/add.getByRole.spec.ts +0 -23
  62. package/intTestV2/tests/locatorRegistry/add/add.getByTestId.spec.ts +0 -23
  63. package/intTestV2/tests/locatorRegistry/add/add.getByText.spec.ts +0 -23
  64. package/intTestV2/tests/locatorRegistry/add/add.getByTitle.spec.ts +0 -23
  65. package/intTestV2/tests/locatorRegistry/add/add.locator.spec.ts +0 -23
  66. package/intTestV2/tests/locatorRegistry/add/add.reuseExisting.spec.ts +0 -66
  67. package/intTestV2/tests/locatorRegistry/add/add.reuseReusable.spec.ts +0 -311
  68. package/intTestV2/tests/locatorRegistry/add/add.spec.ts +0 -159
  69. package/intTestV2/tests/locatorRegistry/filter.cycle.spec.ts +0 -39
  70. package/intTestV2/tests/locatorRegistry/getLocator/getLocator.spec.ts +0 -253
  71. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.clearSteps.spec.ts +0 -105
  72. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.describe.spec.ts +0 -23
  73. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.filter.spec.ts +0 -368
  74. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.getLocator.spec.ts +0 -56
  75. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.getNestedLocator.spec.ts +0 -175
  76. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.nth.spec.ts +0 -60
  77. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.remove.spec.ts +0 -32
  78. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.replace.spec.ts +0 -24
  79. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.spec.ts +0 -110
  80. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.update.spec.ts +0 -322
  81. package/intTestV2/tests/locatorRegistry/getNestedLocator/getNestedLocator.spec.ts +0 -412
  82. package/intTestV2/tests/locatorRegistry/registry/registry.binding.spec.ts +0 -50
  83. package/intTestV2/tests/locatorRegistry/validation/validation.locatorSchemaPath.spec.ts +0 -115
  84. package/intTestV2/tests/locatorRegistry/validation/validation.sub-path.spec.ts +0 -45
  85. package/intTestV2/tests/step/step.spec.ts +0 -49
  86. package/intTestV2/tests/testApp/color.spec.ts +0 -15
  87. package/intTestV2/tests/testApp/iframe.spec.ts +0 -57
  88. package/intTestV2/tests/testApp/testFilters.spec.ts +0 -24
  89. package/intTestV2/tests/testApp/testPage.spec.ts +0 -161
  90. package/intTestV2/tests/testApp/testPath.spec.ts +0 -18
  91. package/pack-build.sh +0 -11
  92. package/pack-test-v2.sh +0 -36
  93. package/playwright.base.ts +0 -42
  94. package/skills/README.md +0 -56
  95. package/skills/pomwright-v1-5-bridge-migration/SKILL.md +0 -40
  96. package/skills/pomwright-v1-5-bridge-migration/references/call-site-migration.md +0 -178
  97. package/skills/pomwright-v1-5-bridge-migration/references/schema-translation.md +0 -183
  98. package/skills/pomwright-v2-migration/SKILL.md +0 -63
  99. package/skills/pomwright-v2-migration/references/call-site-migration.md +0 -265
  100. package/skills/pomwright-v2-migration/references/class-migration.md +0 -266
  101. package/skills/pomwright-v2-migration/references/fixture-and-helpers.md +0 -423
  102. package/skills/pomwright-v2-migration/references/locator-registration.md +0 -344
  103. package/srcV2/fixture/base.fixtures.ts +0 -23
  104. package/srcV2/helpers/navigation.ts +0 -153
  105. package/srcV2/helpers/playwrightReportLogger.ts +0 -196
  106. package/srcV2/helpers/sessionStorage.ts +0 -251
  107. package/srcV2/helpers/stepDecorator.ts +0 -106
  108. package/srcV2/locators/index.ts +0 -15
  109. package/srcV2/locators/locatorQueryBuilder.ts +0 -427
  110. package/srcV2/locators/locatorRegistrationBuilder.ts +0 -558
  111. package/srcV2/locators/locatorRegistry.ts +0 -541
  112. package/srcV2/locators/locatorUpdateBuilder.ts +0 -602
  113. package/srcV2/locators/reusableLocatorBuilder.ts +0 -200
  114. package/srcV2/locators/types.ts +0 -256
  115. package/srcV2/locators/utils.ts +0 -309
  116. package/srcV2/locators/v1SchemaTranslator.ts +0 -178
  117. package/srcV2/pageObject.ts +0 -105
@@ -1,15 +0,0 @@
1
- import { test } from "@fixtures-v2/testApp.fixtures";
2
-
3
- test("Should validate navigation using RegExp-based urlPath and fullUrl", async ({ testPath, color }) => {
4
- await testPath.page.goto(testPath.fullUrl);
5
-
6
- await testPath.expectThisPage();
7
-
8
- const linkToColorPage = testPath.getNestedLocator("body.link@color");
9
- await linkToColorPage.waitFor({ state: "visible" });
10
-
11
- await linkToColorPage.click();
12
-
13
- await color.expectThisPage();
14
- await color.validateColorPage();
15
- });
@@ -1,57 +0,0 @@
1
- import { expect, test } from "@fixtures-v2/testApp.fixtures";
2
-
3
- const toggleStates = {
4
- on: "On",
5
- off: "Off",
6
- } as const;
7
-
8
- test.describe("iframe handling", () => {
9
- test.beforeEach(async ({ iframePage }) => {
10
- await iframePage.page.goto(iframePage.fullUrl);
11
- });
12
-
13
- test("getLocator finds iframeA and iframeB", async ({ iframePage }) => {
14
- const iframeA = iframePage.getLocator("sectionA.frame");
15
- const iframeB = iframePage.getLocator("sectionB.frame");
16
-
17
- await expect(iframeA).toBeVisible();
18
- await expect(iframeB).toBeVisible();
19
- });
20
-
21
- test("getLocator does not finds iframeC as it is inside iframeB", async ({ iframePage }) => {
22
- const iframeC = iframePage.getLocator("sectionB.frame.innerFrame");
23
-
24
- await expect(iframeC).not.toBeVisible();
25
- });
26
-
27
- test("getNestedLocator finds iframeA and iframeB", async ({ iframePage }) => {
28
- const iframeA = iframePage.getNestedLocator("sectionA.frame");
29
- const iframeB = iframePage.getNestedLocator("sectionB.frame");
30
-
31
- await expect(iframeA).toBeVisible();
32
- await expect(iframeB).toBeVisible();
33
- });
34
-
35
- test("getNestedLocator finds nested iframeC", async ({ iframePage }) => {
36
- const iframeC = iframePage.getNestedLocator("sectionB.frame.innerFrame");
37
- await expect(iframeC).toBeVisible();
38
- });
39
-
40
- test("toggle elements inside each iframe", async ({ iframePage }) => {
41
- const toggleA = iframePage.getNestedLocator("sectionA.frame.toggle");
42
- const toggleB = iframePage.getNestedLocator("sectionB.frame.toggle");
43
- const toggleC = iframePage.getNestedLocator("sectionB.frame.innerFrame.toggle");
44
-
45
- await expect(toggleA).toHaveText(`Toggle A: ${toggleStates.off}`);
46
- await expect(toggleB).toHaveText(`Toggle B: ${toggleStates.off}`);
47
- await expect(toggleC).toHaveText(`Toggle C: ${toggleStates.off}`);
48
-
49
- await toggleA.click();
50
- await toggleB.click();
51
- await toggleC.click();
52
-
53
- await expect(toggleA).toHaveText(`Toggle A: ${toggleStates.on}`);
54
- await expect(toggleB).toHaveText(`Toggle B: ${toggleStates.on}`);
55
- await expect(toggleC).toHaveText(`Toggle C: ${toggleStates.on}`);
56
- });
57
- });
@@ -1,24 +0,0 @@
1
- import { expect, test } from "@fixtures-v2/testApp.fixtures";
2
-
3
- test("locator definitions with options should resolve playground interactions", async ({ testFilters }) => {
4
- await testFilters.page.goto(testFilters.fullUrl);
5
-
6
- const playgroundSection = testFilters.getNestedLocator("body.section@playground");
7
-
8
- const playgroundBtnRed = testFilters.getNestedLocator("body.section@playground.button@red");
9
- await playgroundBtnRed.click();
10
-
11
- await expect(playgroundSection).toHaveCSS("background-color", "rgb(255, 0, 0)");
12
- });
13
-
14
- test("getLocatorSchema propagates registered filters and indices to getLocator", async ({ testFilters }) => {
15
- await testFilters.page.goto(testFilters.fullUrl);
16
-
17
- const locator = testFilters
18
- .getLocatorSchema("body.section@playground.button@reset")
19
- .filter("body.section@playground.button@reset", { hasText: /Reset/i })
20
- .nth("body.section@playground.button@reset", "first")
21
- .getLocator();
22
-
23
- expect(`${locator}`).toEqual("getByRole('button', { name: 'Reset Color' }).filter({ hasText: /Reset/i }).first()");
24
- });
@@ -1,161 +0,0 @@
1
- import { expect, test } from "@fixtures-v2/testApp.fixtures";
2
- import { SessionStorage } from "pomwright";
3
-
4
- test("navigation.gotoThisPage runs post-navigation actions", async ({ testPage }) => {
5
- expect(testPage.navigationActionCount.value).toBe(0);
6
-
7
- await testPage.navigation.gotoThisPage();
8
-
9
- expect(testPage.navigationActionCount.value).toBe(1);
10
- });
11
-
12
- test("topMenu should expose notification badge count", async ({ testPage }) => {
13
- await testPage.page.goto(testPage.fullUrl);
14
-
15
- const notificationBadge = testPage.getNestedLocator("topMenu.notifications.button.countBadge");
16
- await expect(notificationBadge).toHaveText("3");
17
- });
18
-
19
- test("stepWithAdvancedReturnType should return the expected payload", async ({ testPage }) => {
20
- await testPage.page.goto(testPage.fullUrl);
21
-
22
- const result = await testPage.stepWithAdvancedReturnType();
23
-
24
- expect(result.status).toBe("ready");
25
- expect(result.payload[0]?.values[0]?.key).toBe("alpha");
26
- expect(result.metadata.flags.has("beta")).toBe(true);
27
- expect(result.metadata.versions.get("v2")?.hash).toBe("def456");
28
- expect(result.startedAt.getTime()).toBe(0);
29
- });
30
-
31
- test.describe("getLocator helpers on web app", () => {
32
- test.afterEach(async ({ testPage }) => {
33
- await testPage.page.goto(testPage.fullUrl);
34
- });
35
-
36
- test("getLocator should return the single locator the complete LocatorSchemaPath resolves to", async ({
37
- testPage,
38
- }) => {
39
- const locator = testPage.getLocator("topMenu.notifications.dropdown.item");
40
- expect(locator).not.toBeNull();
41
- expect(locator).not.toBeUndefined();
42
- expect(`${locator}`).toEqual("locator('.w3-bar-item')");
43
- });
44
-
45
- test("should be able to manually chain locators returned by getLocator", async ({ testPage }) => {
46
- const topMenu = testPage.getLocator("topMenu");
47
-
48
- const topMenuNotifications = topMenu.locator(testPage.getLocator("topMenu.notifications"));
49
-
50
- const topMenuNotificationsDropdown = topMenuNotifications.locator(
51
- testPage.getLocator("topMenu.notifications.dropdown"),
52
- );
53
-
54
- const topMenuNotificationsDropdownItem = topMenuNotificationsDropdown.locator(
55
- testPage.getLocator("topMenu.notifications.dropdown.item"),
56
- );
57
-
58
- expect(topMenuNotificationsDropdownItem).not.toBeNull();
59
- expect(topMenuNotificationsDropdownItem).not.toBeUndefined();
60
- expect(`${topMenuNotificationsDropdownItem}`).toEqual(
61
- "locator('.w3-top').locator(locator('.w3-dropdown-hover')).locator(locator('.w3-dropdown-content')).locator(locator('.w3-bar-item'))",
62
- );
63
- });
64
- });
65
-
66
- test("getNestedLocator should support index overrides", async ({ testPage }) => {
67
- await testPage.page.goto(testPage.fullUrl);
68
-
69
- const secondNotification = testPage
70
- .getLocatorSchema("topMenu.notifications.dropdown.item")
71
- .nth("topMenu.notifications.dropdown.item", 1)
72
- .getNestedLocator();
73
- await expect(secondNotification).toHaveText("John Doe posted on your wall");
74
-
75
- const lastNotification = testPage
76
- .getLocatorSchema("topMenu.notifications.dropdown.item")
77
- .nth("topMenu.notifications.dropdown.item", "last")
78
- .getNestedLocator();
79
- await expect(lastNotification).toHaveText("Jane likes your post");
80
- });
81
-
82
- test("setOnNextNavigation waits for a main-frame navigation", async ({ testPage }) => {
83
- await testPage.page.goto(testPage.fullUrl);
84
- await testPage.sessionStorage.clear();
85
-
86
- await testPage.sessionStorage.setOnNextNavigation({ token: "abc" });
87
- await expect(testPage.sessionStorage.get(["token"])).resolves.toEqual({});
88
-
89
- await testPage.page.goto(testPage.fullUrl);
90
- await expect(testPage.sessionStorage.get(["token"])).resolves.toEqual({ token: "abc" });
91
- });
92
-
93
- test("setOnNextNavigation merges multiple calls before navigation", async ({ testPage }) => {
94
- await testPage.page.goto(testPage.fullUrl);
95
- await testPage.sessionStorage.clear();
96
-
97
- await testPage.sessionStorage.setOnNextNavigation({ token: "abc" });
98
- await testPage.sessionStorage.setOnNextNavigation({ theme: "dark" });
99
- await testPage.page.goto(testPage.fullUrl);
100
-
101
- await expect(testPage.sessionStorage.get(["token", "theme"])).resolves.toEqual({
102
- token: "abc",
103
- theme: "dark",
104
- });
105
- });
106
-
107
- test("clear can target specific keys", async ({ testPage }) => {
108
- await testPage.page.goto(testPage.fullUrl);
109
- await testPage.sessionStorage.set({ token: "abc", theme: "dark" });
110
-
111
- await testPage.sessionStorage.clear("token");
112
- await expect(testPage.sessionStorage.get(["token", "theme"])).resolves.toEqual({ theme: "dark" });
113
- });
114
-
115
- test("sessionStorage set/get supports waitForContext", async ({ testPage }) => {
116
- await testPage.page.goto(testPage.fullUrl);
117
-
118
- await testPage.sessionStorage.set({ token: "abc" }, { waitForContext: true });
119
-
120
- const { token } = await testPage.sessionStorage.get(["token"], { waitForContext: true });
121
- expect(token).toBe("abc");
122
- });
123
-
124
- test("sessionStorage clear supports keys and waitForContext", async ({ testPage }) => {
125
- await testPage.page.goto(testPage.fullUrl);
126
-
127
- await testPage.sessionStorage.set({ token: "abc", theme: "dark" }, { waitForContext: true });
128
- await testPage.sessionStorage.clear("token", { waitForContext: true });
129
-
130
- const data = await testPage.sessionStorage.get(["token", "theme"], { waitForContext: true });
131
- expect(data.token).toBeUndefined();
132
- expect(data.theme).toBe("dark");
133
- });
134
-
135
- test("sessionStorage set/get should write immediately on a loaded page", async ({ testPage }) => {
136
- await testPage.page.goto(testPage.fullUrl);
137
-
138
- await testPage.sessionStorage.set({ token: { value: "abc" } });
139
-
140
- const data = await testPage.sessionStorage.get(["token"]);
141
- expect(data.token).toEqual({ value: "abc" });
142
- });
143
-
144
- test("sessionStorage set with waitForContext should wait for navigation context", async ({ testPage }) => {
145
- const freshPage = await testPage.page.context().newPage();
146
- const sessionStorage = new SessionStorage(freshPage, { label: "SessionStorageTest" });
147
-
148
- const navigation = freshPage.goto(testPage.fullUrl);
149
- await sessionStorage.set({ token: { value: "waited" } }, { waitForContext: true });
150
- await navigation;
151
-
152
- const data = await sessionStorage.get(["token"]);
153
- expect(data.token).toEqual({ value: "waited" });
154
- });
155
-
156
- test("sessionStorage operations reject without waitForContext when no context", async ({ testPage }) => {
157
- const freshPage = await testPage.page.context().newPage();
158
- const sessionStorage = new SessionStorage(freshPage, { label: "SessionStorageTest" });
159
-
160
- await expect(sessionStorage.get(["token"])).rejects.toThrow("SessionStorage context is not available.");
161
- });
@@ -1,18 +0,0 @@
1
- import { expect, test } from "@fixtures-v2/testApp.fixtures";
2
-
3
- test("navigation.goto prefixes baseUrl for URL paths", async ({ testPath }) => {
4
- await testPath.navigation.goto("/testpath");
5
- await testPath.navigation.expectThisPage();
6
-
7
- expect(testPath.page.url()).toBe(testPath.fullUrl);
8
- });
9
-
10
- test("navigation.expectThisPage supports RegExp fullUrl", async ({ testPath, color }) => {
11
- await testPath.navigation.gotoThisPage();
12
-
13
- const linkToColorPage = testPath.getNestedLocator("body.link@color");
14
- await linkToColorPage.waitFor({ state: "visible" });
15
- await linkToColorPage.click();
16
-
17
- await color.navigation.expectThisPage();
18
- });
package/pack-build.sh DELETED
@@ -1,11 +0,0 @@
1
- #!/bin/bash
2
-
3
- set -e
4
-
5
- VERSION=$(node -pe "require('./package.json').version")
6
-
7
- pnpm i --frozen-lockfile || { echo "Installation failed"; exit 1; }
8
- pnpm build || { echo "Build failed"; exit 1; }
9
- pnpm pack || { echo "Packaging failed"; exit 1; }
10
-
11
- echo "Built pomwright-$VERSION.tgz"
package/pack-test-v2.sh DELETED
@@ -1,36 +0,0 @@
1
- #!/bin/bash
2
-
3
- TEST_DIR="intTestV2"
4
-
5
- cleanup() {
6
- if [[ $(basename "$PWD") != "$TEST_DIR" ]]; then
7
- echo "Not in ./$TEST_DIR directory. Trying to change to ./$TEST_DIR directory..."
8
- if [[ -d "$TEST_DIR" ]]; then
9
- cd $TEST_DIR || { echo "Failed to change to ./$TEST_DIR directory"; return 1; }
10
- else
11
- echo "The ./$TEST_DIR directory does not exist. Exiting cleanup."
12
- return 1
13
- fi
14
- fi
15
-
16
- # echo "Reverting to latest published version of POMWright in the ./$TEST_DIR directory..."
17
- # pnpm i -D pomwright@latest || { echo "Failed to revert to latest POMWright version"; exit 1; }
18
- }
19
-
20
- trap cleanup EXIT
21
-
22
- set -e
23
-
24
- VERSION=$(node -pe "require('./package.json').version")
25
-
26
- ./pack-build.sh
27
-
28
- cd $TEST_DIR || { echo "Changing directory failed"; exit 1; }
29
-
30
- pnpm i -D "../pomwright-$VERSION.tgz" || { echo "Local package installation failed"; exit 1; }
31
-
32
- pnpm i --frozen-lockfile || { echo "Installation failed"; exit 1; }
33
- pnpm playwright install --with-deps || { echo "Playwright dependencies installation failed"; exit 1; }
34
- pnpm playwright test --project=chromium || { echo "Tests failed"; exit 1; }
35
-
36
- echo "Testing completed successfully."
@@ -1,42 +0,0 @@
1
- // playwright.base.ts
2
- import type { PlaywrightTestConfig } from "@playwright/test";
3
-
4
- // this is only a *type* import → erased at runtime → does NOT trigger the double-load
5
- // everything below is plain data the subprojects can spread in
6
-
7
- export const baseConfig: PlaywrightTestConfig = {
8
- // things you currently have in both configs:
9
- globalTimeout: 60_000 * 5,
10
- timeout: 60_000,
11
- expect: {
12
- timeout: 5_000,
13
- },
14
- fullyParallel: true,
15
- forbidOnly: !!process.env.CI,
16
- retries: process.env.CI ? 1 : 1,
17
- workers: "50%",
18
- reporter: process.env.CI
19
- ? [
20
- ["html", { open: "never" }],
21
- ["github", { printSteps: false }],
22
- ]
23
- : [
24
- ["html", { open: "on-failure" }],
25
- ["list", { printSteps: false }],
26
- ],
27
- use: {
28
- actionTimeout: 5_000,
29
- navigationTimeout: 10_000,
30
- headless: true,
31
- viewport: { width: 1280, height: 720 },
32
- ignoreHTTPSErrors: false,
33
- video: "retry-with-video",
34
- screenshot: {
35
- mode: "only-on-failure",
36
- fullPage: true,
37
- omitBackground: false,
38
- },
39
- trace: "on-all-retries",
40
- testIdAttribute: "data-testid",
41
- },
42
- };
package/skills/README.md DELETED
@@ -1,56 +0,0 @@
1
- # POMWright Migration Skills
2
-
3
- AI assistant skills for migrating POMWright page objects between versions.
4
-
5
- ## Available Skills
6
-
7
- ### pomwright-v1-5-bridge-migration
8
- Migrate v1 `BasePage` page objects to the v1.5 bridge (`BasePageV1toV2`) as an intermediate step toward v2.
9
-
10
- **Triggered by:**
11
- - "Migrate/convert/upgrade this page object from v1 to the bridge"
12
- - "Use BasePageV1toV2 for this page object"
13
- - Mentioning `BasePageV1toV2` or "bridge" in migration context
14
-
15
- **Covers:**
16
- - Changing class inheritance
17
- - Translating `addSchema`/`initLocatorSchemas` to `defineLocators` with v2 DSL
18
- - Updating call-site syntax (`getLocator`, `getNestedLocator`, `getLocatorSchema`)
19
- - Updating filter/index/update/mutation patterns
20
-
21
- ### pomwright-v2-migration
22
- Migrate page objects to v2 `PageObject` from either v1 `BasePage` or the v1.5 bridge.
23
-
24
- **Triggered by:**
25
- - "Migrate/convert/upgrade this page object to v2"
26
- - "Use v2 PageObject for this page object"
27
- - Mentioning `PageObject` or "v2" in migration context
28
-
29
- **Covers:**
30
- - Class inheritance and constructor signature changes
31
- - Locator registration with v2 DSL
32
- - Adding `pageActionsToPerformAfterNavigation`
33
- - Call-site syntax updates
34
- - Migrating fixtures, navigation, sessionStorage, and logging
35
- - Adopting the `@step` decorator
36
-
37
- ## Installation
38
-
39
- ### For Claude Code
40
-
41
- Copy the skill directories to your local Claude Code skills folder:
42
-
43
- ```bash
44
- cp -r skills/pomwright-v1-5-bridge-migration ~/.claude/skills/
45
- cp -r skills/pomwright-v2-migration ~/.claude/skills/
46
- ```
47
-
48
- ### For Other AI Assistants
49
-
50
- These skills are structured as markdown-based instructions with reference documentation. Adapt the content from each `SKILL.md` file according to your AI assistant's skill/prompt format.
51
-
52
- ## Structure
53
-
54
- Each skill includes:
55
- - `SKILL.md` - Main skill instructions
56
- - `references/` - Supporting documentation and examples
@@ -1,40 +0,0 @@
1
- ---
2
- name: pomwright-v1-5-bridge-migration
3
- description: >
4
- Migrate POMWright v1 BasePage page objects to the v1.5 bridge (BasePageV1toV2) as an intermediate
5
- step toward v2 PageObject. Use when asked to migrate, convert, or upgrade POMWright page objects
6
- from v1 to the bridge, or when working with BasePageV1toV2. Covers: changing class inheritance,
7
- translating addSchema/initLocatorSchemas to defineLocators with v2 DSL, updating call-site syntax
8
- (getLocator, getNestedLocator, getLocatorSchema), and updating filter/index/update/mutation patterns.
9
- ---
10
-
11
- # POMWright v1.5 Bridge Migration (BasePage -> BasePageV1toV2)
12
-
13
- Migrate v1 `BasePage` page objects to `BasePageV1toV2` (the bridge), converting locator definitions
14
- and call-site syntax to v2. The bridge is deprecated and will be removed in 2.0.0; it exists only
15
- as a staged migration step.
16
-
17
- ## Workflow
18
-
19
- 1. **Inventory** the target POC file: identify `BasePage` extends, `initLocatorSchemas`, all `addSchema` calls, and call-sites using v1 accessors.
20
- 2. **Switch inheritance** from `BasePage` to `BasePageV1toV2`. Constructor signature stays the same (`page, testInfo, baseUrl, urlPath, pocName, pwrl`).
21
- 3. **Add `defineLocators()`** method stub.
22
- 4. **Translate each `addSchema` call** from `initLocatorSchemas` into `this.add(path).method(...)` inside `defineLocators()`. See [references/schema-translation.md](references/schema-translation.md) for the full mapping table and examples.
23
- 5. **Remove translated `addSchema` entries** from `initLocatorSchemas`. Once all are moved, keep `initLocatorSchemas()` as an empty method while still extending `BasePageV1toV2`.
24
- 6. **Update call-site syntax** in tests/helpers/fixtures that consume the POC. See [references/call-site-migration.md](references/call-site-migration.md).
25
- 7. **Verify** by running tests.
26
-
27
- ## Key rules
28
-
29
- - Paths already registered in `defineLocators` are skipped when the bridge translates `initLocatorSchemas` - no duplicates.
30
- - v1 schemas using `Locator` instances or missing selector fields cannot be auto-translated; rewrite those in `defineLocators` immediately.
31
- - `BasePageV1toV2` narrows `this.locators` to `addSchema` only; no other v1 mutations are exposed.
32
- - v2 accessors (`add`, `getLocator`, `getNestedLocator`, `getLocatorSchema`) are exposed on the bridge and should be used from this point forward.
33
- - v2 `getLocator`/`getNestedLocator` are **synchronous** (no `await`). v1 versions were async.
34
- - v2 `getNestedLocator` no longer accepts index maps. Use `getLocatorSchema(path).nth(subPath, index).getNestedLocator()` instead.
35
- - `filter` replaces v1 `addFilter`. `nth` replaces v1 index maps. Both can be chained in any order.
36
-
37
- ## References
38
-
39
- - **Schema translation mapping**: [references/schema-translation.md](references/schema-translation.md) - GetByMethod -> v2 DSL mapping table, filter/options translation, reusable locators, frameLocator changes
40
- - **Call-site migration**: [references/call-site-migration.md](references/call-site-migration.md) - getLocator, getNestedLocator, getLocatorSchema, update, addFilter, index maps, SessionStorage changes
@@ -1,178 +0,0 @@
1
- # Call-Site Migration: v1 -> v2 accessor syntax
2
-
3
- ## getLocator / getNestedLocator (async -> sync)
4
-
5
- v1 returns `Promise<Locator>`. v2 returns `Locator` synchronously. Remove `await`.
6
-
7
- ```ts
8
- // v1
9
- const btn = await poc.getLocator("navbar.button@login");
10
- await btn.click();
11
-
12
- const nested = await poc.getNestedLocator("navbar.button@logout");
13
- await nested.click();
14
-
15
- // v2
16
- await poc.getLocator("navbar.button@login").click();
17
- await poc.getNestedLocator("navbar.button@logout").click();
18
- ```
19
-
20
- ## getNestedLocator with index maps -> getLocatorSchema + nth
21
-
22
- v1 accepted an optional index map object as second argument. v2 does not; use `getLocatorSchema` with `.nth()` instead.
23
-
24
- ```ts
25
- // v1
26
- const submit = await poc.getNestedLocator("main.form.button@submit", {
27
- "main.form": 0,
28
- });
29
-
30
- // v2
31
- const submit = poc
32
- .getLocatorSchema("main.form.button@submit")
33
- .nth("main.form", 0)
34
- .getNestedLocator();
35
- ```
36
-
37
- Multiple indices:
38
-
39
- ```ts
40
- // v1
41
- const item = await poc.getNestedLocator("main.list.item.detail", {
42
- "main.list": 0,
43
- "main.list.item": 2,
44
- });
45
-
46
- // v2
47
- const item = poc
48
- .getLocatorSchema("main.list.item.detail")
49
- .nth("main.list", 0)
50
- .nth("main.list.item", 2)
51
- .getNestedLocator();
52
- ```
53
-
54
- ## addFilter -> filter
55
-
56
- v1 `addFilter` on `getLocatorSchema()` becomes v2 `filter`. Method name and argument shape changed.
57
-
58
- ```ts
59
- // v1
60
- const filtered = await poc
61
- .getLocatorSchema("main.list.item")
62
- .addFilter("main.list", { hasText: "list" })
63
- .addFilter("main.list.item", { hasText: "Row" })
64
- .getNestedLocator({ "main.list": 0, "main.list.item": -1 });
65
-
66
- // v2
67
- const filtered = poc
68
- .getLocatorSchema("main.list.item")
69
- .filter("main.list", { hasText: "list" })
70
- .nth("main.list", 0)
71
- .filter({ hasText: "Row" }) // omitted subPath defaults to terminal path
72
- .nth(-1) // omitted subPath defaults to terminal path
73
- .getNestedLocator();
74
- ```
75
-
76
- Key difference: v2 `filter` and `nth` can be interleaved in any order. v1 required all filters first, then one index map at the end.
77
-
78
- ## update (schema mutation)
79
-
80
- v1 `update` accepted a partial schema object. v2 `update` returns a sub-builder where you chain the locator method with override options.
81
-
82
- ```ts
83
- // v1
84
- const patched = await poc
85
- .getLocatorSchema("main.button@login")
86
- .update("main.button@login", { roleOptions: { name: "Sign in" } })
87
- .getNestedLocator();
88
-
89
- // v2
90
- const patched = poc
91
- .getLocatorSchema("main.button@login")
92
- .update() // defaults to terminal path
93
- .getByRole({ name: "Sign in" }) // PATCH-style: only override options
94
- .getNestedLocator();
95
- ```
96
-
97
- v2 also adds `replace` (full replacement) and `remove` (drop a subpath from chain):
98
-
99
- ```ts
100
- // replace the entire locator strategy for a subpath
101
- const replaced = poc
102
- .getLocatorSchema("main.button@login")
103
- .replace()
104
- .getByText("Sign in")
105
- .getNestedLocator();
106
-
107
- // remove a segment from the chain
108
- const removed = poc
109
- .getLocatorSchema("main.button@login")
110
- .remove("main")
111
- .getNestedLocator();
112
- ```
113
-
114
- ## getLocatorSchema().getLocator() / .getNestedLocator()
115
-
116
- v1 terminal resolution was async. v2 is sync.
117
-
118
- ```ts
119
- // v1
120
- const loc = await poc.getLocatorSchema("main.button@login").getLocator();
121
- const nested = await poc.getLocatorSchema("main.button@login").getNestedLocator();
122
-
123
- // v2
124
- const loc = poc.getLocatorSchema("main.button@login").getLocator();
125
- const nested = poc.getLocatorSchema("main.button@login").getNestedLocator();
126
- ```
127
-
128
- ## describe (v2 only, no v1 equivalent)
129
-
130
- ```ts
131
- const btn = poc
132
- .getLocatorSchema("main.region@security.button@edit")
133
- .filter({ hasText: "Change password" })
134
- .describe("Change password")
135
- .getNestedLocator();
136
- ```
137
-
138
- ## SessionStorage signature changes
139
-
140
- ```ts
141
- // v1
142
- await poc.sessionStorage.set({ token: "abc" }, true); // boolean reload
143
- await poc.sessionStorage.get(["token"]);
144
- await poc.sessionStorage.clear();
145
-
146
- // v2
147
- await poc.sessionStorage.set({ token: "abc" }, { reload: true });
148
- await poc.sessionStorage.get(["token"], { waitForContext: true });
149
- await poc.sessionStorage.clear(); // clears all
150
- await poc.sessionStorage.clear(["token"]); // clears specific keys
151
- ```
152
-
153
- ## Import changes
154
-
155
- ```ts
156
- // v1
157
- import { BasePage, GetByMethod } from "pomwright";
158
-
159
- // v1.5 bridge
160
- import { BasePageV1toV2, GetByMethod } from "pomwright";
161
-
162
- // When all schemas moved to defineLocators, remove GetByMethod import.
163
- ```
164
-
165
- ## filter has/hasNot value changes
166
-
167
- v1 `filter.has`/`filter.hasNot` accepted `Locator` instances. v2 accepts **registry path strings** or `Locator` instances from `getLocator`/`getNestedLocator`.
168
-
169
- ```ts
170
- // v1 (Locator instance in filter)
171
- .addFilter("main.card", { has: someLocator })
172
-
173
- // v2 (path string reference)
174
- .filter("main.card", { has: "main.card.badge" })
175
-
176
- // v2 (Locator instance from registry)
177
- .filter("main.card", { has: poc.getNestedLocator("main.card.badge") })
178
- ```