@guidepup/playwright 0.19.0 → 0.20.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.
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.navigateVoiceOverToWebContent = void 0;
4
+ const guidepup_1 = require("@guidepup/guidepup");
5
+ const delay_1 = require("./delay");
6
+ const MAX_WEB_CONTENT_SEARCH_ATTEMPTS = 10;
7
+ const cancelCurrentInteraction = async (voiceOver) => {
8
+ await voiceOver.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control }, { capture: false });
9
+ };
10
+ const closeMenus = async (voiceOver) => {
11
+ await voiceOver.perform({ keyCode: guidepup_1.MacOSKeyCodes.Escape }, { capture: false });
12
+ };
13
+ const openItemChooser = async (voiceOver) => {
14
+ let lastSpokenPhrase = "";
15
+ while (!lastSpokenPhrase.toLowerCase().includes("item chooser")) {
16
+ await cancelCurrentInteraction(voiceOver);
17
+ await (0, delay_1.delay)(100);
18
+ await closeMenus(voiceOver);
19
+ await (0, delay_1.delay)(100);
20
+ await voiceOver.perform(guidepup_1.voiceOverKeyCodeCommands.openItemChooser, {
21
+ capture: true,
22
+ });
23
+ lastSpokenPhrase = await voiceOver.lastSpokenPhrase();
24
+ }
25
+ };
26
+ const selectWebContentItem = async (voiceOver) => {
27
+ let matched = false;
28
+ for (let attempt = 0; attempt < MAX_WEB_CONTENT_SEARCH_ATTEMPTS && !matched; attempt++) {
29
+ for (const character of "web content") {
30
+ await cancelCurrentInteraction(voiceOver);
31
+ await (0, delay_1.delay)(100);
32
+ await voiceOver.type(character, { capture: "initial" });
33
+ const lastSpokenPhrase = await voiceOver.lastSpokenPhrase();
34
+ if (lastSpokenPhrase.toLowerCase().includes("web content")) {
35
+ matched = true;
36
+ break;
37
+ }
38
+ }
39
+ if (matched) {
40
+ break;
41
+ }
42
+ if (attempt + 1 < MAX_WEB_CONTENT_SEARCH_ATTEMPTS) {
43
+ await voiceOver.perform({ keyCode: guidepup_1.MacOSKeyCodes.Backspace }, { capture: false });
44
+ await (0, delay_1.delay)(100);
45
+ }
46
+ }
47
+ if (!matched) {
48
+ throw new Error(`Unable to find "web content" in the VoiceOver Item Chooser after ${MAX_WEB_CONTENT_SEARCH_ATTEMPTS} attempts.`);
49
+ }
50
+ await voiceOver.perform({ keyCode: guidepup_1.MacOSKeyCodes.Enter }, { capture: false });
51
+ };
52
+ const navigateVoiceOverToWebContent = async ({ voiceOver, page, applicationId, capture, }) => {
53
+ const currentSpokenPhraseLog = [...(await voiceOver.spokenPhraseLog())];
54
+ const currentItemTextLog = [...(await voiceOver.itemTextLog())];
55
+ await (0, guidepup_1.macOSActivateId)(applicationId);
56
+ await cancelCurrentInteraction(voiceOver);
57
+ await (0, delay_1.delay)(100);
58
+ await page.bringToFront();
59
+ await page.locator("body").waitFor();
60
+ try {
61
+ await page.evaluate(() => {
62
+ const marker = document.createElement("input");
63
+ marker.id = "__guidepup_marker__";
64
+ marker.type = "text";
65
+ marker.value = "Guidepup Marker";
66
+ marker.readOnly = true;
67
+ marker.tabIndex = -1;
68
+ marker.autocomplete = "off";
69
+ marker.setAttribute("aria-label", "Guidepup Marker");
70
+ marker.style.cssText = `
71
+ position: absolute;
72
+ width: 1px;
73
+ height: 1px;
74
+ overflow: hidden;
75
+ clip: rect(0 0 0 0);
76
+ white-space: nowrap;
77
+ `;
78
+ document.body.prepend(marker);
79
+ });
80
+ await openItemChooser(voiceOver);
81
+ await selectWebContentItem(voiceOver);
82
+ await voiceOver.interact({ capture: false });
83
+ await (0, delay_1.delay)(100);
84
+ await voiceOver.clearSpokenPhraseLog();
85
+ await voiceOver.clearItemTextLog();
86
+ const spokenPhraseLog = await voiceOver.spokenPhraseLog();
87
+ const itemTextLog = await voiceOver.itemTextLog();
88
+ spokenPhraseLog.push(...currentSpokenPhraseLog);
89
+ itemTextLog.push(...currentItemTextLog);
90
+ await voiceOver.next({ capture });
91
+ }
92
+ finally {
93
+ await page.evaluate(() => {
94
+ const marker = document.querySelector("#__guidepup_marker__");
95
+ if (marker) {
96
+ document.body.removeChild(marker);
97
+ }
98
+ });
99
+ }
100
+ };
101
+ exports.navigateVoiceOverToWebContent = navigateVoiceOverToWebContent;
package/lib/nvdaTest.js CHANGED
@@ -4,49 +4,8 @@ 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
+ const navigateNVDAtoWebContent_1 = require("./navigateNVDAtoWebContent");
8
8
  const nvdaPlaywright = guidepup_1.nvda;
