Skip to content

Commit 9cb2b6a

Browse files
committed
✨(frontend) improve accessibility of cdoc content with correct aria tags
added appropriate aria attributes and semantic tags to enhance accessibility Signed-off-by: Cyril <[email protected]>
1 parent 0a1eaa3 commit 9cb2b6a

File tree

13 files changed

+116
-88
lines changed

13 files changed

+116
-88
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ and this project adheres to
3838
- ♿(frontend) improve accessibility for decorative images in editor #1282
3939
- #1338
4040
- #1281
41+
- #1271
4142
- ♻️(backend) fallback to email identifier when no name #1298
4243
- 🐛(backend) allow ASCII characters in user sub field #1295
4344
- ⚡️(frontend) improve fallback width calculation #1333

src/frontend/apps/e2e/__tests__/app-impress/doc-create.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ test.describe('Doc Create', () => {
4545
})
4646
.click();
4747

48-
const input = page.getByRole('textbox', { name: 'doc title input' });
49-
await expect(input).toHaveText('');
48+
const input = page.getByRole('textbox', { name: 'Document title' });
49+
await expect(input).toHaveText('', { timeout: 10000 });
5050
await expect(
5151
page.locator('.c__tree-view--row-content').getByText('Untitled document'),
5252
).toBeVisible();
@@ -67,8 +67,8 @@ test.describe('Doc Create', () => {
6767
.getByText('New sub-doc')
6868
.click();
6969

70-
const input = page.getByRole('textbox', { name: 'doc title input' });
71-
await expect(input).toHaveText('');
70+
const input = page.getByRole('textbox', { name: 'Document title' });
71+
await expect(input).toHaveText('', { timeout: 10000 });
7272
await expect(
7373
page.locator('.c__tree-view--row-content').getByText('Untitled document'),
7474
).toBeVisible();

src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ test.describe('Doc Export', () => {
4040
await expect(
4141
page.getByRole('button', { name: 'Close the modal' }),
4242
).toBeVisible();
43-
await expect(page.getByTestId('modal-download-button')).toBeVisible();
43+
await expect(page.getByTestId('doc-export-download-button')).toBeVisible();
4444
});
4545

4646
test('it exports the doc with pdf line break', async ({
@@ -81,12 +81,7 @@ test.describe('Doc Export', () => {
8181
return download.suggestedFilename().includes(`${randomDoc}.pdf`);
8282
});
8383

84-
void page
85-
.getByRole('button', {
86-
name: 'Download',
87-
exact: true,
88-
})
89-
.click();
84+
void page.getByTestId('doc-export-download-button').click();
9085

9186
const download = await downloadPromise;
9287
expect(download.suggestedFilename()).toBe(`${randomDoc}.pdf`);
@@ -131,13 +126,13 @@ test.describe('Doc Export', () => {
131126
await page.getByRole('combobox', { name: 'Format' }).click();
132127
await page.getByRole('option', { name: 'Docx' }).click();
133128

134-
await expect(page.getByTestId('modal-download-button')).toBeVisible();
129+
await expect(page.getByTestId('doc-export-download-button')).toBeVisible();
135130

136131
const downloadPromise = page.waitForEvent('download', (download) => {
137132
return download.suggestedFilename().includes(`${randomDoc}.docx`);
138133
});
139134

140-
void page.getByTestId('modal-download-button').click();
135+
void page.getByTestId('doc-export-download-button').click();
141136

142137
const download = await downloadPromise;
143138
expect(download.suggestedFilename()).toBe(`${randomDoc}.docx`);
@@ -203,7 +198,7 @@ test.describe('Doc Export', () => {
203198

204199
await new Promise((resolve) => setTimeout(resolve, 1000));
205200

206-
await expect(page.getByTestId('modal-download-button')).toBeVisible();
201+
await expect(page.getByTestId('doc-export-download-button')).toBeVisible();
207202

208203
const responseCorsPromise = page.waitForResponse(
209204
(response) =>
@@ -214,7 +209,7 @@ test.describe('Doc Export', () => {
214209
return download.suggestedFilename().includes(`${randomDoc}.pdf`);
215210
});
216211

217-
void page.getByTestId('modal-download-button').click();
212+
void page.getByTestId('doc-export-download-button').click();
218213

219214
const responseCors = await responseCorsPromise;
220215
expect(responseCors.ok()).toBe(true);
@@ -256,13 +251,13 @@ test.describe('Doc Export', () => {
256251
})
257252
.click();
258253

259-
await expect(page.getByTestId('modal-download-button')).toBeVisible();
254+
await expect(page.getByTestId('doc-export-download-button')).toBeVisible();
260255

261256
const downloadPromise = page.waitForEvent('download', (download) => {
262257
return download.suggestedFilename().includes(`${randomDoc}.pdf`);
263258
});
264259

265-
void page.getByTestId('modal-download-button').click();
260+
void page.getByTestId('doc-export-download-button').click();
266261

267262
const download = await downloadPromise;
268263
expect(download.suggestedFilename()).toBe(`${randomDoc}.pdf`);
@@ -298,13 +293,15 @@ test.describe('Doc Export', () => {
298293
})
299294
.click();
300295

301-
await expect(page.getByTestId('modal-download-button')).toBeVisible();
296+
await expect(
297+
page.getByTestId('doc-open-modal-download-button'),
298+
).toBeVisible();
302299

303300
const downloadPromise = page.waitForEvent('download', (download) => {
304301
return download.suggestedFilename().includes(`${randomDoc}.pdf`);
305302
});
306303

307-
void page.getByTestId('modal-download-button').click();
304+
void page.getByTestId('doc-export-download-button').click();
308305

309306
const download = await downloadPromise;
310307
expect(download.suggestedFilename()).toBe(`${randomDoc}.pdf`);
@@ -350,13 +347,15 @@ test.describe('Doc Export', () => {
350347
})
351348
.click();
352349

353-
await expect(page.getByTestId('modal-download-button')).toBeVisible();
350+
await expect(
351+
page.getByTestId('doc-open-modal-download-button'),
352+
).toBeVisible();
354353

355354
const downloadPromise = page.waitForEvent('download', (download) => {
356355
return download.suggestedFilename().includes(`${randomDoc}.pdf`);
357356
});
358357

359-
void page.getByTestId('modal-download-button').click();
358+
void page.getByTestId('doc-export-download-button').click();
360359

361360
const download = await downloadPromise;
362361
expect(download.suggestedFilename()).toBe(`${randomDoc}.pdf`);
@@ -392,14 +391,9 @@ test.describe('Doc Export', () => {
392391
})
393392
.click();
394393

395-
await page.waitForURL('**/docs/**', {
396-
timeout: 10000,
397-
waitUntil: 'domcontentloaded',
398-
});
399-
400-
const input = page.getByLabel('doc title input');
394+
const input = page.locator('.--docs--doc-title-input[role="textbox"]');
401395
await expect(input).toBeVisible();
402-
await expect(input).toHaveText('');
396+
await expect(input).toHaveText('', { timeout: 10000 });
403397
await input.click();
404398
await input.fill(randomDocFrench);
405399
await input.blur();
@@ -418,7 +412,7 @@ test.describe('Doc Export', () => {
418412
return download.suggestedFilename().includes(`${randomDocFrench}.pdf`);
419413
});
420414

421-
void page.getByTestId('modal-download-button').click();
415+
void page.getByTestId('doc-export-download-button').click();
422416

423417
const download = await downloadPromise;
424418
expect(download.suggestedFilename()).toBe(`${randomDocFrench}.pdf`);
@@ -453,19 +447,23 @@ test.describe('Doc Export', () => {
453447
await page.locator('.bn-block-outer').last().fill('/');
454448
await page.getByText('Link a doc').first().click();
455449

456-
await page
457-
.locator(
458-
"span[data-inline-content-type='interlinkingSearchInline'] input",
459-
)
460-
.fill('interlink-child');
450+
const input = page.locator(
451+
"span[data-inline-content-type='interlinkingSearchInline'] input",
452+
);
453+
const searchContainer = page.locator('.quick-search-container');
461454

462-
await page
463-
.locator('.quick-search-container')
464-
.getByText('interlink-child')
465-
.click();
455+
await input.fill('export-interlink');
456+
457+
await expect(searchContainer).toBeVisible();
458+
await expect(searchContainer.getByText(randomDoc)).toBeVisible();
466459

467-
const interlink = page.getByRole('link', {
468-
name: 'interlink-child',
460+
// We are in docChild, we want to create a link to randomDoc (parent)
461+
await searchContainer.getByText(randomDoc).click();
462+
463+
// Search the interlinking link in the editor (not in the document tree)
464+
const editor = page.locator('.ProseMirror.bn-editor');
465+
const interlink = editor.getByRole('link', {
466+
name: randomDoc,
469467
});
470468

471469
await expect(interlink).toBeVisible();
@@ -480,14 +478,14 @@ test.describe('Doc Export', () => {
480478
})
481479
.click();
482480

483-
void page.getByTestId('modal-download-button').click();
481+
void page.getByTestId('doc-export-download-button').click();
484482

485483
const download = await downloadPromise;
486484
expect(download.suggestedFilename()).toBe(`${docChild}.pdf`);
487485

488486
const pdfBuffer = await cs.toBuffer(await download.createReadStream());
489487
const pdfData = await pdf(pdfBuffer);
490488

491-
expect(pdfData.text).toContain('interlink-child'); // This is the pdf text
489+
expect(pdfData.text).toContain(randomDoc);
492490
});
493491
});

src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ test.describe('Doc Header', () => {
2525
'It is the card information about the document.',
2626
);
2727

28-
const docTitle = card.getByRole('textbox', { name: 'doc title input' });
28+
const docTitle = card.getByRole('textbox', { name: 'Document title' });
2929
await expect(docTitle).toBeVisible();
3030

3131
await page.getByRole('button', { name: 'Share' }).click();
@@ -54,7 +54,7 @@ test.describe('Doc Header', () => {
5454

5555
test('it updates the title doc', async ({ page, browserName }) => {
5656
await createDoc(page, 'doc-update', browserName, 1);
57-
const docTitle = page.getByRole('textbox', { name: 'doc title input' });
57+
const docTitle = page.getByRole('textbox', { name: 'Document title' });
5858
await expect(docTitle).toBeVisible();
5959
await docTitle.fill('Hello World');
6060
await docTitle.blur();
@@ -66,7 +66,7 @@ test.describe('Doc Header', () => {
6666
browserName,
6767
}) => {
6868
await createDoc(page, 'doc-update', browserName, 1);
69-
const docTitle = page.getByRole('textbox', { name: 'doc title input' });
69+
const docTitle = page.getByRole('textbox', { name: 'Document title' });
7070
await expect(docTitle).toBeVisible();
7171
await docTitle.fill('👍 Hello Emoji World');
7272
await docTitle.blur();
@@ -228,23 +228,27 @@ test.describe('Doc Header', () => {
228228

229229
await page.getByRole('button', { name: 'Share' }).click();
230230

231-
const shareModal = page.getByLabel('Share modal');
231+
const shareModal = page.getByRole('dialog', {
232+
name: 'Share modal content',
233+
});
234+
await expect(shareModal).toBeVisible();
232235
await expect(page.getByText('Share the document')).toBeVisible();
233236

234237
await expect(page.getByPlaceholder('Type a name or email')).toBeHidden();
235238

236239
const invitationCard = shareModal.getByLabel('List invitation card');
240+
await expect(invitationCard).toBeVisible();
237241
await expect(
238242
invitationCard.getByText('[email protected]').first(),
239243
).toBeVisible();
240-
await expect(invitationCard.getByLabel('doc-role-text')).toBeVisible();
244+
await expect(invitationCard.getByLabel('Document role text')).toBeVisible();
241245
await expect(
242246
invitationCard.getByRole('button', { name: 'more_horiz' }),
243247
).toBeHidden();
244248

245249
const memberCard = shareModal.getByLabel('List members card');
246250
await expect(memberCard.getByText('[email protected]')).toBeVisible();
247-
await expect(memberCard.getByLabel('doc-role-text')).toBeVisible();
251+
await expect(memberCard.getByLabel('Document role text')).toBeVisible();
248252
await expect(
249253
memberCard.getByRole('button', { name: 'more_horiz' }),
250254
).toBeHidden();
@@ -296,17 +300,18 @@ test.describe('Doc Header', () => {
296300
await expect(page.getByPlaceholder('Type a name or email')).toBeHidden();
297301

298302
const invitationCard = shareModal.getByLabel('List invitation card');
303+
await expect(invitationCard).toBeVisible();
299304
await expect(
300305
invitationCard.getByText('[email protected]').first(),
301306
).toBeVisible();
302-
await expect(invitationCard.getByLabel('doc-role-text')).toBeVisible();
307+
await expect(invitationCard.getByLabel('Document role text')).toBeVisible();
303308
await expect(
304309
invitationCard.getByRole('button', { name: 'more_horiz' }),
305310
).toBeHidden();
306311

307312
const memberCard = shareModal.getByLabel('List members card');
308313
await expect(memberCard.getByText('[email protected]')).toBeVisible();
309-
await expect(memberCard.getByLabel('doc-role-text')).toBeVisible();
314+
await expect(memberCard.getByLabel('Document role text')).toBeVisible();
310315
await expect(
311316
memberCard.getByRole('button', { name: 'more_horiz' }),
312317
).toBeHidden();

src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,32 +60,37 @@ test.describe('Doc Routing', () => {
6060

6161
await page.locator('.ProseMirror.bn-editor').fill('Hello World');
6262

63-
const responsePromise = page.route(
64-
/.*\/documents\/.*\/$|users\/me\/$/,
65-
async (route) => {
66-
const request = route.request();
67-
68-
if (
69-
request.method().includes('PATCH') ||
70-
request.method().includes('GET')
71-
) {
72-
await route.fulfill({
73-
status: 401,
74-
json: {
75-
detail: 'Log in to access the document',
76-
},
77-
});
78-
} else {
79-
await route.continue();
80-
}
81-
},
82-
);
63+
// Wait for the doc link (via its dynamic title) to be visible
64+
const docLink = page.getByRole('link', { name: docTitle });
65+
await expect(docLink).toBeVisible();
66+
67+
// Intercept GET/PATCH requests to return 401
68+
await page.route(/.*\/documents\/.*\/$|users\/me\/$/, async (route) => {
69+
const request = route.request();
70+
if (
71+
request.method().includes('PATCH') ||
72+
request.method().includes('GET')
73+
) {
74+
await route.fulfill({
75+
status: 401,
76+
json: { detail: 'Log in to access the document' },
77+
});
78+
} else {
79+
await route.continue();
80+
}
81+
});
8382

84-
await page.getByRole('link', { name: '401-doc-parent' }).click();
83+
// Explicitly wait for a 401 response after clicking
84+
const wait401 = page.waitForResponse(
85+
(resp) =>
86+
resp.status() === 401 &&
87+
/\/(documents\/[^/]+\/|users\/me\/)$/.test(resp.url()),
88+
);
8589

86-
await responsePromise;
90+
await docLink.click();
91+
await wait401;
8792

88-
await expect(page.getByText('Log in to access the document')).toBeVisible({
93+
await expect(page.getByText('Log in to access the document.')).toBeVisible({
8994
timeout: 10000,
9095
});
9196
});

src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ test.describe('Doc Tree', () => {
5050
await expect(subPageItem).toBeVisible();
5151
await subPageItem.click();
5252
await verifyDocName(page, '');
53-
const input = page.getByRole('textbox', { name: 'doc title input' });
53+
const input = page.getByRole('textbox', { name: 'Document title' });
5454
await input.click();
5555
const [randomDocName] = randomName('doc-tree-test', browserName, 1);
5656
await input.fill(randomDocName);
@@ -196,7 +196,7 @@ test.describe('Doc Tree', () => {
196196
await page.getByText('Move to my docs').click();
197197

198198
await expect(
199-
page.getByRole('textbox', { name: 'doc title input' }),
199+
page.getByRole('textbox', { name: 'Document title' }),
200200
).not.toHaveText(docChild);
201201

202202
const header = page.locator('header').first();

0 commit comments

Comments
 (0)