pomwright 1.5.1 → 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 (119) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +5 -5
  3. package/dist/index.d.mts +75 -970
  4. package/dist/index.d.ts +75 -970
  5. package/dist/index.js +585 -1872
  6. package/dist/index.mjs +598 -1880
  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 -695
  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.get.clone.spec.ts +0 -76
  58. package/intTestV2/tests/locatorRegistry/add/add.getByAltText.spec.ts +0 -23
  59. package/intTestV2/tests/locatorRegistry/add/add.getById.spec.ts +0 -45
  60. package/intTestV2/tests/locatorRegistry/add/add.getByLabel.spec.ts +0 -23
  61. package/intTestV2/tests/locatorRegistry/add/add.getByPlaceholder.spec.ts +0 -23
  62. package/intTestV2/tests/locatorRegistry/add/add.getByRole.spec.ts +0 -23
  63. package/intTestV2/tests/locatorRegistry/add/add.getByTestId.spec.ts +0 -23
  64. package/intTestV2/tests/locatorRegistry/add/add.getByText.spec.ts +0 -23
  65. package/intTestV2/tests/locatorRegistry/add/add.getByTitle.spec.ts +0 -23
  66. package/intTestV2/tests/locatorRegistry/add/add.locator.spec.ts +0 -23
  67. package/intTestV2/tests/locatorRegistry/add/add.reuseExisting.spec.ts +0 -107
  68. package/intTestV2/tests/locatorRegistry/add/add.reuseReusable.spec.ts +0 -311
  69. package/intTestV2/tests/locatorRegistry/add/add.spec.ts +0 -159
  70. package/intTestV2/tests/locatorRegistry/filter.cycle.spec.ts +0 -39
  71. package/intTestV2/tests/locatorRegistry/getLocator/getLocator.spec.ts +0 -253
  72. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.clearSteps.spec.ts +0 -105
  73. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.describe.spec.ts +0 -23
  74. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.filter.spec.ts +0 -368
  75. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.getLocator.spec.ts +0 -56
  76. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.getNestedLocator.spec.ts +0 -175
  77. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.nth.spec.ts +0 -60
  78. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.remove.spec.ts +0 -32
  79. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.replace.spec.ts +0 -24
  80. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.spec.ts +0 -110
  81. package/intTestV2/tests/locatorRegistry/getLocatorSchema/getLocatorSchema.update.spec.ts +0 -322
  82. package/intTestV2/tests/locatorRegistry/getNestedLocator/getNestedLocator.spec.ts +0 -412
  83. package/intTestV2/tests/locatorRegistry/registry/registry.binding.spec.ts +0 -50
  84. package/intTestV2/tests/locatorRegistry/validation/validation.locatorSchemaPath.spec.ts +0 -115
  85. package/intTestV2/tests/locatorRegistry/validation/validation.locatorSchemaPath.typecheck.ts +0 -86
  86. package/intTestV2/tests/locatorRegistry/validation/validation.sub-path.spec.ts +0 -45
  87. package/intTestV2/tests/step/step.spec.ts +0 -49
  88. package/intTestV2/tests/testApp/color.spec.ts +0 -15
  89. package/intTestV2/tests/testApp/iframe.spec.ts +0 -57
  90. package/intTestV2/tests/testApp/testFilters.spec.ts +0 -24
  91. package/intTestV2/tests/testApp/testPage.spec.ts +0 -161
  92. package/intTestV2/tests/testApp/testPath.spec.ts +0 -18
  93. package/pack-build.sh +0 -11
  94. package/pack-test-v2.sh +0 -36
  95. package/playwright.base.ts +0 -42
  96. package/skills/README.md +0 -56
  97. package/skills/pomwright-v1-5-bridge-migration/SKILL.md +0 -40
  98. package/skills/pomwright-v1-5-bridge-migration/references/call-site-migration.md +0 -178
  99. package/skills/pomwright-v1-5-bridge-migration/references/schema-translation.md +0 -183
  100. package/skills/pomwright-v2-migration/SKILL.md +0 -63
  101. package/skills/pomwright-v2-migration/references/call-site-migration.md +0 -265
  102. package/skills/pomwright-v2-migration/references/class-migration.md +0 -266
  103. package/skills/pomwright-v2-migration/references/fixture-and-helpers.md +0 -423
  104. package/skills/pomwright-v2-migration/references/locator-registration.md +0 -344
  105. package/srcV2/fixture/base.fixtures.ts +0 -23
  106. package/srcV2/helpers/navigation.ts +0 -153
  107. package/srcV2/helpers/playwrightReportLogger.ts +0 -196
  108. package/srcV2/helpers/sessionStorage.ts +0 -251
  109. package/srcV2/helpers/stepDecorator.ts +0 -106
  110. package/srcV2/locators/index.ts +0 -15
  111. package/srcV2/locators/locatorQueryBuilder.ts +0 -427
  112. package/srcV2/locators/locatorRegistrationBuilder.ts +0 -558
  113. package/srcV2/locators/locatorRegistry.ts +0 -583
  114. package/srcV2/locators/locatorUpdateBuilder.ts +0 -602
  115. package/srcV2/locators/reusableLocatorBuilder.ts +0 -200
  116. package/srcV2/locators/types.ts +0 -256
  117. package/srcV2/locators/utils.ts +0 -309
  118. package/srcV2/locators/v1SchemaTranslator.ts +0 -178
  119. package/srcV2/pageObject.ts +0 -105
