@guidepup/playwright 0.17.0 → 0.18.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
@@ -1,8 +1,13 @@
1
- # Guidepup Playwright
1
+ <div align="center">
2
+ <img align="center" alt="" height="120px" width="120px" src="https://github.com/guidepup/guidepup/raw/main/img/logo.png">
3
+ <h1 align="center">Guidepup for Playwright</h1>
4
+ </div>
2
5
 
3
- <a href="https://www.npmjs.com/package/@guidepup/playwright"><img alt="@guidepup/playwright available on NPM" src="https://img.shields.io/npm/v/@guidepup/playwright" /></a>
4
- <a href="https://github.com/guidepup/guidepup-playwright/actions/workflows/test.yml"><img alt="@guidepup/playwright test workflows" src="https://github.com/guidepup/guidepup-playwright/workflows/Test/badge.svg" /></a>
5
- <a href="https://github.com/guidepup/guidepup-playwright/blob/main/LICENSE"><img alt="@guidepup/playwright uses the MIT license" src="https://img.shields.io/github/license/guidepup/guidepup-playwright" /></a>
6
+ <div align="center">
7
+ <a href="https://www.npmjs.com/package/@guidepup/playwright"><img alt="@guidepup/playwright available on NPM" src="https://img.shields.io/npm/v/@guidepup/playwright" /></a>
8
+ <a href="https://github.com/guidepup/guidepup-playwright/actions/workflows/test.yml"><img alt="@guidepup/playwright test workflows" src="https://github.com/guidepup/guidepup-playwright/workflows/Test/badge.svg" /></a>
9
+ <a href="https://github.com/guidepup/guidepup-playwright/blob/main/LICENSE"><img alt="@guidepup/playwright uses the MIT license" src="https://img.shields.io/github/license/guidepup/guidepup-playwright" /></a>
10
+ </div>
6
11
 
7
12
  ## [Documentation](https://guidepup.dev) | [API Reference](https://www.guidepup.dev/docs/api/class-guidepup)
8
13
 
