✅(e2e) add test for accessible html export from export modal
checks generated zip contains html and embedded media files Signed-off-by: Cyril <c.gromoff@gmail.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import path from 'path';
|
||||
|
||||
import { expect, test } from '@playwright/test';
|
||||
import cs from 'convert-stream';
|
||||
import JSZip from 'jszip';
|
||||
import { PDFParse } from 'pdf-parse';
|
||||
|
||||
import {
|
||||
@@ -31,7 +32,7 @@ test.describe('Doc Export', () => {
|
||||
|
||||
await expect(page.getByTestId('modal-export-title')).toBeVisible();
|
||||
await expect(
|
||||
page.getByText('Download your document in a .docx, .odt or .pdf format.'),
|
||||
page.getByText(/Download your document in a \.docx, \.odt.*format\./i),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole('combobox', { name: 'Template' }),
|
||||
@@ -187,6 +188,86 @@ test.describe('Doc Export', () => {
|
||||
expect(download.suggestedFilename()).toBe(`${randomDoc}.odt`);
|
||||
});
|
||||
|
||||
test('it exports the doc to html zip', async ({ page, browserName }) => {
|
||||
const [randomDoc] = await createDoc(
|
||||
page,
|
||||
'doc-editor-html-zip',
|
||||
browserName,
|
||||
1,
|
||||
);
|
||||
|
||||
await verifyDocName(page, randomDoc);
|
||||
|
||||
// Add some content and at least one image so that the ZIP contains media files.
|
||||
await page.locator('.ProseMirror.bn-editor').click();
|
||||
await page.locator('.ProseMirror.bn-editor').fill('Hello HTML ZIP');
|
||||
|
||||
await page.keyboard.press('Enter');
|
||||
await page.locator('.bn-block-outer').last().fill('/');
|
||||
await page.getByText('Resizable image with caption').click();
|
||||
|
||||
const fileChooserPromise = page.waitForEvent('filechooser');
|
||||
await page.getByText('Upload image').click();
|
||||
|
||||
const fileChooser = await fileChooserPromise;
|
||||
await fileChooser.setFiles(path.join(__dirname, 'assets/test.svg'));
|
||||
|
||||
const image = page
|
||||
.locator('.--docs--editor-container img.bn-visual-media')
|
||||
.first();
|
||||
|
||||
// Wait for the image to be attached and have a valid src (aria-hidden prevents toBeVisible on Chromium)
|
||||
await expect(image).toBeAttached({ timeout: 10000 });
|
||||
await expect(image).toHaveAttribute('src', /.*\.svg/);
|
||||
|
||||
// Give some time for the image to be fully processed
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'Export the document',
|
||||
})
|
||||
.click();
|
||||
|
||||
await page.getByRole('combobox', { name: 'Format' }).click();
|
||||
await page.getByRole('option', { name: 'HTML' }).click();
|
||||
|
||||
await expect(page.getByTestId('doc-export-download-button')).toBeVisible();
|
||||
|
||||
const downloadPromise = page.waitForEvent('download', (download) => {
|
||||
return download.suggestedFilename().includes(`${randomDoc}.zip`);
|
||||
});
|
||||
|
||||
void page.getByTestId('doc-export-download-button').click();
|
||||
|
||||
const download = await downloadPromise;
|
||||
expect(download.suggestedFilename()).toBe(`${randomDoc}.zip`);
|
||||
|
||||
const zipBuffer = await cs.toBuffer(await download.createReadStream());
|
||||
// Unzip and inspect contents
|
||||
const zip = await JSZip.loadAsync(zipBuffer);
|
||||
|
||||
// Check that index.html exists
|
||||
const indexHtml = zip.file('index.html');
|
||||
expect(indexHtml).not.toBeNull();
|
||||
|
||||
// Read and verify HTML content
|
||||
const htmlContent = await indexHtml!.async('string');
|
||||
expect(htmlContent).toContain('Hello HTML ZIP');
|
||||
|
||||
// Check for media files (they are at the root of the ZIP, not in a media/ folder)
|
||||
// Media files are named like "1-test.svg" or "media-1.png" by deriveMediaFilename
|
||||
const allFiles = Object.keys(zip.files);
|
||||
const mediaFiles = allFiles.filter(
|
||||
(name) => name !== 'index.html' && !name.endsWith('/'),
|
||||
);
|
||||
expect(mediaFiles.length).toBeGreaterThan(0);
|
||||
|
||||
// Verify the SVG image is included
|
||||
const svgFile = mediaFiles.find((name) => name.endsWith('.svg'));
|
||||
expect(svgFile).toBeDefined();
|
||||
});
|
||||
|
||||
/**
|
||||
* This test tell us that the export to pdf is working with images
|
||||
* but it does not tell us if the images are being displayed correctly
|
||||
|
||||
@@ -408,40 +408,6 @@ test.describe('Doc Header', () => {
|
||||
expect(clipboardContent.trim()).toBe('# Hello World');
|
||||
});
|
||||
|
||||
test('It checks the copy as HTML button', async ({ page, browserName }) => {
|
||||
test.skip(
|
||||
browserName === 'webkit',
|
||||
'navigator.clipboard is not working with webkit and playwright',
|
||||
);
|
||||
|
||||
// create page and navigate to it
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'New doc',
|
||||
})
|
||||
.click();
|
||||
|
||||
// Add dummy content to the doc
|
||||
const editor = page.locator('.ProseMirror');
|
||||
const docFirstBlock = editor.locator('.bn-block-content').first();
|
||||
await docFirstBlock.click();
|
||||
await page.keyboard.type('# Hello World', { delay: 100 });
|
||||
const docFirstBlockContent = docFirstBlock.locator('h1');
|
||||
await expect(docFirstBlockContent).toHaveText('Hello World');
|
||||
|
||||
// Copy content to clipboard
|
||||
await page.getByLabel('Open the document options').click();
|
||||
await page.getByRole('menuitem', { name: 'Copy as HTML' }).click();
|
||||
await expect(page.getByText('Copied to clipboard')).toBeVisible();
|
||||
|
||||
// Test that clipboard is in HTML format
|
||||
const handle = await page.evaluateHandle(() =>
|
||||
navigator.clipboard.readText(),
|
||||
);
|
||||
const clipboardContent = await handle.jsonValue();
|
||||
expect(clipboardContent.trim()).toBe(`<h1>Hello World</h1><p></p>`);
|
||||
});
|
||||
|
||||
test('it checks the copy link button', async ({ page, browserName }) => {
|
||||
test.skip(
|
||||
browserName === 'webkit',
|
||||
|
||||
Reference in New Issue
Block a user