-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathrich-text-input.visualspec.js
More file actions
377 lines (277 loc) Β· 11.3 KB
/
Copy pathrich-text-input.visualspec.js
File metadata and controls
377 lines (277 loc) Β· 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
// import percySnapshot from '@percy/puppeteer';
import puppeteer from 'puppeteer';
import { getDocument, queries } from 'pptr-testing-library';
let browser;
let page;
jest.setTimeout(20000);
beforeEach(async () => {
browser = await puppeteer.launch({
headless: 'new',
// This spec launches its own browser (not the jest-puppeteer global one), so
// it must opt out of the Chrome sandbox itself. CI runners (Ubuntu 24.04+)
// restrict unprivileged user namespaces via AppArmor, so the sandbox can't
// start otherwise. Matches jest-puppeteer.config.js used by other specs.
args: ['--no-sandbox', '--disable-setuid-sandbox'],
slowMo: 10, // Launching the browser in slow motion is necessary due to race conditions. Otherwise browser closes prematurely and tests fail.
});
page = await browser.newPage();
});
afterEach(async () => {
await browser.close();
});
describe('RichTextInput', () => {
const blur = async (element) => {
// eslint-disable-next-line no-shadow
await page.evaluate((element) => {
element.blur();
}, element);
};
const selectAllText = async (input) => {
// eslint-disable-next-line no-shadow
await page.evaluate((input) => {
const range = document.createRange();
range.selectNodeContents(input);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}, input);
};
const waitForNumberOfTags = (tagName, count) => {
return page.waitForFunction(
(_tagName, _count) => {
return document.querySelectorAll(_tagName).length === _count;
},
{ timeout: 10000 },
tagName,
count
);
};
it('Default', async () => {
await page.goto(`${globalThis.HOST}/rich-text-input`);
await page.waitForSelector('text/minimal');
// TODO: uncomment when issue with Percy is resolved
// await percySnapshot(page, 'RichTextInput');
});
describe('Interactive', () => {
it('apply bold, italic, underline, strikethrough, superscript, subscript', async () => {
await page.goto(`${globalThis.HOST}/rich-text-input/interactive`);
const doc = await getDocument(page);
const input = await queries.findByTestId(doc, 'rich-text');
await selectAllText(input);
await input.press('Backspace');
// make the text bold
const boldButton = await queries.findByLabelText(doc, 'Bold');
await boldButton.click();
await input.type('Hello world');
await queries.findByText(doc, 'Hello world');
// check that there is now a strong tag in the document.
await waitForNumberOfTags('strong', 1);
// select the text
await selectAllText(input);
// click the bold button again
await boldButton.click();
// check there are no strong tags in the document.
await waitForNumberOfTags('strong', 0);
await input.press('Backspace');
await input.type('Italic text!');
await queries.findByText(doc, 'Italic text!');
await selectAllText(input);
// make the selection italic
const italicButton = await queries.findByLabelText(doc, 'Italic');
await italicButton.click();
// check there are italic tags in the document.
await waitForNumberOfTags('em', 1);
// click italic button to remove it
await italicButton.click();
// check that the italic tags have been removed.
await waitForNumberOfTags('em', 0);
await selectAllText(input);
await input.press('Backspace');
await input.type('Underlined text!');
await queries.findByText(doc, 'Underlined text!');
await selectAllText(input);
// make the selection underlined
const underlineButton = await queries.findByLabelText(doc, 'Underline');
await underlineButton.click();
// check there are italic tags in the document.
await waitForNumberOfTags('u', 1);
await queries.findByText(doc, 'Underlined text!');
// click italic button to remove it
await underlineButton.click();
// check that the italic tags have been removed.
await waitForNumberOfTags('u', 0);
// multi select marks
// Strike through
await selectAllText(input);
await input.press('Backspace');
await input.type('Strike through?!');
await queries.findByText(doc, 'Strike through?!');
await selectAllText(input);
const moreStylesButton = await queries.findByLabelText(
doc,
'More styles'
);
await moreStylesButton.click();
await queries.findByText(doc, 'Strikethrough');
// TODO: uncomment when issue with Percy is resolved
// await percySnapshot(page, 'RichTextInput - more styles menu open');
let strikethroughButton = await queries.findByText(doc, 'Strikethrough');
await strikethroughButton.click();
// check there are del tags in the document.
await waitForNumberOfTags('del', 1);
// remove the mark
await moreStylesButton.click();
await queries.findByText(doc, 'Strikethrough');
strikethroughButton = await queries.findByText(doc, 'Strikethrough');
await strikethroughButton.click();
// check there are del tags in the document.
await waitForNumberOfTags('del', 0);
await selectAllText(input);
await input.press('Backspace');
await input.type('Superscript!');
await queries.findByText(doc, 'Superscript!');
await selectAllText(input);
await moreStylesButton.click();
await queries.findByText(doc, 'Superscript');
let superscriptButton = await queries.findByText(doc, 'Superscript');
await superscriptButton.click();
// check there are sup tags in the document.
await waitForNumberOfTags('sup', 1);
// remove the mark
await moreStylesButton.click();
await queries.findByText(doc, 'Superscript');
superscriptButton = await queries.findByText(doc, 'Superscript');
await superscriptButton.click();
// check there are no del tags in the document.
await waitForNumberOfTags('sup', 0);
// apply subscript to the selection
await moreStylesButton.click();
let subscriptButton = await queries.findByText(doc, 'Subscript');
await subscriptButton.click();
// check there are sub tags in the document.
await waitForNumberOfTags('sub', 1);
// remove subscript now
await moreStylesButton.click();
subscriptButton = await queries.findByText(doc, 'Subscript');
await subscriptButton.click();
// check there are no sub tags in the document.
await waitForNumberOfTags('sub', 0);
});
it('undo and redo', async () => {
await page.goto(`${globalThis.HOST}/rich-text-input/interactive`);
const doc = await getDocument(page);
const input = await queries.findByTestId(doc, 'rich-text');
await selectAllText(input);
await input.press('Backspace');
// make the text bold
const boldButton = await queries.findByLabelText(doc, 'Bold');
await input.type('Let us now test undo!');
await queries.findByText(doc, 'Let us now test undo!');
// apply bold to selection.
await selectAllText(input);
await boldButton.click();
// bold should be applied
await waitForNumberOfTags('strong', 1);
const undoButton = await queries.findByLabelText(doc, 'Undo');
await undoButton.click();
// bold should be removed
await waitForNumberOfTags('strong', 0);
// now we can try redoing it
const redoButton = await queries.findByLabelText(doc, 'Redo');
await redoButton.click();
// bold should be added again
await waitForNumberOfTags('strong', 1);
/* with text */
// start by removing all the text
await selectAllText(input);
await input.press('Backspace');
// then click undo, text should be back
await undoButton.click();
await queries.findByText(doc, 'Let us now test undo!');
});
it('apply text styles', async () => {
await page.goto(`${globalThis.HOST}/rich-text-input/interactive`);
const doc = await getDocument(page);
const input = await queries.findByTestId(doc, 'rich-text');
await selectAllText(input);
await input.press('Backspace');
// next, open the Style menu
// blur input first to test that editor focus works correctly
await blur(input);
const styleMenuButton = await queries.findByLabelText(doc, 'Style');
await styleMenuButton.click();
await queries.findByText(doc, 'Headline H1');
// TODO: uncomment when issue with Percy is resolved
// await percySnapshot(page, 'RichTextInput - style menu open');
// then click on the H1 button
const h1Button = await queries.findByText(doc, 'Headline H1');
await h1Button.click();
// now type into the input
const h1Text = 'here is our first h1';
await input.type(h1Text);
// text we typed should be visible on the screen
await queries.findByText(doc, h1Text);
// h1 should be in document
await waitForNumberOfTags('h1', 1);
// now, let's change back to h3
await selectAllText(input);
// open style menu again
await styleMenuButton.click();
// then click on the H1 button
const h3Button = await queries.findByText(doc, 'Headline H3');
await h3Button.click();
// h1 should not be in document
await waitForNumberOfTags('h1', 0);
// h3 should be in document
await waitForNumberOfTags('h3', 1);
// now change back to paragraph (the default)
// blur input first to test that editor focus works correctly
await blur(input);
// open style menu again
await styleMenuButton.click();
// then click on the paragraph button
const paragraphbutton = await queries.findByText(doc, 'Paragraph');
await paragraphbutton.click();
// h3 should not be in document
await waitForNumberOfTags('h3', 0);
});
it('apply lists', async () => {
await page.goto(`${globalThis.HOST}/rich-text-input/interactive`);
const doc = await getDocument(page);
const input = await queries.findByTestId(doc, 'rich-text');
const resetButton = await queries.findByLabelText(
doc,
'Reset value to Hello World'
);
await resetButton.click();
await selectAllText(input);
await input.press('Backspace');
// get and click unordered list button
const unorderedListButton = await queries.findByLabelText(
doc,
'Bullet list'
);
await unorderedListButton.click();
await input.type('Item 1');
await input.press('Enter');
await input.type('Item 2');
// ul should be in the document
await waitForNumberOfTags('ul', 1);
// two li tags should be in the document
await waitForNumberOfTags('li', 2);
// now switch to an ordered list
await selectAllText(input);
const orderedListButton = await queries.findByLabelText(
doc,
'Numbered list'
);
await orderedListButton.click();
// ul should not be in the document
await waitForNumberOfTags('ul', 0);
// ol should be in the document
await waitForNumberOfTags('ol', 1);
// two li tags should still be in the document
await waitForNumberOfTags('li', 2);
});
});
});