@@ -12,26 +17,21 @@
12
17
  [![Windows Server 2022 Support](https://img.shields.io/badge/windows_server-2022-blue.svg?logo=windows)](https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2022)
13
18
  [![Windows Server 2025 Support](https://img.shields.io/badge/windows_server-2025-blue.svg?logo=windows)](https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2025)
14
19
 
15
- This package provides [Guidepup](https://github.com/guidepup/guidepup) integration with [Playwright](https://playwright.dev/) for writing screen reader tests that automate <a href="https://www.guidepup.dev/docs/api/class-voiceover"><b>VoiceOver on MacOS</b></a> and <a href="https://www.guidepup.dev/docs/api/class-nvda"><b>NVDA on Windows</b></a>.
20
+ Guidepup is a screen reader automation library for testing.
21
+
22
+ This package provides [Guidepup](https://github.com/guidepup/guidepup) integration with [Playwright](https://playwright.dev/) to enable testing with <a href="https://www.guidepup.dev/docs/api/class-voiceover"><b>VoiceOver on MacOS</b></a> and <a href="https://www.guidepup.dev/docs/api/class-nvda"><b>NVDA on Windows</b></a>.
16
23
 
17
24
  ## Capabilities
18
25
 
19
26
  - **Full Control** - If a screen reader has a keyboard command, then Guidepup supports it.
20
27
  - **Mirrors Real User Experience** - Assert on what users really do and hear when using screen readers.
21
28
 
22
- ## Getting Started
29
+ ## Getting started
23
30
 
24
- Set up your environment for screen reader automation with [`@guidepup/setup`](https://github.com/guidepup/setup):
31
+ Set up your machine for screen reader automation:
25
32
 
26
33
  ```sh
27
- npx @guidepup/setup
28
- ```
29
-
30
- If you are using GitHub Actions, check out the dedicated [`guidepup/setup-action`](https://github.com/marketplace/actions/guidepup-setup):
31
-
32
- ```yaml
33
- - name: Setup Environment
34
- uses: guidepup/setup-action
34
+ npx @guidepup/setup setup
35
35
  ```
36
36
 
37
37
  Install `@guidepup/playwright` to your project:
@@ -40,7 +40,14 @@ Install `@guidepup/playwright` to your project:
40
40
  npm install --save-dev @guidepup/playwright @guidepup/guidepup @playwright/test
41
41
  ```
42
42
 
43
- Note: you require `@guidepup/guidepup` and `@playwright/test` as they are peer dependencies to this project.
43
+ > [!NOTE]
44
+ > `@guidepup/guidepup` and `@playwright/test` are required as peer dependencies of this project.
45
+
46
+ Install the Guidepup screen reader assets:
47
+
48
+ ```sh
49
+ npx @guidepup/setup install
50
+ ```
44
51
 
45
52
  And get cracking with your first screen reader tests in Playwright!
46
53
 
@@ -48,11 +55,9 @@ And get cracking with your first screen reader tests in Playwright!
48
55
 
49
56
  Head over to the [Guidepup Website](https://www.guidepup.dev/) for guides, real world examples, environment setup, and complete API documentation with examples.
50
57
 
51
- You can also check out these [awesome examples](https://github.com/guidepup/guidepup/tree/main/examples) to learn how you could use Guidepup with Playwright in your projects.
52
-
53
- Alternatively check out [this project](https://github.com/guidepup/aria-at-tests) which runs several thousand tests to assert screen reader compatibility against [W3C ARIA-AT](https://github.com/w3c/aria-at) test suite.
58
+ You can also check out these [examples](https://github.com/guidepup/guidepup-playwright/tree/main/examples) to learn how you could use Guidepup with Playwright in your projects.
54
59
 
55
- ### Playwright Config
60
+ ### Playwright config
56
61
 
57
62
  In your `playwright.config.ts` add the following for the best results with Guidepup for Screen Reader automation:
58
63
 
@@ -71,13 +76,13 @@ export default config;
71
76
 
72
77
  Check out the configuration this adds [in the `config.ts` file](./src/config.ts).
73
78
 
74
- ### Web Content Navigation
79
+ ### Web content navigation
75
80
 
76
- In addition to the Guidepup APIs the `voiceOver` and `nvda` instances provided by the Guidepup Playwright setup have an additional utility method `.navigateToWebContent()`.
81
+ In addition to the Guidepup APIs the `screenReader`, `voiceOver`, and `nvda` instances provided by the Guidepup Playwright setup have an additional utility method `.navigateToWebContent()`.
77
82
 
78
83
  This method will navigate the screen reader to the first element of the document body in the browser.
79
84
 
80
- Use this method after you navigate to a page and have made any necessary checks that the page has loaded as expected. For example, this is how you might use the method with NVDA:
85
+ Use this method after you navigate to a page and have made any necessary checks that the page has loaded as expected. For example, this is how you might use the method:
81
86
 
82
87
  ```ts
83
88
  // Navigate to the desired page
@@ -89,7 +94,7 @@ await page.goto("https://github.com/guidepup/guidepup", {
89
94
  await page.locator('header[role="banner"]').waitFor();
90
95
 
91
96
  // Navigate to the web content
92
- await nvda.navigateToWebContent();
97
+ await screenReader.navigateToWebContent();
93
98
 
94
99
  // ... some commands
95
100
  ```
@@ -100,15 +105,18 @@ await nvda.navigateToWebContent();
100
105
  // ... some commands
101
106
 
102
107
  // Store spoken phrases
103
- const spokenPhrases = await nvda.spokenPhraseLog();
108
+ const spokenPhrases = await screenReader.spokenPhraseLog();
104
109
 
105
110
  // Navigate to the web content
106
- await nvda.navigateToWebContent();
111
+ await screenReader.navigateToWebContent();
107
112
 
108
113
  // ... some commands
109
114
 
110
115
  // Collect all spoken phrases
111
- const allSpokenPhrases = [...spokenPhrases, ...(await nvda.spokenPhraseLog())];
116
+ const allSpokenPhrases = [
117
+ ...spokenPhrases,
118
+ ...(await screenReader.spokenPhraseLog()),
119
+ ];
112
120
 
113
121
  // ... do something with spoken phrases
114
122
  ```
@@ -119,14 +127,22 @@ or pass a flag to prevent log clearing:
119
127
  // ... some commands
120
128
 
121
129
  // Navigate to the web content
122
- await nvda.navigateToWebContent(false);
130
+ await screenReader.navigateToWebContent(false);
123
131
 
124
132
  // ... some commands
125
133
  ```
126
134
 
127
- ### Providing Screen Reader Start Options
135
+ ### Providing screen reader start options
128
136
 
129
- The options provided to `nvda.start([options])` or `voiceOver.start([options])` can be configured using `test.use(config)` as follows:
137
+ The options provided to `screenReader.start([options])`, `nvda.start([options])`, or `voiceOver.start([options])` can be configured using `test.use(config)` as follows:
138
+
139
+ ```ts
140
+ // Screen Reader Example
141
+ import { screenReaderTest as test } from "@guidepup/playwright";
142
+
143
+ // Capture all spoken phrases, including usage hints
144
+ test.use({ screenReaderStartOptions: { capture: true } });
145
+ ```
130
146
 
131
147
  ```ts
132
148
  // VoiceOver Example
@@ -146,7 +162,7 @@ test.use({ nvdaStartOptions: { capture: true } });
146
162
 
147
163
  The default for VoiceOver and NVDA is set to `"initial"`. `true` captures all spoken phrases, including usage hints. `false` disables spoken phrase capture.
148
164
 
149
- ### VoiceOver Example
165
+ ### VoiceOver example
150
166
 
151
167
  `playwright.config.ts`:
152
168
 
@@ -206,7 +222,7 @@ test.describe("Playwright VoiceOver", () => {
206
222
  });
207
223
  ```
208
224
 
209
- ### NVDA Example
225
+ ### NVDA example
210
226
 
211
227
  `playwright.config.ts`:
212
228
 
@@ -268,7 +284,7 @@ test.describe("Playwright NVDA", () => {
268
284
  });
269
285
  ```
270
286
 
271
- ## Powerful Tooling
287
+ ## Powerful tooling
272
288
 
273
289
  Check out some of the other Guidepup modules:
274
290
 
package/lib/delay.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function delay(ms: number): Promise<unknown>;
package/lib/delay.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.delay = delay;
4
+ async function delay(ms) {
5
+ return new Promise((resolve) => setTimeout(resolve, ms));
6
+ }
package/lib/nvdaTest.d.ts CHANGED
@@ -31,10 +31,8 @@ export interface NVDAPlaywright extends NVDA {
31
31
  * of the browser's web content.
32
32
  *
33
33
  * This command should be used after page navigation.
34
- *
35
- * Note: this command clears all logs by default.
36
34
  */
37
- navigateToWebContent(clearLogs?: boolean): Promise<void>;
35
+ navigateToWebContent(options?: Pick<CommandOptions, "capture">): Promise<void>;
38
36
  }
39
37
  /**
40
38
  * These tests extend the default Playwright environment that launches the
package/lib/nvdaTest.js CHANGED
@@ -4,6 +4,7 @@ exports.nvdaTest = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const guidepup_1 = require("@guidepup/guidepup");
6
6
  const applicationNameMap_1 = require("./applicationNameMap");
7
+ const delay_1 = require("./delay");
7
8
  const nvdaPlaywright = guidepup_1.nvda;
8
9
  const MAX_APPLICATION_SWITCH_RETRY_COUNT = 10;
9
10
  const SWITCH_APPLICATION = {
@@ -37,7 +38,8 @@ const focusBrowser = async ({ applicationName, pageTitle, }) => {
37
38
  let applicationSwitchRetryCount = 0;
38
39
  while (applicationSwitchRetryCount < MAX_APPLICATION_SWITCH_RETRY_COUNT) {
39
40
  applicationSwitchRetryCount++;
40
- await nvdaPlaywright.perform(SWITCH_APPLICATION);
41
+ await nvdaPlaywright.perform(SWITCH_APPLICATION, { capture: false });
42
+ await (0, delay_1.delay)(500);
41
43
  await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.reportTitle);
42
44
  windowTitle = await nvdaPlaywright.lastSpokenPhrase();
43
45
  if (hasFocus({ applicationName, pageTitle, windowTitle })) {
@@ -59,15 +61,17 @@ exports.nvdaTest = test_1.test.extend({
59
61
  if (!applicationName) {
60
62
  throw new Error(`Browser ${browserName} is not installed.`);
61
63
  }
62
- nvdaPlaywright.navigateToWebContent = async (clearLogs = true) => {
64
+ nvdaPlaywright.navigateToWebContent = async ({ capture } = {}) => {
65
+ const currentSpokenPhraseLog = [
66
+ ...(await nvdaPlaywright.spokenPhraseLog()),
67
+ ];
68
+ const currentItemTextLog = [...(await nvdaPlaywright.itemTextLog())];
63
69
  // Make sure NVDA is not in focus mode.
64
- await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.exitFocusMode);
65
- const pageTitle = await page.title();
70
+ await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.exitFocusMode, { capture: false });
71
+ await (0, delay_1.delay)(100);
66
72
  // Ensure application is brought to front and focused.
67
- await focusBrowser({
68
- applicationName,
69
- pageTitle,
70
- });
73
+ const pageTitle = await page.title();
74
+ await focusBrowser({ applicationName, pageTitle });
71
75
  // Ensure the document is ready and focused.
72
76
  await page.bringToFront();
73
77
  await page.locator("body").waitFor();
@@ -84,16 +88,23 @@ exports.nvdaTest = test_1.test.extend({
84
88
  // we exit focus mode and move NVDA to the top of the page.
85
89
  //
86
90
  // REF: https://github.com/nvaccess/nvda/issues/5758
87
- await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.readNextFocusableItem);
88
- await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.toggleBetweenBrowseAndFocusMode);
89
- await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.toggleBetweenBrowseAndFocusMode);
90
- await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.exitFocusMode);
91
- await nvdaPlaywright.perform(MOVE_TO_TOP);
92
- if (clearLogs) {
93
- // Clear out logs.
94
- await nvdaPlaywright.clearItemTextLog();
95
- await nvdaPlaywright.clearSpokenPhraseLog();
96
- }
91
+ await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.readNextFocusableItem, { capture: false });
92
+ await (0, delay_1.delay)(100);
93
+ await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.toggleBetweenBrowseAndFocusMode, { capture: false });
94
+ await (0, delay_1.delay)(100);
95
+ await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.toggleBetweenBrowseAndFocusMode, { capture: false });
96
+ await (0, delay_1.delay)(100);
97
+ await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.exitFocusMode, { capture: false });
98
+ await (0, delay_1.delay)(100);
99
+ await nvdaPlaywright.clearSpokenPhraseLog();
100
+ await nvdaPlaywright.clearItemTextLog();
101
+ const spokenPhraseLog = await nvdaPlaywright.spokenPhraseLog();
102
+ const itemTextLog = await nvdaPlaywright.itemTextLog();
103
+ spokenPhraseLog.push(...currentSpokenPhraseLog);
104
+ itemTextLog.push(...currentItemTextLog);
105
+ // Navigate to the beginning of the web content, using chosen capture
106
+ // settings, so don't miss announcing the first item on the page.
107
+ await nvdaPlaywright.perform(MOVE_TO_TOP, { capture });
97
108
  };
98
109
  await nvdaPlaywright.start(nvdaStartOptions);
99
110
  await use(nvdaPlaywright);
@@ -32,10 +32,8 @@ export interface ScreenReaderPlaywright extends ScreenReader {
32
32
  * the beginning of the browser's web content.
33
33
  *
34
34
  * This command should be used after page navigation.
35
- *
36
- * Note: this command clears all logs by default.
37
35
  */
38
- navigateToWebContent(clearLogs?: boolean): Promise<void>;
36
+ navigateToWebContent(options?: Pick<CommandOptions, "capture">): Promise<void>;
39
37
  }
40
38
  /**
41
39
  * These tests extend the default Playwright environment that launches the
@@ -4,6 +4,7 @@ exports.screenReaderTest = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const guidepup_1 = require("@guidepup/guidepup");
6
6
  const applicationNameMap_1 = require("./applicationNameMap");
7
+ const delay_1 = require("./delay");
7
8
  const MAX_APPLICATION_SWITCH_RETRY_COUNT = 10;
8
9
  const SWITCH_APPLICATION = {
9
10
  keyCode: [guidepup_1.WindowsKeyCodes.Escape],
@@ -36,7 +37,10 @@ const focusBrowser = async ({ applicationName, pageTitle, }) => {
36
37
  let applicationSwitchRetryCount = 0;
37
38
  while (applicationSwitchRetryCount < MAX_APPLICATION_SWITCH_RETRY_COUNT) {
38
39
  applicationSwitchRetryCount++;
39
- await screenReaderPlaywright.perform(SWITCH_APPLICATION);
40
+ await screenReaderPlaywright.perform(SWITCH_APPLICATION, {
41
+ capture: false,
42
+ });
43
+ await (0, delay_1.delay)(500);
40
44
  await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.reportTitle);
41
45
  windowTitle = await screenReaderPlaywright.lastSpokenPhrase();
42
46
  if (hasFocus({ applicationName, pageTitle, windowTitle })) {
@@ -62,11 +66,18 @@ exports.screenReaderTest = test_1.test.extend({
62
66
  throw new Error(`Browser ${browserName} is not installed.`);
63
67
  }
64
68
  if (guidepup_1.nvda.default()) {
65
- screenReaderPlaywright.navigateToWebContent = async (clearLogs = true) => {
69
+ screenReaderPlaywright.navigateToWebContent = async ({ capture, } = {}) => {
70
+ const currentSpokenPhraseLog = [
71
+ ...(await screenReaderPlaywright.spokenPhraseLog()),
72
+ ];
73
+ const currentItemTextLog = [
74
+ ...(await screenReaderPlaywright.itemTextLog()),
75
+ ];
66
76
  // Make sure NVDA is not in focus mode.
67
- await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.exitFocusMode);
68
- const pageTitle = await page.title();
77
+ await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.exitFocusMode, { capture: false });
78
+ await (0, delay_1.delay)(100);
69
79
  // Ensure application is brought to front and focused.
80
+ const pageTitle = await page.title();
70
81
  await focusBrowser({ applicationName, pageTitle });
71
82
  // Ensure the document is ready and focused.
72
83
  await page.bringToFront();
@@ -84,40 +95,59 @@ exports.screenReaderTest = test_1.test.extend({
84
95
  // we exit focus mode and move NVDA to the top of the page.
85
96
  //
86
97
  // REF: https://github.com/nvaccess/nvda/issues/5758
87
- await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.readNextFocusableItem);
88
- await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.toggleBetweenBrowseAndFocusMode);
89
- await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.toggleBetweenBrowseAndFocusMode);
90
- await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.exitFocusMode);
91
- await screenReaderPlaywright.perform(MOVE_TO_TOP);
92
- if (clearLogs) {
93
- // Clear out logs.
94
- await screenReaderPlaywright.clearItemTextLog();
95
- await screenReaderPlaywright.clearSpokenPhraseLog();
96
- }
98
+ await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.readNextFocusableItem, { capture: false });
99
+ await (0, delay_1.delay)(100);
100
+ await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.toggleBetweenBrowseAndFocusMode, { capture: false });
101
+ await (0, delay_1.delay)(100);
102
+ await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.toggleBetweenBrowseAndFocusMode, { capture: false });
103
+ await (0, delay_1.delay)(100);
104
+ await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.exitFocusMode, { capture: false });
105
+ await (0, delay_1.delay)(100);
106
+ await screenReaderPlaywright.clearSpokenPhraseLog();
107
+ await screenReaderPlaywright.clearItemTextLog();
108
+ const spokenPhraseLog = await screenReaderPlaywright.spokenPhraseLog();
109
+ const itemTextLog = await screenReaderPlaywright.itemTextLog();
110
+ spokenPhraseLog.push(...currentSpokenPhraseLog);
111
+ itemTextLog.push(...currentItemTextLog);
112
+ // Navigate to the beginning of the web content, using chosen capture
113
+ // settings, so don't miss announcing the first item on the page.
114
+ await screenReaderPlaywright.perform(MOVE_TO_TOP, { capture });
97
115
  };
98
116
  }
99
117
  else if (guidepup_1.voiceOver.default()) {
100
- screenReaderPlaywright.navigateToWebContent = async (clearLogs = true) => {
118
+ screenReaderPlaywright.navigateToWebContent = async ({ capture, } = {}) => {
119
+ // Ensure application is brought to front and focused.
101
120
  await (0, guidepup_1.macOSActivate)(applicationName);
102
- await screenReaderPlaywright.perform({
103
- keyCode: guidepup_1.MacOSKeyCodes.Control,
104
- });
121
+ // Cancel auto navigation.
122
+ await screenReaderPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control }, { capture: false });
123
+ await (0, delay_1.delay)(100);
124
+ // Ensure the document is ready and focused.
105
125
  await page.bringToFront();
106
126
  await page.locator("body").waitFor();
107
- await screenReaderPlaywright.perform(guidepup_1.voiceOverKeyCodeCommands.openItemChooser);
108
- await screenReaderPlaywright.type("web content");
109
- await screenReaderPlaywright.perform({
110
- keyCode: guidepup_1.MacOSKeyCodes.Enter,
111
- });
112
- await screenReaderPlaywright.interact();
113
- await screenReaderPlaywright.perform(guidepup_1.voiceOverKeyCodeCommands.moveToBeginningOfText);
114
- await screenReaderPlaywright.perform({
115
- keyCode: guidepup_1.MacOSKeyCodes.Control,
116
- });
117
- if (clearLogs) {
118
- await screenReaderPlaywright.clearItemTextLog();
119
- await screenReaderPlaywright.clearSpokenPhraseLog();
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 });
134
+ await (0, delay_1.delay)(100);
120
135
  }
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 });
121
151
  };
122
152
  }
123
153
  else {
@@ -29,10 +29,8 @@ export interface VoiceOverPlaywright extends VoiceOver {
29
29
  * of the browser's web content.
30
30
  *
31
31
  * This command should be used after a page navigation has completed.
32
- *
33
- * Note: this command clears all logs by default.
34
32
  */
35
- navigateToWebContent(clearLogs?: boolean): Promise<void>;
33
+ navigateToWebContent(options?: Pick<CommandOptions, "capture">): Promise<void>;
36
34
  }
37
35
  /**
38
36
  * These tests extend the default Playwright environment that launches the
@@ -4,6 +4,7 @@ exports.voiceOverTest = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const guidepup_1 = require("@guidepup/guidepup");
6
6
  const applicationNameMap_1 = require("./applicationNameMap");
7
+ const delay_1 = require("./delay");
7
8
  const voiceOverPlaywright = guidepup_1.voiceOver;
8
9
  /**
9
10
  * These tests extend the default Playwright environment that launches the
@@ -19,32 +20,39 @@ exports.voiceOverTest = test_1.test.extend({
19
20
  if (!applicationName) {
20
21
  throw new Error(`Browser ${browserName} is not installed.`);
21
22
  }
22
- voiceOverPlaywright.navigateToWebContent = async (clearLogs = true) => {
23
+ voiceOverPlaywright.navigateToWebContent = async ({ capture } = {}) => {
23
24
  // Ensure application is brought to front and focused.
24
25
  await (0, guidepup_1.macOSActivate)(applicationName);
25
- // Cancel auto navigation
26
- await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control });
26
+ // Cancel auto navigation.
27
+ await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control }, { capture: false });
28
+ await (0, delay_1.delay)(100);
27
29
  // Ensure the document is ready and focused.
28
30
  await page.bringToFront();
29
31
  await page.locator("body").waitFor();
30
32
  // Open the web item chooser.
31
- await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.openItemChooser);
33
+ await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.openItemChooser, { capture: false });
34
+ await (0, delay_1.delay)(500);
32
35
  // Filter by "web content" - currently web content items for all browsers
33
36
  // are suffixed by "web content".
34
- await voiceOverPlaywright.type("web content");
37
+ for (const character of "web content") {
38
+ await voiceOverPlaywright.type(character, { capture: false });
39
+ await (0, delay_1.delay)(100);
40
+ }
35
41
  // Select the web content window spot.
36
- await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Enter });
42
+ await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Enter }, { capture: false });
43
+ await (0, delay_1.delay)(100);
37
44
  // Navigate into web content.
38
- await voiceOverPlaywright.interact();
45
+ await voiceOverPlaywright.interact({ capture: false });
46
+ await (0, delay_1.delay)(100);
39
47
  // Navigate to the beginning of the web content.
40
- await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.moveToBeginningOfText);
48
+ await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.moveToBeginningOfText, { capture: false });
49
+ await (0, delay_1.delay)(100);
41
50
  // Cancel auto navigation
42
- await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control });
43
- if (clearLogs) {
44
- // Clear out logs.
45
- await voiceOverPlaywright.clearItemTextLog();
46
- await voiceOverPlaywright.clearSpokenPhraseLog();
47
- }
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 });
48
56
  };
49
57
  await voiceOverPlaywright.start(voiceOverStartOptions);
50
58
  await use(voiceOverPlaywright);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guidepup/playwright",
3
- "version": "0.17.0",
3
+ "version": "0.18.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.27.0",
47
+ "@guidepup/guidepup": "^0.29.1",
48
48
  "@guidepup/record": "^0.1.0",
49
49
  "@playwright/test": "^1.60.0",
50
50
  "@types/node": "^24.10.1",