9
- const MAX_APPLICATION_SWITCH_RETRY_COUNT = 10;
10
- const SWITCH_APPLICATION = {
11
- keyCode: [guidepup_1.WindowsKeyCodes.Escape],
12
- modifiers: [guidepup_1.WindowsModifiers.Alt],
13
- };
14
- const MOVE_TO_TOP = {
15
- keyCode: [guidepup_1.WindowsKeyCodes.Home],
16
- modifiers: [guidepup_1.WindowsModifiers.Control],
17
- };
18
- const cleanString = (str) => str
19
- .toLowerCase()
20
- // REF: https://github.com/nvaccess/nvda/blob/master/source/locale/en/symbols.dic
21
- .replace(/[|¦:;'"`\-‐–—·_()[\]{}\\^~]/g, " ")
22
- .replace(/\s+/g, " ")
23
- .trim();
24
- const hasFocus = ({ applicationName, pageTitle, windowTitle, }) => {
25
- const cleanedApplicationName = cleanString(applicationName);
26
- const cleanedPageTitle = cleanString(pageTitle);
27
- const cleanedWindowTitle = cleanString(windowTitle);
28
- return ((cleanedPageTitle.length &&
29
- cleanedWindowTitle.startsWith(cleanedPageTitle)) ||
30
- cleanedWindowTitle.includes(cleanedApplicationName));
31
- };
32
- const focusBrowser = async ({ applicationName, pageTitle, }) => {
33
- await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.reportTitle);
34
- let windowTitle = await nvdaPlaywright.lastSpokenPhrase();
35
- if (hasFocus({ applicationName, pageTitle, windowTitle })) {
36
- return;
37
- }
38
- let applicationSwitchRetryCount = 0;
39
- while (applicationSwitchRetryCount < MAX_APPLICATION_SWITCH_RETRY_COUNT) {
40
- applicationSwitchRetryCount++;
41
- await nvdaPlaywright.perform(SWITCH_APPLICATION, { capture: false });
42
- await (0, delay_1.delay)(500);
43
- await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.reportTitle);
44
- windowTitle = await nvdaPlaywright.lastSpokenPhrase();
45
- if (hasFocus({ applicationName, pageTitle, windowTitle })) {
46
- break;
47
- }
48
- }
49
- };
50
9
  /**
51
10
  * These tests extend the default Playwright environment that launches the
52
11
  * browser with a running instance of the NVDA screen reader for Windows.
@@ -59,53 +18,14 @@ exports.nvdaTest = test_1.test.extend({
59
18
  try {
60
19
  const applicationName = applicationNameMap_1.applicationNameMap[browserName];
61
20
  if (!applicationName) {
62
- throw new Error(`Browser ${browserName} is not installed.`);
21
+ throw new Error(`Browser ${browserName} is not recognised.`);
63
22
  }
64
- nvdaPlaywright.navigateToWebContent = async ({ capture } = {}) => {
65
- const currentSpokenPhraseLog = [
66
- ...(await nvdaPlaywright.spokenPhraseLog()),
67
- ];
68
- const currentItemTextLog = [...(await nvdaPlaywright.itemTextLog())];
69
- // Make sure NVDA is not in focus mode.
70
- await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.exitFocusMode, { capture: false });
71
- await (0, delay_1.delay)(100);
72
- // Ensure application is brought to front and focused.
73
- const pageTitle = await page.title();
74
- await focusBrowser({ applicationName, pageTitle });
75
- // Ensure the document is ready and focused.
76
- await page.bringToFront();
77
- await page.locator("body").waitFor();
78
- await page.locator("body").focus();
79
- await page.locator("body").click();
80
- await page.locator("body").blur();
81
- // NVDA appears to not work well with Firefox when switching between
82
- // applications resulting in the entire browser window having NVDA focus
83
- // with focus mode.
84
- //
85
- // One workaround is to tab to the next focusable item. From there we can
86
- // toggle into (yes although we are already in it...) focus mode and back
87
- // out. In case this ever transpires to not happen as expect, we then ensure
88
- // we exit focus mode and move NVDA to the top of the page.
89
- //
90
- // REF: https://github.com/nvaccess/nvda/issues/5758
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 });
108
- };
23
+ nvdaPlaywright.navigateToWebContent = ({ capture } = {}) => (0, navigateNVDAtoWebContent_1.navigateNVDAtoWebContent)({
24
+ nvda: nvdaPlaywright,
25
+ page,
26
+ applicationName,
27
+ capture,
28
+ });
109
29
  await nvdaPlaywright.start(nvdaStartOptions);
110
30
  await use(nvdaPlaywright);
111
31
  }
@@ -0,0 +1,73 @@
1
+ import { type CommandOptions, type Orca, type StartOptions } from "@guidepup/guidepup";
2
+ /**
3
+ * [API Reference](https://www.guidepup.dev/docs/api/class-orca)
4
+ *
5
+ * This object can be used to launch and control Orca.
6
+ *
7
+ * Here's a typical example:
8
+ *
9
+ * ```ts
10
+ * import { unstable_orca } from "@guidepup/guidepup";
11
+ *
12
+ * (async () => {
13
+ * // Start Orca.
14
+ * await unstable_orca.start();
15
+ *
16
+ * // Move to the next item.
17
+ * await unstable_orca.next();
18
+ *
19
+ * // ... perform some commands.
20
+ *
21
+ * // Stop Orca.
22
+ * await unstable_orca.stop();
23
+ * })();
24
+ * ```
25
+ */
26
+ export interface OrcaPlaywright extends Orca {
27
+ /**
28
+ * Guidepup Playwright specific command that navigates Orca to the beginning
29
+ * of the browser's web content.
30
+ *
31
+ * This command should be used after a page navigation has completed.
32
+ */
33
+ navigateToWebContent(options?: Pick<CommandOptions, "capture">): Promise<void>;
34
+ }
35
+ /**
36
+ * These tests extend the default Playwright environment that launches the
37
+ * browser with a running instance of the Orca screen reader for macOS.
38
+ *
39
+ * A fresh started Orca instance `orca` is provided to each test.
40
+ */
41
+ export declare const orcaTest: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions & {
42
+ /**
43
+ * [API Reference](https://www.guidepup.dev/docs/api/class-orca)
44
+ *
45
+ * This object can be used to launch and control Orca.
46
+ *
47
+ * Here's a typical example:
48
+ *
49
+ * ```ts
50
+ * import { unstable_orca } from "@guidepup/guidepup";
51
+ *
52
+ * (async () => {
53
+ * // Start Orca.
54
+ * await unstable_orca.start();
55
+ *
56
+ * // Move to the next item.
57
+ * await unstable_orca.next();
58
+ *
59
+ * // ... perform some commands.
60
+ *
61
+ * // Stop Orca.
62
+ * await unstable_orca.stop();
63
+ * })();
64
+ * ```
65
+ */
66
+ orca: OrcaPlaywright;
67
+ /**
68
+ * [API Reference](https://www.guidepup.dev/docs/api/class-start-options)
69
+ *
70
+ * Options to start Orca with, see also [unstable_orca.start([options])](https://www.guidepup.dev/docs/api/class-orca#unstable-orca-start).
71
+ */
72
+ orcaStartOptions: StartOptions;
73
+ }, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.orcaTest = void 0;
4
+ const test_1 = require("@playwright/test");
5
+ const guidepup_1 = require("@guidepup/guidepup");
6
+ const navigateOrcaToWebContent_1 = require("./navigateOrcaToWebContent");
7
+ const orcaPlaywright = guidepup_1.unstable_orca;
8
+ /**
9
+ * These tests extend the default Playwright environment that launches the
10
+ * browser with a running instance of the Orca screen reader for macOS.
11
+ *
12
+ * A fresh started Orca instance `orca` is provided to each test.
13
+ */
14
+ exports.orcaTest = test_1.test.extend({
15
+ orcaStartOptions: { capture: "initial" },
16
+ orca: async ({ page, orcaStartOptions }, use) => {
17
+ try {
18
+ orcaPlaywright.navigateToWebContent = ({ capture } = {}) => (0, navigateOrcaToWebContent_1.navigateOrcaToWebContent)({
19
+ orca: orcaPlaywright,
20
+ page,
21
+ capture,
22
+ });
23
+ await orcaPlaywright.start(orcaStartOptions);
24
+ await use(orcaPlaywright);
25
+ }
26
+ finally {
27
+ try {
28
+ await orcaPlaywright.stop();
29
+ }
30
+ catch {
31
+ // swallow stop failure
32
+ }
33
+ }
34
+ },
35
+ });
@@ -5,6 +5,8 @@ type Prettify<T> = {
5
5
  type CaptureCommandOptions = Prettify<Pick<CommandOptions, "capture">>;
6
6
  type CaptureStartOptions = Prettify<Pick<StartOptions, "capture" | "settings">>;
7
7
  /**
8
+ * [API Reference](https://www.guidepup.dev/docs/api/class-screenreader)
9
+ *
8
10
  * This object can be used to launch and control the default screen reader for
9
11
  * the environment.
10
12
  *
@@ -46,6 +48,8 @@ export interface ScreenReaderPlaywright extends ScreenReader {
46
48
  */
47
49
  export declare const screenReaderTest: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions & {
48
50
  /**
51
+ * [API Reference](https://www.guidepup.dev/docs/api/class-screenreader)
52
+ *
49
53
  * This object can be used to launch and control the default screen reader for
50
54
  * the environment.
51
55
  *
@@ -70,7 +74,9 @@ export declare const screenReaderTest: import("@playwright/test").TestType<impor
70
74
  */
71
75
  screenReader: ScreenReaderPlaywright;
72
76
  /**
73
- * Options to start the default screen reader with.
77
+ * [API Reference](https://www.guidepup.dev/docs/api/class-start-options)
78
+ *
79
+ * Options to start the default screen reader with, see also [screenReader.start([options])](https://www.guidepup.dev/docs/api/class-screenreader#screenreader-start).
74
80
  */
75
81
  screenReaderStartOptions: CaptureStartOptions;
76
82
  }, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
@@ -4,50 +4,10 @@ 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");
8
- const MAX_APPLICATION_SWITCH_RETRY_COUNT = 10;
9
- const SWITCH_APPLICATION = {
10
- keyCode: [guidepup_1.WindowsKeyCodes.Escape],
11
- modifiers: [guidepup_1.WindowsModifiers.Alt],
12
- };
13
- const MOVE_TO_TOP = {
14
- keyCode: [guidepup_1.WindowsKeyCodes.Home],
15
- modifiers: [guidepup_1.WindowsModifiers.Control],
16
- };
17
- const cleanString = (str) => str
18
- .toLowerCase()
19
- // REF: https://github.com/nvaccess/nvda/blob/master/source/locale/en/symbols.dic
20
- .replace(/[|¦:;'"`\-‐–—·_()[\]{}\\^~]/g, " ")
21
- .replace(/\s+/g, " ")
22
- .trim();
23
- const hasFocus = ({ applicationName, pageTitle, windowTitle, }) => {
24
- const cleanedApplicationName = cleanString(applicationName);
25
- const cleanedPageTitle = cleanString(pageTitle);
26
- const cleanedWindowTitle = cleanString(windowTitle);
27
- return ((cleanedPageTitle.length &&
28
- cleanedWindowTitle.startsWith(cleanedPageTitle)) ||
29
- cleanedWindowTitle.includes(cleanedApplicationName));
30
- };
31
- const focusBrowser = async ({ applicationName, pageTitle, }) => {
32
- await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.reportTitle);
33
- let windowTitle = await screenReaderPlaywright.lastSpokenPhrase();
34
- if (hasFocus({ applicationName, pageTitle, windowTitle })) {
35
- return;
36
- }
37
- let applicationSwitchRetryCount = 0;
38
- while (applicationSwitchRetryCount < MAX_APPLICATION_SWITCH_RETRY_COUNT) {
39
- applicationSwitchRetryCount++;
40
- await screenReaderPlaywright.perform(SWITCH_APPLICATION, {
41
- capture: false,
42
- });
43
- await (0, delay_1.delay)(500);
44
- await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.reportTitle);
45
- windowTitle = await screenReaderPlaywright.lastSpokenPhrase();
46
- if (hasFocus({ applicationName, pageTitle, windowTitle })) {
47
- break;
48
- }
49
- }
50
- };
7
+ const navigateNVDAtoWebContent_1 = require("./navigateNVDAtoWebContent");
8
+ const navigateOrcaToWebContent_1 = require("./navigateOrcaToWebContent");
9
+ const navigateVoiceOverToWebContent_1 = require("./navigateVoiceOverToWebContent");
10
+ const applicationIdMap_1 = require("./applicationIdMap");
51
11
  const screenReaderPlaywright = guidepup_1.screenReader;
52
12
  /**
53
13
  * These tests extend the default Playwright environment that launches the
@@ -62,131 +22,32 @@ exports.screenReaderTest = test_1.test.extend({
62
22
  screenReader: async ({ browserName, page, screenReaderStartOptions }, use) => {
63
23
  try {
64
24
  const applicationName = applicationNameMap_1.applicationNameMap[browserName];
65
- if (!applicationName) {
66
- throw new Error(`Browser ${browserName} is not installed.`);
25
+ const applicationId = applicationIdMap_1.applicationIdMap[browserName];
26
+ if (!applicationName || !applicationId) {
27
+ throw new Error(`Browser ${browserName} is not recognised.`);
67
28
  }
68
29
  if (guidepup_1.nvda.default()) {
69
- screenReaderPlaywright.navigateToWebContent = async ({ capture, } = {}) => {
70
- const currentSpokenPhraseLog = [
71
- ...(await screenReaderPlaywright.spokenPhraseLog()),
72
- ];
73
- const currentItemTextLog = [
74
- ...(await screenReaderPlaywright.itemTextLog()),
75
- ];
76
- // Make sure NVDA is not in focus mode.
77
- await screenReaderPlaywright.perform(guidepup_1.NVDAKeyCodeCommands.exitFocusMode, { capture: false });
78
- await (0, delay_1.delay)(100);
79
- // Ensure application is brought to front and focused.
80
- const pageTitle = await page.title();
81
- await focusBrowser({ applicationName, pageTitle });
82
- // Ensure the document is ready and focused.
83
- await page.bringToFront();
84
- await page.locator("body").waitFor();
85
- await page.locator("body").focus();
86
- await page.locator("body").click();
87
- await page.locator("body").blur();
88
- // NVDA appears to not work well with Firefox when switching between
89
- // applications resulting in the entire browser window having NVDA focus
90
- // with focus mode.
91
- //
92
- // One workaround is to tab to the next focusable item. From there we can
93
- // toggle into (yes although we are already in it...) focus mode and back
94
- // out. In case this ever transpires to not happen as expect, we then ensure
95
- // we exit focus mode and move NVDA to the top of the page.
96
- //
97
- // REF: https://github.com/nvaccess/nvda/issues/5758
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 });
115
- };
30
+ screenReaderPlaywright.navigateToWebContent = ({ capture } = {}) => (0, navigateNVDAtoWebContent_1.navigateNVDAtoWebContent)({
31
+ nvda: guidepup_1.nvda,
32
+ page,
33
+ applicationName,
34
+ capture,
35
+ });
116
36
  }
117
37
  else if (guidepup_1.voiceOver.default()) {
118
- screenReaderPlaywright.navigateToWebContent = async ({ capture, } = {}) => {
119
- // Ensure application is brought to front and focused.
120
- await (0, guidepup_1.macOSActivate)(applicationName);
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.
125
- await page.bringToFront();
126
- await page.locator("body").waitFor();
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 });
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
- });
188
- }
189
- };
38
+ screenReaderPlaywright.navigateToWebContent = ({ capture } = {}) => (0, navigateVoiceOverToWebContent_1.navigateVoiceOverToWebContent)({
39
+ voiceOver: guidepup_1.voiceOver,
40
+ page,
41
+ applicationId,
42
+ capture,
43
+ });
44
+ }
45
+ else if (guidepup_1.unstable_orca.default()) {
46
+ screenReaderPlaywright.navigateToWebContent = ({ capture } = {}) => (0, navigateOrcaToWebContent_1.navigateOrcaToWebContent)({
47
+ orca: guidepup_1.unstable_orca,
48
+ page,
49
+ capture,
50
+ });
190
51
  }
191
52
  else {
192
53
  throw new Error("No supported screen reader");
@@ -1,4 +1,4 @@
1
- import type { StartOptions, CommandOptions, VoiceOver } from "@guidepup/guidepup";
1
+ import { type CommandOptions, type StartOptions, type VoiceOver } from "@guidepup/guidepup";
2
2
  /**
3
3
  * [API Reference](https://www.guidepup.dev/docs/api/class-voiceover)
4
4
  *
@@ -34,7 +34,7 @@ export interface VoiceOverPlaywright extends VoiceOver {
34
34
  }
35
35
  /**
36
36
  * These tests extend the default Playwright environment that launches the
37
- * browser with a running instance of the VoiceOver screen reader for MacOS.
37
+ * browser with a running instance of the VoiceOver screen reader for macOS.
38
38
  *
39
39
  * A fresh started VoiceOver instance `voiceOver` is provided to each test.
40
40
  */