diff --git a/e2e-tests/package.json b/e2e-tests/package.json index 014edfdea..7576988b3 100644 --- a/e2e-tests/package.json +++ b/e2e-tests/package.json @@ -7,7 +7,7 @@ "build": "docker build -t playwright .", "build:nocache": "docker build --no-cache -t playwright .", "update-screenshots": "npm run build && docker run -e PLAYWRIGHT_ARGS='--update-snapshots' --rm -v ./test-results:/app/test-results -v ./tests/visuals:/app/tests/visuals playwright", - "test:local": "docker run --rm --cpus=4 --memory=8gb -v ./test-results:/app/test-results -v ./tests:/app/tests playwright", + "test:local": "docker run --rm --cpus=4 --memory=8gb -e PLAYWRIGHT_ARGS -v ./test-results:/app/test-results -v ./tests:/app/tests playwright", "test": "npx playwright test", "test:ui": "PWDEBUG=1 npx playwright test --ui -g", "build:superdoc": "cd ../ && npm run pack && cp ./packages/superdoc/superdoc.tgz ./e2e-tests/superdoc.tgz && cd e2e-tests/templates/vue && npm install file:../../superdoc.tgz", diff --git a/e2e-tests/test-data/performance-documents/100pg document.docx b/e2e-tests/test-data/performance-documents/100pg document.docx new file mode 100644 index 000000000..26453eb63 Binary files /dev/null and b/e2e-tests/test-data/performance-documents/100pg document.docx differ diff --git a/e2e-tests/test-data/performance-documents/3MB 100pg document.docx b/e2e-tests/test-data/performance-documents/3MB 100pg document.docx new file mode 100644 index 000000000..b9c3f52d3 Binary files /dev/null and b/e2e-tests/test-data/performance-documents/3MB 100pg document.docx differ diff --git a/e2e-tests/test-data/performance-documents/3MB document.docx b/e2e-tests/test-data/performance-documents/3MB document.docx new file mode 100644 index 000000000..4d675952f Binary files /dev/null and b/e2e-tests/test-data/performance-documents/3MB document.docx differ diff --git a/e2e-tests/test-data/performance-documents/Anywhere Airport Bid.docx b/e2e-tests/test-data/performance-documents/Anywhere Airport Bid.docx new file mode 100644 index 000000000..3c7fe2bf5 Binary files /dev/null and b/e2e-tests/test-data/performance-documents/Anywhere Airport Bid.docx differ diff --git a/e2e-tests/test-data/performance-documents/Lease Test Doc.docx b/e2e-tests/test-data/performance-documents/Lease Test Doc.docx new file mode 100644 index 000000000..9100cf697 Binary files /dev/null and b/e2e-tests/test-data/performance-documents/Lease Test Doc.docx differ diff --git a/e2e-tests/tests/performance/performance.spec.js b/e2e-tests/tests/performance/performance.spec.js index 22464c1df..b71d06c8a 100644 --- a/e2e-tests/tests/performance/performance.spec.js +++ b/e2e-tests/tests/performance/performance.spec.js @@ -1,7 +1,10 @@ import { test, expect } from '@playwright/test'; import { sleep } from '../helpers'; -test.describe.skip('performance', () => { +test.describe('performance', () => { + // Maximum acceptable load time is 10 s + // Expected load time for document under 3MB or 100 pgs is less than 1s + // TODO: Reduce the timeouts once performance improves test.describe('load time', () => { test('should load a basic document in less than 3s', async ({ page }) => { test.setTimeout(30_000); @@ -143,6 +146,172 @@ test.describe.skip('performance', () => { expect(duration).toBeLessThan(7_000); }); + test('should load 3MB document.docx in less than 4s', async ({ page }) => { + test.setTimeout(30_000); + + const documentPath = `./test-data/performance-documents/3MB document.docx`; + await page.goto('http://localhost:4173/'); + await page.waitForSelector('div.super-editor'); + const superEditor = page.locator('div.super-editor').first(); + + await expect(superEditor).toBeVisible({ timeout: 1_000 }); + // Wait for any initial superdocReady fired on page load so we measure document load time. + await sleep(1_000); + + const start = Date.now(); + const superdocReadyPromise = new Promise((resolve) => { + page.exposeFunction('superdocReady', () => resolve(Date.now() - start)); + }); + + await page.locator('input[type="file"]').setInputFiles(documentPath); + const duration = await superdocReadyPromise; + + expect(duration).toBeLessThan(4_000); + }); + // TODO add test for 100pg document.docx + test('should load a 100pg document in less than 4s', async ({ page }) => { + test.setTimeout(30_000); + + const baseDocumentPath = `./test-data/performance-documents/100pg document.docx`; + await page.goto('http://localhost:4173/'); + await page.waitForSelector('div.super-editor'); + const superEditor = page.locator('div.super-editor').first(); + + await expect(superEditor).toBeVisible({ + timeout: 1_000, + }); + + // This has to be here because `superdocReady` will be called once when the page is initially loaded + // But we want to measure the time it takes to load the document + await sleep(1_000); + + let start, end, duration; + start = Date.now(); + + // Create a Promise that resolves when superdocReady is called + const superdocReadyPromise = new Promise((resolve) => { + page.exposeFunction('superdocReady', () => { + end = Date.now(); + duration = end - start; + resolve(); + }); + }); + + await page.locator('input[type="file"]').setInputFiles(baseDocumentPath); + + // Wait for the superdocReady callback to be called + await superdocReadyPromise; + + expect(duration).toBeLessThan(4_000); + }); + // TODO add test for 3MB 100pg document.docx + test('should load a 3MB 100pg document in less than 4s', async ({ page }) => { + test.setTimeout(30_000); + + const baseDocumentPath = `./test-data/performance-documents/3MB 100pg document.docx`; + await page.goto('http://localhost:4173/'); + await page.waitForSelector('div.super-editor'); + const superEditor = page.locator('div.super-editor').first(); + + await expect(superEditor).toBeVisible({ + timeout: 1_000, + }); + + // This has to be here because `superdocReady` will be called once when the page is initially loaded + // But we want to measure the time it takes to load the document + await sleep(1_000); + + let start, end, duration; + start = Date.now(); + + // Create a Promise that resolves when superdocReady is called + const superdocReadyPromise = new Promise((resolve) => { + page.exposeFunction('superdocReady', () => { + end = Date.now(); + duration = end - start; + resolve(); + }); + }); + + await page.locator('input[type="file"]').setInputFiles(baseDocumentPath); + + // Wait for the superdocReady callback to be called + await superdocReadyPromise; + + expect(duration).toBeLessThan(4_000); + }); + // TODO add test for Lease Test Doc.docx + test('should load a Lease Test Doc.docx document in less than 4s', async ({ page }) => { + test.setTimeout(30_000); + + const baseDocumentPath = `./test-data/performance-documents/Lease Test Doc.docx`; + await page.goto('http://localhost:4173/'); + await page.waitForSelector('div.super-editor'); + const superEditor = page.locator('div.super-editor').first(); + + await expect(superEditor).toBeVisible({ + timeout: 1_000, + }); + + // This has to be here because `superdocReady` will be called once when the page is initially loaded + // But we want to measure the time it takes to load the document + await sleep(1_000); + + let start, end, duration; + start = Date.now(); + + // Create a Promise that resolves when superdocReady is called + const superdocReadyPromise = new Promise((resolve) => { + page.exposeFunction('superdocReady', () => { + end = Date.now(); + duration = end - start; + resolve(); + }); + }); + + await page.locator('input[type="file"]').setInputFiles(baseDocumentPath); + + // Wait for the superdocReady callback to be called + await superdocReadyPromise; + + expect(duration).toBeLessThan(4_000); + }); + test.skip('should load an Airport Bid document in less than 10s', async ({ page }) => { + // This load time is around 45s currently, so this test will be skipped until the new layout engine is implemented. + test.setTimeout(60_000); + + const baseDocumentPath = `./test-data/performance-documents/Anywhere Airport Bid.docx`; + await page.goto('http://localhost:4173/'); + await page.waitForSelector('div.super-editor'); + const superEditor = page.locator('div.super-editor').first(); + + await expect(superEditor).toBeVisible({ + timeout: 1_000, + }); + + // This has to be here because `superdocReady` will be called once when the page is initially loaded + // But we want to measure the time it takes to load the document + await sleep(1_000); + + let start, end, duration; + start = Date.now(); + + // Create a Promise that resolves when superdocReady is called + const superdocReadyPromise = new Promise((resolve) => { + page.exposeFunction('superdocReady', () => { + end = Date.now(); + duration = end - start; + resolve(); + }); + }); + + await page.locator('input[type="file"]').setInputFiles(baseDocumentPath); + + // Wait for the superdocReady callback to be called + await superdocReadyPromise; + + expect(duration).toBeLessThan(10_000); + }); }); test.describe('interactions', () => {