Skip to content

Commit 4cf487b

Browse files
committed
✅(e2e) ensure i18n.language is injected into generated PDF
Adds an end-to-end test to verify language injection in the generated PDF. Signed-off-by: Cyril <c.gromoff@gmail.com>
1 parent f1c9282 commit 4cf487b

File tree

4 files changed

+122
-48
lines changed

4 files changed

+122
-48
lines changed

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

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import { expect, test } from '@playwright/test';
44
import cs from 'convert-stream';
55
import pdf from 'pdf-parse';
66

7-
import { createDoc, verifyDocName } from './utils-common';
7+
import {
8+
TestLanguage,
9+
createDoc,
10+
randomName,
11+
verifyDocName,
12+
waitForLanguageSwitch,
13+
} from './utils-common';
814

915
test.beforeEach(async ({ page }) => {
1016
await page.goto('/');
@@ -411,4 +417,71 @@ test.describe('Doc Export', () => {
411417
expect(pdfData.text).toContain('Column 2');
412418
expect(pdfData.text).toContain('Column 3');
413419
});
420+
421+
test('it injects the correct language attribute into PDF export', async ({
422+
page,
423+
browserName,
424+
}) => {
425+
await waitForLanguageSwitch(page, TestLanguage.French);
426+
427+
// Wait for the page to be ready after language switch
428+
await page.waitForLoadState('domcontentloaded');
429+
430+
const header = page.locator('header').first();
431+
await header.locator('h2').getByText('Docs').click();
432+
433+
const randomDocFrench = randomName(
434+
'doc-language-export-french',
435+
browserName,
436+
1,
437+
)[0];
438+
439+
await page
440+
.getByRole('button', {
441+
name: 'Nouveau doc',
442+
})
443+
.click();
444+
445+
await page.waitForURL('**/docs/**', {
446+
timeout: 10000,
447+
waitUntil: 'domcontentloaded',
448+
});
449+
450+
const input = page.getByLabel('doc title input');
451+
await expect(input).toBeVisible();
452+
await expect(input).toHaveText('');
453+
await input.click();
454+
await input.fill(randomDocFrench);
455+
await input.blur();
456+
457+
const editor = page.locator('.ProseMirror.bn-editor');
458+
await editor.click();
459+
await editor.fill('Contenu de test pour export en français');
460+
461+
await page
462+
.getByRole('button', {
463+
name: 'download',
464+
exact: true,
465+
})
466+
.click();
467+
468+
const downloadPromise = page.waitForEvent('download', (download) => {
469+
return download.suggestedFilename().includes(`${randomDocFrench}.pdf`);
470+
});
471+
472+
void page
473+
.getByRole('button', {
474+
name: 'Télécharger',
475+
exact: true,
476+
})
477+
.click();
478+
479+
const download = await downloadPromise;
480+
expect(download.suggestedFilename()).toBe(`${randomDocFrench}.pdf`);
481+
482+
const pdfBuffer = await cs.toBuffer(await download.createReadStream());
483+
const pdfString = pdfBuffer.toString('latin1');
484+
485+
expect(pdfString).toContain('/Lang (fr)');
486+
});
414487
});

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

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Page, expect, test } from '@playwright/test';
22

3-
import { createDoc } from './utils-common';
3+
import { TestLanguage, createDoc, waitForLanguageSwitch } from './utils-common';
44

55
test.describe.serial('Language', () => {
66
let page: Page;
@@ -94,48 +94,3 @@ test.describe.serial('Language', () => {
9494
await expect(page.getByText('Titres', { exact: true })).toBeVisible();
9595
});
9696
});
97-
98-
// language helper
99-
export const TestLanguage = {
100-
English: {
101-
label: 'English',
102-
expectedLocale: ['en-us'],
103-
},
104-
French: {
105-
label: 'Français',
106-
expectedLocale: ['fr-fr'],
107-
},
108-
German: {
109-
label: 'Deutsch',
110-
expectedLocale: ['de-de'],
111-
},
112-
} as const;
113-
114-
type TestLanguageKey = keyof typeof TestLanguage;
115-
type TestLanguageValue = (typeof TestLanguage)[TestLanguageKey];
116-
117-
export async function waitForLanguageSwitch(
118-
page: Page,
119-
lang: TestLanguageValue,
120-
) {
121-
const header = page.locator('header').first();
122-
const languagePicker = header.locator('.--docs--language-picker-text');
123-
const isAlreadyTargetLanguage = await languagePicker
124-
.innerText()
125-
.then((text) => text.toLowerCase().includes(lang.label.toLowerCase()));
126-
127-
if (isAlreadyTargetLanguage) {
128-
return;
129-
}
130-
131-
await languagePicker.click();
132-
const responsePromise = page.waitForResponse(
133-
(resp) =>
134-
resp.url().includes('/user') && resp.request().method() === 'PATCH',
135-
);
136-
await page.getByLabel(lang.label).click();
137-
const resolvedResponsePromise = await responsePromise;
138-
const responseData = await resolvedResponsePromise.json();
139-
140-
expect(lang.expectedLocale).toContain(responseData.language);
141-
}

src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,49 @@ export const expectLoginPage = async (page: Page) =>
279279
).toBeVisible({
280280
timeout: 10000,
281281
});
282+
// language helper
283+
export const TestLanguage = {
284+
English: {
285+
label: 'English',
286+
expectedLocale: ['en-us'],
287+
},
288+
French: {
289+
label: 'Français',
290+
expectedLocale: ['fr-fr'],
291+
},
292+
German: {
293+
label: 'Deutsch',
294+
expectedLocale: ['de-de'],
295+
},
296+
} as const;
297+
298+
type TestLanguageKey = keyof typeof TestLanguage;
299+
type TestLanguageValue = (typeof TestLanguage)[TestLanguageKey];
300+
301+
export async function waitForLanguageSwitch(
302+
page: Page,
303+
lang: TestLanguageValue,
304+
) {
305+
const header = page.locator('header').first();
306+
const languagePicker = header.locator('.--docs--language-picker-text');
307+
const isAlreadyTargetLanguage = await languagePicker
308+
.innerText()
309+
.then((text) => text.toLowerCase().includes(lang.label.toLowerCase()));
310+
311+
if (isAlreadyTargetLanguage) {
312+
return;
313+
}
314+
315+
await languagePicker.click();
316+
const responsePromise = page.waitForResponse(
317+
(resp) =>
318+
resp.url().includes('/user') && resp.request().method() === 'PATCH',
319+
);
320+
await page.getByLabel(lang.label).click();
321+
const resolvedResponsePromise = await responsePromise;
322+
const responseData = (await resolvedResponsePromise.json()) as {
323+
language: string;
324+
};
325+
326+
expect(lang.expectedLocale).toContain(responseData.language);
327+
}

src/frontend/apps/impress/src/features/docs/doc-export/components/ModalExport.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
9797
exportDocument,
9898
)) as React.ReactElement<DocumentProps>;
9999

100-
// Inject language="fr-FR" for screen reader support
100+
// Inject language for screen reader support
101101
const pdfDocument = isValidElement(rawPdfDocument)
102102
? cloneElement(rawPdfDocument, { language: i18next.language })
103103
: rawPdfDocument;

0 commit comments

Comments
 (0)