@guidepup/playwright 0.19.0 → 0.19.1
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 +12 -0
- package/lib/screenReaderTest.js +57 -24
- package/lib/voiceOverTest.js +57 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -251,6 +251,18 @@ test.describe("Playwright NVDA", () => {
|
|
|
251
251
|
});
|
|
252
252
|
```
|
|
253
253
|
|
|
254
|
+
### Capture Playwright Interactions
|
|
255
|
+
|
|
256
|
+
Use the `capture()` API to wrap Playwright interactions and capture the resulting screen reader output without needing to perform the interaction through Guidepup.
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
const capture = await screenReader.capture(() =>
|
|
260
|
+
page.getByRole("button", { name: "Add to cart" }).click(),
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
expect(capture.spokenPhrase).toContain("Added to cart");
|
|
264
|
+
```
|
|
265
|
+
|
|
254
266
|
## Powerful tooling
|
|
255
267
|
|
|
256
268
|
Check out some of the other Guidepup modules:
|
package/lib/screenReaderTest.js
CHANGED
|
@@ -48,6 +48,46 @@ const focusBrowser = async ({ applicationName, pageTitle, }) => {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
|
+
const closeMenus = async ({ screenReaderPlaywright, }) => {
|
|
52
|
+
await screenReaderPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Escape }, { capture: false });
|
|
53
|
+
};
|
|
54
|
+
const cancelCurrentInteraction = async ({ screenReaderPlaywright, }) => {
|
|
55
|
+
await screenReaderPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control }, { capture: false });
|
|
56
|
+
};
|
|
57
|
+
const openItemChooser = async ({ screenReaderPlaywright, }) => {
|
|
58
|
+
let lastSpokenPhrase = "";
|
|
59
|
+
while (!lastSpokenPhrase.toLowerCase().includes("item chooser")) {
|
|
60
|
+
await cancelCurrentInteraction({ screenReaderPlaywright });
|
|
61
|
+
await (0, delay_1.delay)(100);
|
|
62
|
+
await closeMenus({ screenReaderPlaywright });
|
|
63
|
+
await (0, delay_1.delay)(100);
|
|
64
|
+
await screenReaderPlaywright.perform(guidepup_1.voiceOverKeyCodeCommands.openItemChooser, { capture: true });
|
|
65
|
+
lastSpokenPhrase = await screenReaderPlaywright.lastSpokenPhrase();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
async function selectWebContentItem({ screenReaderPlaywright, }) {
|
|
69
|
+
// eslint-disable-next-line no-constant-condition
|
|
70
|
+
while (true) {
|
|
71
|
+
let matched = false;
|
|
72
|
+
for (const character of "web content") {
|
|
73
|
+
await cancelCurrentInteraction({ screenReaderPlaywright });
|
|
74
|
+
await (0, delay_1.delay)(100);
|
|
75
|
+
await screenReaderPlaywright.type(character, { capture: "initial" });
|
|
76
|
+
const lastSpokenPhrase = await screenReaderPlaywright.lastSpokenPhrase();
|
|
77
|
+
if (lastSpokenPhrase.toLowerCase().includes("web content")) {
|
|
78
|
+
matched = true;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (matched) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
// Clear the entire Item Chooser search.
|
|
86
|
+
await screenReaderPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Backspace }, { capture: false });
|
|
87
|
+
await (0, delay_1.delay)(100);
|
|
88
|
+
}
|
|
89
|
+
await screenReaderPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Enter }, { capture: false });
|
|
90
|
+
}
|
|
51
91
|
const screenReaderPlaywright = guidepup_1.screenReader;
|
|
52
92
|
/**
|
|
53
93
|
* These tests extend the default Playwright environment that launches the
|
|
@@ -116,10 +156,16 @@ exports.screenReaderTest = test_1.test.extend({
|
|
|
116
156
|
}
|
|
117
157
|
else if (guidepup_1.voiceOver.default()) {
|
|
118
158
|
screenReaderPlaywright.navigateToWebContent = async ({ capture, } = {}) => {
|
|
159
|
+
const currentSpokenPhraseLog = [
|
|
160
|
+
...(await screenReaderPlaywright.spokenPhraseLog()),
|
|
161
|
+
];
|
|
162
|
+
const currentItemTextLog = [
|
|
163
|
+
...(await screenReaderPlaywright.itemTextLog()),
|
|
164
|
+
];
|
|
119
165
|
// Ensure application is brought to front and focused.
|
|
120
166
|
await (0, guidepup_1.macOSActivate)(applicationName);
|
|
121
|
-
// Cancel
|
|
122
|
-
await
|
|
167
|
+
// Cancel automatic behaviours/previous commands.
|
|
168
|
+
await cancelCurrentInteraction({ screenReaderPlaywright });
|
|
123
169
|
await (0, delay_1.delay)(100);
|
|
124
170
|
// Ensure the document is ready and focused.
|
|
125
171
|
await page.bringToFront();
|
|
@@ -147,31 +193,18 @@ exports.screenReaderTest = test_1.test.extend({
|
|
|
147
193
|
`;
|
|
148
194
|
document.body.prepend(marker);
|
|
149
195
|
});
|
|
150
|
-
// Open
|
|
151
|
-
await
|
|
152
|
-
await (
|
|
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);
|
|
196
|
+
// Open item chooser and select web content.
|
|
197
|
+
await openItemChooser({ screenReaderPlaywright });
|
|
198
|
+
await selectWebContentItem({ screenReaderPlaywright });
|
|
162
199
|
// Navigate into web content.
|
|
163
200
|
await screenReaderPlaywright.interact({ capture: false });
|
|
164
201
|
await (0, delay_1.delay)(100);
|
|
165
|
-
|
|
166
|
-
await screenReaderPlaywright.
|
|
167
|
-
await
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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);
|
|
202
|
+
await screenReaderPlaywright.clearSpokenPhraseLog();
|
|
203
|
+
await screenReaderPlaywright.clearItemTextLog();
|
|
204
|
+
const spokenPhraseLog = await screenReaderPlaywright.spokenPhraseLog();
|
|
205
|
+
const itemTextLog = await screenReaderPlaywright.itemTextLog();
|
|
206
|
+
spokenPhraseLog.push(...currentSpokenPhraseLog);
|
|
207
|
+
itemTextLog.push(...currentItemTextLog);
|
|
175
208
|
// Navigate to the first element of the page using the provided
|
|
176
209
|
// capture settings.
|
|
177
210
|
await screenReaderPlaywright.next({ capture });
|
package/lib/voiceOverTest.js
CHANGED
|
@@ -5,6 +5,46 @@ const test_1 = require("@playwright/test");
|
|
|
5
5
|
const guidepup_1 = require("@guidepup/guidepup");
|
|
6
6
|
const applicationNameMap_1 = require("./applicationNameMap");
|
|
7
7
|
const delay_1 = require("./delay");
|
|
8
|
+
const closeMenus = async ({ voiceOverPlaywright, }) => {
|
|
9
|
+
await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Escape }, { capture: false });
|
|
10
|
+
};
|
|
11
|
+
const cancelCurrentInteraction = async ({ voiceOverPlaywright, }) => {
|
|
12
|
+
await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Control }, { capture: false });
|
|
13
|
+
};
|
|
14
|
+
const openItemChooser = async ({ voiceOverPlaywright, }) => {
|
|
15
|
+
let lastSpokenPhrase = "";
|
|
16
|
+
while (!lastSpokenPhrase.toLowerCase().includes("item chooser")) {
|
|
17
|
+
await cancelCurrentInteraction({ voiceOverPlaywright });
|
|
18
|
+
await (0, delay_1.delay)(100);
|
|
19
|
+
await closeMenus({ voiceOverPlaywright });
|
|
20
|
+
await (0, delay_1.delay)(100);
|
|
21
|
+
await voiceOverPlaywright.perform(voiceOverPlaywright.keyboardCommands.openItemChooser, { capture: true });
|
|
22
|
+
lastSpokenPhrase = await voiceOverPlaywright.lastSpokenPhrase();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
async function selectWebContentItem({ voiceOverPlaywright, }) {
|
|
26
|
+
// eslint-disable-next-line no-constant-condition
|
|
27
|
+
while (true) {
|
|
28
|
+
let matched = false;
|
|
29
|
+
for (const character of "web content") {
|
|
30
|
+
await cancelCurrentInteraction({ voiceOverPlaywright });
|
|
31
|
+
await (0, delay_1.delay)(100);
|
|
32
|
+
await voiceOverPlaywright.type(character, { capture: "initial" });
|
|
33
|
+
const lastSpokenPhrase = await voiceOverPlaywright.lastSpokenPhrase();
|
|
34
|
+
if (lastSpokenPhrase.toLowerCase().includes("web content")) {
|
|
35
|
+
matched = true;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (matched) {
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
// Clear the entire Item Chooser search.
|
|
43
|
+
await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Backspace }, { capture: false });
|
|
44
|
+
await (0, delay_1.delay)(100);
|
|
45
|
+
}
|
|
46
|
+
await voiceOverPlaywright.perform({ keyCode: guidepup_1.MacOSKeyCodes.Enter }, { capture: false });
|
|
47
|
+
}
|
|
8
48
|
const voiceOverPlaywright = guidepup_1.voiceOver;
|
|
9
49
|
/**
|
|
10
50
|
* These tests extend the default Playwright environment that launches the
|
|
@@ -21,10 +61,16 @@ exports.voiceOverTest = test_1.test.extend({
|
|
|
21
61
|
throw new Error(`Browser ${browserName} is not installed.`);
|
|
22
62
|
}
|
|
23
63
|
voiceOverPlaywright.navigateToWebContent = async ({ capture } = {}) => {
|
|
64
|
+
const currentSpokenPhraseLog = [
|
|
65
|
+
...(await voiceOverPlaywright.spokenPhraseLog()),
|
|
66
|
+
];
|
|
67
|
+
const currentItemTextLog = [
|
|
68
|
+
...(await voiceOverPlaywright.itemTextLog()),
|
|
69
|
+
];
|
|
24
70
|
// Ensure application is brought to front and focused.
|
|
25
71
|
await (0, guidepup_1.macOSActivate)(applicationName);
|
|
26
|
-
// Cancel
|
|
27
|
-
await
|
|
72
|
+
// Cancel automatic behaviours/previous commands.
|
|
73
|
+
await cancelCurrentInteraction({ voiceOverPlaywright });
|
|
28
74
|
await (0, delay_1.delay)(100);
|
|
29
75
|
// Ensure the document is ready and focused.
|
|
30
76
|
await page.bringToFront();
|
|
@@ -52,31 +98,18 @@ exports.voiceOverTest = test_1.test.extend({
|
|
|
52
98
|
`;
|
|
53
99
|
document.body.prepend(marker);
|
|
54
100
|
});
|
|
55
|
-
// Open
|
|
56
|
-
await
|
|
57
|
-
await (
|
|
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 });
|
|
66
|
-
await (0, delay_1.delay)(100);
|
|
101
|
+
// Open item chooser and select web content.
|
|
102
|
+
await openItemChooser({ voiceOverPlaywright });
|
|
103
|
+
await selectWebContentItem({ voiceOverPlaywright });
|
|
67
104
|
// Navigate into web content.
|
|
68
105
|
await voiceOverPlaywright.interact({ capture: false });
|
|
69
106
|
await (0, delay_1.delay)(100);
|
|
70
|
-
|
|
71
|
-
await voiceOverPlaywright.
|
|
72
|
-
await
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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);
|
|
107
|
+
await voiceOverPlaywright.clearSpokenPhraseLog();
|
|
108
|
+
await voiceOverPlaywright.clearItemTextLog();
|
|
109
|
+
const spokenPhraseLog = await voiceOverPlaywright.spokenPhraseLog();
|
|
110
|
+
const itemTextLog = await voiceOverPlaywright.itemTextLog();
|
|
111
|
+
spokenPhraseLog.push(...currentSpokenPhraseLog);
|
|
112
|
+
itemTextLog.push(...currentItemTextLog);
|
|
80
113
|
// Navigate to the first element of the page using the provided
|
|
81
114
|
// capture settings.
|
|
82
115
|
await voiceOverPlaywright.next({ capture });
|