@guidepup/playwright 0.18.0 → 0.19.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/README.md CHANGED
@@ -99,39 +99,6 @@ await screenReader.navigateToWebContent();
99
99
  // ... some commands
100
100
  ```
101
101
 
102
- **Note:** This command clears all logs by default meaning `.spokenPhraseLog()` and `.itemTextLog()` are emptied. If logs from prior to the command are required, either store the logs in a variable for later use:
103
-
104
- ```ts
105
- // ... some commands
106
-
107
- // Store spoken phrases
108
- const spokenPhrases = await screenReader.spokenPhraseLog();
109
-
110
- // Navigate to the web content
111
- await screenReader.navigateToWebContent();
112
-
113
- // ... some commands
114
-
115
- // Collect all spoken phrases
116
- const allSpokenPhrases = [
117
- ...spokenPhrases,
118
- ...(await screenReader.spokenPhraseLog()),
119
- ];
120
-
121
- // ... do something with spoken phrases
122
- ```
123
-
124
- or pass a flag to prevent log clearing:
125
-
126
- ```ts
127
- // ... some commands
128
-
129
- // Navigate to the web content
130
- await screenReader.navigateToWebContent(false);
131
-
132
- // ... some commands
133
- ```
134
-
135
102
  ### Providing screen reader start options
136
103
 
137
104
  The options provided to `screenReader.start([options])`, `nvda.start([options])`, or `voiceOver.start([options])` can be configured using `test.use(config)` as follows:
@@ -213,7 +180,7 @@ test.describe("Playwright VoiceOver", () => {
213
180
 
214
181
  // Move across the page menu to the Guidepup heading using VoiceOver
215
182
  while ((await voiceOver.itemText()) !== "Guidepup heading level 1") {
216
- await voiceOver.perform(voiceOver.keyboardCommands.findNextHeading);
183
+ await voiceOver.nextHeading();
217
184
  }
218
185
 
219
186
  // Assert that the spoken phrases are as expected
@@ -275,7 +242,7 @@ test.describe("Playwright NVDA", () => {
275
242
  while (
276
243
  !(await nvda.lastSpokenPhrase()).includes("Guidepup, heading, level 1")
277
244
  ) {
278
- await nvda.perform(nvda.keyboardCommands.moveToNextHeading);
245
+ await nvda.nextHeading();
279
246
  }
280
247
 
281
248
  // Assert that the spoken phrases are as expected
package/lib/nvdaTest.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import type { CommandOptions, NVDA } from "@guidepup/guidepup";
1
+ import { type CommandOptions, type NVDA, type StartOptions } from "@guidepup/guidepup";
2
2
  type Prettify<T> = {
3
3
  [K in keyof T]: T[K];
4
4
  } & {};
5
5
  type CaptureCommandOptions = Prettify<Pick<CommandOptions, "capture">>;
6
+ type CaptureStartOptions = Prettify<Pick<StartOptions, "capture" | "settings">>;
6
7
  /**
7
8
  * [API Reference](https://www.guidepup.dev/docs/api/class-nvda)
8
9
  *
@@ -32,7 +33,7 @@ export interface NVDAPlaywright extends NVDA {
32
33
  *
33
34
  * This command should be used after page navigation.
34
35
  */
35
- navigateToWebContent(options?: Pick<CommandOptions, "capture">): Promise<void>;
36
+ navigateToWebContent(options?: CaptureCommandOptions): Promise<void>;
36
37
  }
37
38
  /**
38
39
  * These tests extend the default Playwright environment that launches the
@@ -65,10 +66,10 @@ export declare const nvdaTest: import("@playwright/test").TestType<import("@play
65
66
  */
66
67
  nvda: NVDAPlaywright;
67
68
  /**
68
- * [API Reference](https://www.guidepup.dev/docs/api/class-command-options)
69
+ * [API Reference](https://www.guidepup.dev/docs/api/class-start-options)
69
70
  *
70
71
  * Options to start NVDA with, see also [nvda.start([options])](https://www.guidepup.dev/docs/api/class-nvda#nvda-start).
71
72
  */
72
- nvdaStartOptions: CaptureCommandOptions;
73
+ nvdaStartOptions: CaptureStartOptions;
73
74
  }, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
74
75
  export {};
@@ -1,8 +1,9 @@
1
- import { CommandOptions, type ScreenReader } from "@guidepup/guidepup";
1
+ import { type CommandOptions, type ScreenReader, type StartOptions } from "@guidepup/guidepup";
2
2
  type Prettify<T> = {
3
3
  [K in keyof T]: T[K];
4
4
  } & {};
5
5
  type CaptureCommandOptions = Prettify<Pick<CommandOptions, "capture">>;
6
+ type CaptureStartOptions = Prettify<Pick<StartOptions, "capture" | "settings">>;
6
7
  /**
7
8
  * This object can be used to launch and control the default screen reader for
8
9
  * the environment.
@@ -33,7 +34,7 @@ export interface ScreenReaderPlaywright extends ScreenReader {
33
34
  *
34
35
  * This command should be used after page navigation.
35
36
  */
36
- navigateToWebContent(options?: Pick<CommandOptions, "capture">): Promise<void>;
37
+ navigateToWebContent(options?: CaptureCommandOptions): Promise<void>;
37
38
  }
38
39
  /**
39
40
  * These tests extend the default Playwright environment that launches the
@@ -71,6 +72,6 @@ export declare const screenReaderTest: import("@playwright/test").TestType<impor
71
72
  /**
72
73
  * Options to start the default screen reader with.
73
74
  */
74
- screenReaderStartOptions: CaptureCommandOptions;
75
+ screenReaderStartOptions: CaptureStartOptions;
75
76
  }, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
76
77
  export {};
@@ -124,30 +124,68 @@ exports.screenReaderTest = test_1.test.extend({
124
124
  // Ensure the document is ready and focused.
125
125
  await page.bringToFront();
126
126
  await page.locator("body").waitFor();
127
- // Open the web item chooser.
128
- await screenReaderPlaywright.perform(guidepup_1.voiceOverKeyCodeCommands.openItemChooser, { capture: false });
129
- await (0, delay_1.delay)(500);
130
- // Filter by "web content" - currently web content items for all browsers
131
- // are suffixed by "web content".
132
- for (const character of "web content") {
133
- await screenReaderPlaywright.type(character, { capture: false });
127
+ try {
128
+ // Add an interactive marker to the page that will force VoiceOver
129
+ // to listen to events emitted by Playwright interactions when
130
+ // navigated to.
131
+ await page.evaluate(() => {
132
+ const marker = document.createElement("input");
133
+ marker.id = "__guidepup_marker__";
134
+ marker.type = "text";
135
+ marker.value = "Guidepup Marker";
136
+ marker.readOnly = true;
137
+ marker.tabIndex = -1;
138
+ marker.autocomplete = "off";
139
+ marker.setAttribute("aria-label", "Guidepup Marker");
140
+ marker.style.cssText = `
141
+ position: absolute;
142
+ width: 1px;
143
+ height: 1px;
144
+ overflow: hidden;
145
+ clip: rect(0 0 0 0);
146
+ white-space: nowrap;
147
+ `;
148
+ document.body.prepend(marker);
149
+ });
150
+ // Open the web item chooser.
151
+ await screenReaderPlaywright.perform(guidepup_1.voiceOverKeyCodeCommands.openItemChooser, { capture: false });
152
+ await (0, delay_1.delay)(500);
153
+ // Filter by "web content" - currently web content items for all browsers
154
+ // are suffixed by "web content".
155
+ for (const character of "web content") {
156
+ await screenReaderPlaywright.type(character, { capture: false });
157
+ await (0, delay_1.delay)(100);
158
+ }
159
+ // Select the web content window spot.
160
+ await screenReaderPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Enter }, { capture: false });
134
161
  await (0, delay_1.delay)(100);
162
+ // Navigate into web content.
163
+ await screenReaderPlaywright.interact({ capture: false });
164
+ await (0, delay_1.delay)(100);
165
+ // Navigate to the beginning of the web content.
166
+ await screenReaderPlaywright.perform(guidepup_1.voiceOverKeyCodeCommands.moveToBeginningOfText, { capture: false });
167
+ await (0, delay_1.delay)(100);
168
+ // Cancel auto navigation
169
+ await screenReaderPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control }, { capture: false });
170
+ await (0, delay_1.delay)(100);
171
+ // Navigate to the Guidepup marker element at beginning of the web
172
+ // content.
173
+ await screenReaderPlaywright.perform(guidepup_1.voiceOverKeyCodeCommands.moveToBeginningOfText, { capture: false });
174
+ await (0, delay_1.delay)(100);
175
+ // Navigate to the first element of the page using the provided
176
+ // capture settings.
177
+ await screenReaderPlaywright.next({ capture });
178
+ }
179
+ finally {
180
+ // Remove the temporary Guidepup marker element to restore original
181
+ // page structure.
182
+ await page.evaluate(() => {
183
+ const marker = document.querySelector("#__guidepup_marker__");
184
+ if (marker) {
185
+ document.body.removeChild(marker);
186
+ }
187
+ });
135
188
  }
136
- // Select the web content window spot.
137
- await screenReaderPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Enter }, { capture: false });
138
- await (0, delay_1.delay)(100);
139
- // Navigate into web content.
140
- await screenReaderPlaywright.interact({ capture: false });
141
- await (0, delay_1.delay)(100);
142
- // Navigate to the beginning of the web content.
143
- await screenReaderPlaywright.perform(guidepup_1.voiceOverKeyCodeCommands.moveToBeginningOfText, { capture: false });
144
- await (0, delay_1.delay)(100);
145
- // Cancel auto navigation
146
- await screenReaderPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control }, { capture: false });
147
- await (0, delay_1.delay)(100);
148
- // Navigate to the beginning of the web content, using chosen capture
149
- // settings, so don't miss announcing the first item on the page.
150
- await screenReaderPlaywright.perform(guidepup_1.voiceOverKeyCodeCommands.moveToBeginningOfText, { capture });
151
189
  };
152
190
  }
153
191
  else {
@@ -1,4 +1,4 @@
1
- import type { CommandOptions, VoiceOver } from "@guidepup/guidepup";
1
+ import type { StartOptions, CommandOptions, VoiceOver } from "@guidepup/guidepup";
2
2
  /**
3
3
  * [API Reference](https://www.guidepup.dev/docs/api/class-voiceover)
4
4
  *
@@ -65,9 +65,9 @@ export declare const voiceOverTest: import("@playwright/test").TestType<import("
65
65
  */
66
66
  voiceOver: VoiceOverPlaywright;
67
67
  /**
68
- * [API Reference](https://www.guidepup.dev/docs/api/class-command-options)
68
+ * [API Reference](https://www.guidepup.dev/docs/api/class-start-options)
69
69
  *
70
70
  * Options to start VoiceOver with, see also [voiceOver.start([options])](https://www.guidepup.dev/docs/api/class-voiceover#voiceover-start).
71
71
  */
72
- voiceOverStartOptions: CommandOptions;
72
+ voiceOverStartOptions: StartOptions;
73
73
  }, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
@@ -29,30 +29,68 @@ exports.voiceOverTest = test_1.test.extend({
29
29
  // Ensure the document is ready and focused.
30
30
  await page.bringToFront();
31
31
  await page.locator("body").waitFor();
32
- // Open the web item chooser.
33
- await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.openItemChooser, { capture: false });
34
- await (0, delay_1.delay)(500);
35
- // Filter by "web content" - currently web content items for all browsers
36
- // are suffixed by "web content".
37
- for (const character of "web content") {
38
- await voiceOverPlaywright.type(character, { capture: false });
32
+ try {
33
+ // Add an interactive marker to the page that will force VoiceOver
34
+ // to listen to events emitted by Playwright interactions when
35
+ // navigated to.
36
+ await page.evaluate(() => {
37
+ const marker = document.createElement("input");
38
+ marker.id = "__guidepup_marker__";
39
+ marker.type = "text";
40
+ marker.value = "Guidepup Marker";
41
+ marker.readOnly = true;
42
+ marker.tabIndex = -1;
43
+ marker.autocomplete = "off";
44
+ marker.setAttribute("aria-label", "Guidepup Marker");
45
+ marker.style.cssText = `
46
+ position: absolute;
47
+ width: 1px;
48
+ height: 1px;
49
+ overflow: hidden;
50
+ clip: rect(0 0 0 0);
51
+ white-space: nowrap;
52
+ `;
53
+ document.body.prepend(marker);
54
+ });
55
+ // Open the web item chooser.
56
+ await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.openItemChooser, { capture: false });
57
+ await (0, delay_1.delay)(500);
58
+ // Filter by "web content" - currently web content items for all browsers
59
+ // are suffixed by "web content".
60
+ for (const character of "web content") {
61
+ await voiceOverPlaywright.type(character, { capture: false });
62
+ await (0, delay_1.delay)(100);
63
+ }
64
+ // Select the web content window spot.
65
+ await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Enter }, { capture: false });
39
66
  await (0, delay_1.delay)(100);
67
+ // Navigate into web content.
68
+ await voiceOverPlaywright.interact({ capture: false });
69
+ await (0, delay_1.delay)(100);
70
+ // Navigate to the beginning of the web content.
71
+ await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.moveToBeginningOfText, { capture: false });
72
+ await (0, delay_1.delay)(100);
73
+ // Cancel auto navigation
74
+ await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control }, { capture: false });
75
+ await (0, delay_1.delay)(100);
76
+ // Navigate to the Guidepup marker element at beginning of the web
77
+ // content.
78
+ await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.moveToBeginningOfText, { capture: false });
79
+ await (0, delay_1.delay)(100);
80
+ // Navigate to the first element of the page using the provided
81
+ // capture settings.
82
+ await voiceOverPlaywright.next({ capture });
83
+ }
84
+ finally {
85
+ // Remove the temporary Guidepup marker element to restore original
86
+ // page structure.
87
+ await page.evaluate(() => {
88
+ const marker = document.querySelector("#__guidepup_marker__");
89
+ if (marker) {
90
+ document.body.removeChild(marker);
91
+ }
92
+ });
40
93
  }
41
- // Select the web content window spot.
42
- await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Enter }, { capture: false });
43
- await (0, delay_1.delay)(100);
44
- // Navigate into web content.
45
- await voiceOverPlaywright.interact({ capture: false });
46
- await (0, delay_1.delay)(100);
47
- // Navigate to the beginning of the web content.
48
- await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.moveToBeginningOfText, { capture: false });
49
- await (0, delay_1.delay)(100);
50
- // Cancel auto navigation
51
- await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control }, { capture: false });
52
- await (0, delay_1.delay)(100);
53
- // Navigate to the beginning of the web content, using chosen capture
54
- // settings, so don't miss announcing the first item on the page.
55
- await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.moveToBeginningOfText, { capture });
56
94
  };
57
95
  await voiceOverPlaywright.start(voiceOverStartOptions);
58
96
  await use(voiceOverPlaywright);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guidepup/playwright",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Screen reader automation library for Playwright testing. ",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -44,7 +44,7 @@
44
44
  "test:voiceover:webkit": "playwright test --config ./examples/playwright-voiceover/webkit.config.ts ./examples/playwright-voiceover/tests/webkit/"
45
45
  },
46
46
  "devDependencies": {
47
- "@guidepup/guidepup": "^0.29.1",
47
+ "@guidepup/guidepup": "^0.33.0",
48
48
  "@guidepup/record": "^0.1.0",
49
49
  "@playwright/test": "^1.60.0",
50
50
  "@types/node": "^24.10.1",
@@ -58,7 +58,7 @@
58
58
  "typescript": "^5.9.3"
59
59
  },
60
60
  "peerDependencies": {
61
- "@guidepup/guidepup": ">=0.27.0",
61
+ "@guidepup/guidepup": ">=0.33.0",
62
62
  "@playwright/test": "^1.57.0"
63
63
  },
64
64
  "resolutions": {