@@ -1,45 +0,0 @@
1
- import { expect, test } from "@fixtures-v2/testApp.fixtures";
2
-
3
- const chainedPath = "fictional.filter@hasNotText.filter@hasText.filter@hasNotText.filter@hasText" as const;
4
-
5
- test.describe("sub-path validation", () => {
6
- test("addFilter rejects invalid root-level sub-paths", ({ testFilters }) => {
7
- expect(() =>
8
- testFilters
9
- .getLocatorSchema("fictional.filter@hasNotText.filter@hasText")
10
- // @ts-expect-error Testing invalid path handling
11
- .filter("fictional", { hasText: "nope" }),
12
- ).toThrow('"fictional" is not a valid sub-path of "fictional.filter@hasNotText.filter@hasText".');
13
- });
14
-
15
- test("addFilter rejects invalid intermediate sub-paths", ({ testFilters }) => {
16
- expect(() =>
17
- testFilters
18
- .getLocatorSchema(chainedPath)
19
- // @ts-expect-error Testing invalid path handling
20
- .filter("fictional.filter@hasNotText.filter@missing", { hasText: "nope" }),
21
- ).toThrow(
22
- '"fictional.filter@hasNotText.filter@missing" is not a valid sub-path of "fictional.filter@hasNotText.filter@hasText.filter@hasNotText.filter@hasText".',
23
- );
24
- });
25
-
26
- test("update rejects missing/invalid subPaths", ({ testFilters }) => {
27
- expect(() =>
28
- testFilters
29
- .getLocatorSchema("fictional.filter@hasNotText.filter@hasText")
30
- // @ts-expect-error Testing invalid path handling
31
- .update("fictional.filter@missing")
32
- .getByText("nope"),
33
- ).toThrow('"fictional.filter@missing" is not a valid sub-path of "fictional.filter@hasNotText.filter@hasText".');
34
- });
35
-
36
- test("update rejects a valid LocatorSchemaPath when it's an invalid subPath", ({ testFilters }) => {
37
- expect(() =>
38
- testFilters
39
- .getLocatorSchema("body.section.heading")
40
- // @ts-expect-error Testing invalid path handling
41
- .update("body.section.button")
42
- .locator("noop"),
43
- ).toThrow('"body.section.button" is not a valid sub-path of "body.section.heading"');
44
- });
45
- });
@@ -1,49 +0,0 @@
1
- import { expect, test } from "@fixtures-v2/testApp.fixtures";
2
-
3
- // These tests need to be verified manually by checking the test report
4
-
5
- test("stepNoArgs should return the expected message", async ({ testPage }) => {
6
- await expect(testPage.stepNoArgs()).resolves.toBe("Hello, World!");
7
- });
8
-
9
- test("stepWithTitle should return the expected message", async ({ testPage }) => {
10
- await expect(testPage.stepWithTitle()).resolves.toBe("Hello, World!");
11
- });
12
-
13
- test("stepWithOptionBox should return the expected message", async ({ testPage }) => {
14
- await expect(testPage.stepWithOptionBox()).resolves.toBe("Hello, World!");
15
- });
16
-
17
- test("stepWithOptionTimeout should return the expected message", async ({ testPage }) => {
18
- await expect(testPage.stepWithOptionTimeout()).resolves.toBe("Hello, World!");
19
- });
20
-
21
- test("stepWithOptionLocation should return the expected message", async ({ testPage }) => {
22
- await expect(testPage.stepWithOptionLocation()).resolves.toBe("Hello, World!");
23
- });
24
-
25
- test("stepWithTitleAndAllOptions should return the expected message", async ({ testPage }) => {
26
- await expect(testPage.stepWithTitleAndAllOptions()).resolves.toBe("Hello, World!");
27
- });
28
-
29
- test("stepWithArgs should support required/default parameters", async ({ testPage }) => {
30
- await expect(testPage.stepWithArgs("Starter"))
31
- .resolves.toBe("Starter:1");
32
- await expect(testPage.stepWithArgs("Starter", 3)).resolves.toBe("Starter:3");
33
- });
34
-
35
- test("stepWithArgsAndObjectReturn should preserve typed argument/return flows", async ({ testPage }) => {
36
- await expect(testPage.stepWithArgsAndObjectReturn({ id: "abc" })).resolves.toEqual({
37
- ok: true,
38
- id: "abc",
39
- mode: "basic",
40
- retry: 0,
41
- });
42
-
43
- await expect(testPage.stepWithArgsAndObjectReturn({ id: "xyz", mode: "advanced" }, 2)).resolves.toEqual({
44
- ok: true,
45
- id: "xyz",
46
- mode: "advanced",
47
- retry: 2,
48
- });
49
- });
@@ -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