From c722151188488246408b4512fcecc987b603611b Mon Sep 17 00:00:00 2001 From: lumixraku Date: Fri, 7 Feb 2025 18:03:02 +0800 Subject: [PATCH 1/8] test: test mem --- e2e/memory/memory.spec.ts | 52 ++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/e2e/memory/memory.spec.ts b/e2e/memory/memory.spec.ts index 56dd5b8d3c39..84afebe4ffbc 100644 --- a/e2e/memory/memory.spec.ts +++ b/e2e/memory/memory.spec.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { createWriteStream } from 'node:fs'; import { expect, test } from '@playwright/test'; import { getMetrics } from './util'; @@ -29,30 +30,63 @@ const MAX_SECOND_INSTANCE_OVERFLOW = 100_000; // Only 100 KB test('memory', async ({ page }) => { test.setTimeout(60_000); + const client = await page.context().newCDPSession(page); + async function takeHeapSnapshot(filename) { + const file = createWriteStream(filename); + + // Create a promise that resolves when the snapshot is complete + const snapshotComplete = new Promise((resolve) => { + client.on('HeapProfiler.addHeapSnapshotChunk', (params) => { + console.log('Writing chunk to file', params.chunk.length); + file.write(params.chunk); + }); + + client.on('HeapProfiler.reportHeapSnapshotProgress', (params) => { + if (params.finished) { + file.end(); + console.log(`Heap snapshot finished saved to ${filename}`); + resolve(1); + } + }); + }); + + // Take the snapshot + client.send('HeapProfiler.takeHeapSnapshot'); + + // Wait for the snapshot to complete + await snapshotComplete; + } await page.goto('http://localhost:3000/sheets/'); await page.waitForTimeout(5000); const memoryAfterFirstInstance = (await getMetrics(page)).JSHeapUsedSize; - await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(1)); - await page.waitForTimeout(2000); - const memoryAfterFirstLoad = (await getMetrics(page)).JSHeapUsedSize; + // await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(1)); + // await page.waitForTimeout(2000); + // const memoryAfterFirstLoad = (await getMetrics(page)).JSHeapUsedSize; - await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(2)); - await page.waitForTimeout(2000); - const memoryAfterSecondLoad = (await getMetrics(page)).JSHeapUsedSize; - expect(memoryAfterSecondLoad - memoryAfterFirstLoad) - .toBeLessThanOrEqual(MAX_UNIT_MEMORY_OVERFLOW); + // await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(2)); + // await page.waitForTimeout(2000); + // const memoryAfterSecondLoad = (await getMetrics(page)).JSHeapUsedSize; + // expect(memoryAfterSecondLoad - memoryAfterFirstLoad) + // .toBeLessThanOrEqual(MAX_UNIT_MEMORY_OVERFLOW); await page.evaluate(() => window.univer.dispose()); - await page.waitForTimeout(2000); + await page.waitForTimeout(12000); + takeHeapSnapshot('memory-before.heapsnapshot'); + const memoryAfterDisposingFirstInstance = (await getMetrics(page)).JSHeapUsedSize; await page.evaluate(() => window.createNewInstance()); await page.waitForTimeout(2000); await page.evaluate(() => window.univer.dispose()); await page.waitForTimeout(2000); + + takeHeapSnapshot('memory-after.heapsnapshot'); + + await page.waitForTimeout(12000); + const memoryAfterDisposingSecondUniver = (await getMetrics(page)).JSHeapUsedSize; expect(memoryAfterDisposingSecondUniver - memoryAfterDisposingFirstInstance) .toBeLessThanOrEqual(MAX_SECOND_INSTANCE_OVERFLOW); From e1625748acc6be49a445373817b2757ca89fe658 Mon Sep 17 00:00:00 2001 From: lumixraku Date: Fri, 7 Feb 2025 20:37:58 +0800 Subject: [PATCH 2/8] test: record mem snapshot 1st try --- e2e/memory/memory.spec.ts | 121 ++++++++++++++++++++++++++++---------- e2e/perf/scroll.spec.ts | 2 +- 2 files changed, 90 insertions(+), 33 deletions(-) diff --git a/e2e/memory/memory.spec.ts b/e2e/memory/memory.spec.ts index 84afebe4ffbc..c0ec7f405362 100644 --- a/e2e/memory/memory.spec.ts +++ b/e2e/memory/memory.spec.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +/* eslint-disable no-console */ import { createWriteStream } from 'node:fs'; import { expect, test } from '@playwright/test'; import { getMetrics } from './util'; @@ -29,32 +30,87 @@ const MAX_UNIVER_MEMORY_OVERFLOW = 6_000_000; // TODO@wzhudev: temporarily added const MAX_SECOND_INSTANCE_OVERFLOW = 100_000; // Only 100 KB test('memory', async ({ page }) => { - test.setTimeout(60_000); + test.setTimeout(80_000); const client = await page.context().newCDPSession(page); - async function takeHeapSnapshot(filename) { - const file = createWriteStream(filename); - - // Create a promise that resolves when the snapshot is complete - const snapshotComplete = new Promise((resolve) => { - client.on('HeapProfiler.addHeapSnapshotChunk', (params) => { - console.log('Writing chunk to file', params.chunk.length); - file.write(params.chunk); + + async function takeHeapSnapshot(client, filename) { + return new Promise((resolve, reject) => { + const file = createWriteStream(filename); + let isFinished = false; + let error = null; + let noChunkTimeout = null; + + // Handle file stream errors + file.on('error', (err) => { + error = err; + reject(err); }); - client.on('HeapProfiler.reportHeapSnapshotProgress', (params) => { - if (params.finished) { - file.end(); - console.log(`Heap snapshot finished saved to ${filename}`); - resolve(1); + // Handle successful completion + file.on('finish', () => { + if (!error && isFinished) { + console.log('file write finished', filename); + resolve(0); } }); - }); - // Take the snapshot - client.send('HeapProfiler.takeHeapSnapshot'); + const scheduleEnd = () => { + // Clear any existing timeout + if (noChunkTimeout) { + clearTimeout(noChunkTimeout); + } - // Wait for the snapshot to complete - await snapshotComplete; + // Set new timeout + noChunkTimeout = setTimeout(() => { + cleanup(); + file.end(); + }, 1000); // Wait 1 second after last chunk + }; + // Set up the chunk handler + const chunkHandler = (params) => { + try { + if (params.chunk) { + console.log('chunkHandler write chunk', filename, file.writableLength); + file.write(params.chunk); + scheduleEnd(); + } + } catch (err) { + error = err; + console.error('chunkHandler error', err); + cleanup(); + reject(err); + } + }; + + // Set up the progress handler + const progressHandler = (params) => { + console.log('progressHandler params', filename, params); + if (params.finished) { + isFinished = true; + } + }; + + // Cleanup function to remove listeners + const cleanup = () => { + client.off('HeapProfiler.addHeapSnapshotChunk', chunkHandler); + client.off('HeapProfiler.reportHeapSnapshotProgress', progressHandler); + }; + + // Add event listeners + client.on('HeapProfiler.addHeapSnapshotChunk', chunkHandler); + client.on('HeapProfiler.reportHeapSnapshotProgress', progressHandler); + + // Start the heap snapshot process + client.send('HeapProfiler.enable') + .then(() => client.send('HeapProfiler.takeHeapSnapshot', { reportProgress: true })) + .catch((err) => { + console.error('HeapProfiler.enable error', err); + error = err; + cleanup(); + file.end(); + reject(err); + }); + }); } await page.goto('http://localhost:3000/sheets/'); @@ -62,19 +118,21 @@ test('memory', async ({ page }) => { const memoryAfterFirstInstance = (await getMetrics(page)).JSHeapUsedSize; - // await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(1)); - // await page.waitForTimeout(2000); - // const memoryAfterFirstLoad = (await getMetrics(page)).JSHeapUsedSize; + await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(1)); + await page.waitForTimeout(2000); + const memoryAfterFirstLoad = (await getMetrics(page)).JSHeapUsedSize; - // await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(2)); - // await page.waitForTimeout(2000); - // const memoryAfterSecondLoad = (await getMetrics(page)).JSHeapUsedSize; - // expect(memoryAfterSecondLoad - memoryAfterFirstLoad) - // .toBeLessThanOrEqual(MAX_UNIT_MEMORY_OVERFLOW); + await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(2)); + await page.waitForTimeout(2000); + const memoryAfterSecondLoad = (await getMetrics(page)).JSHeapUsedSize; + expect(memoryAfterSecondLoad - memoryAfterFirstLoad) + .toBeLessThanOrEqual(MAX_UNIT_MEMORY_OVERFLOW); await page.evaluate(() => window.univer.dispose()); - await page.waitForTimeout(12000); - takeHeapSnapshot('memory-before.heapsnapshot'); + await page.waitForTimeout(2000); + + const firstSnapshot = await takeHeapSnapshot(client, 'memory-first.heapsnapshot'); + console.log('firstSnapshot', firstSnapshot); const memoryAfterDisposingFirstInstance = (await getMetrics(page)).JSHeapUsedSize; @@ -83,9 +141,8 @@ test('memory', async ({ page }) => { await page.evaluate(() => window.univer.dispose()); await page.waitForTimeout(2000); - takeHeapSnapshot('memory-after.heapsnapshot'); - - await page.waitForTimeout(12000); + const secondSnapshot = await takeHeapSnapshot(client, 'memory-second.heapsnapshot'); + console.log('secondSnapshot', secondSnapshot); const memoryAfterDisposingSecondUniver = (await getMetrics(page)).JSHeapUsedSize; expect(memoryAfterDisposingSecondUniver - memoryAfterDisposingFirstInstance) diff --git a/e2e/perf/scroll.spec.ts b/e2e/perf/scroll.spec.ts index 8f22fb2fdb3f..2f6460d65bf3 100644 --- a/e2e/perf/scroll.spec.ts +++ b/e2e/perf/scroll.spec.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -import type { Page } from '@playwright/test'; /* eslint-disable no-console */ +import type { Page } from '@playwright/test'; import { expect, test } from '@playwright/test'; import { sheetData as emptySheetData } from '../__testing__/emptysheet'; import { sheetData as freezeData } from '../__testing__/freezesheet'; From 8d3fb8aa7ab8a605597970ff26bd80014ef0f5ec Mon Sep 17 00:00:00 2001 From: lumixraku Date: Fri, 7 Feb 2025 20:55:52 +0800 Subject: [PATCH 3/8] test: better code --- .gitignore | 1 + e2e/memory/memory.spec.ts | 178 ++++++++++++++++++++------------------ 2 files changed, 97 insertions(+), 82 deletions(-) diff --git a/.gitignore b/.gitignore index 741532cd6ec9..7e4a19a7628e 100644 --- a/.gitignore +++ b/.gitignore @@ -86,6 +86,7 @@ typings/ # examples screenshot +*.heapsnapshot univer-custom-build universheet-custom-build diff --git a/e2e/memory/memory.spec.ts b/e2e/memory/memory.spec.ts index c0ec7f405362..8d519e1ba29e 100644 --- a/e2e/memory/memory.spec.ts +++ b/e2e/memory/memory.spec.ts @@ -15,6 +15,7 @@ */ /* eslint-disable no-console */ +import type { CDPSession } from '@playwright/test'; import { createWriteStream } from 'node:fs'; import { expect, test } from '@playwright/test'; import { getMetrics } from './util'; @@ -29,92 +30,103 @@ const MAX_UNIVER_MEMORY_OVERFLOW = 6_000_000; // TODO@wzhudev: temporarily added const MAX_SECOND_INSTANCE_OVERFLOW = 100_000; // Only 100 KB -test('memory', async ({ page }) => { - test.setTimeout(80_000); - const client = await page.context().newCDPSession(page); +interface HeapSnapshotChunk { + chunk: string; +} - async function takeHeapSnapshot(client, filename) { - return new Promise((resolve, reject) => { - const file = createWriteStream(filename); - let isFinished = false; - let error = null; - let noChunkTimeout = null; + // Type the progress handler parameter +interface HeapSnapshotProgress { + done: number; + total: number; + finished?: boolean; +} +async function takeHeapSnapshot(client: CDPSession, filename: string) { + return new Promise((resolve, reject) => { + const file = createWriteStream(filename); + let isFinished = false; + let error = null; + let noChunkTimeout = null; + let chunkHandler = (_: HeapSnapshotChunk) => {}; + let progressHandler = (_: HeapSnapshotProgress) => {}; + + // Cleanup function to remove listeners + const cleanup = () => { + client.off('HeapProfiler.addHeapSnapshotChunk', chunkHandler); + client.off('HeapProfiler.reportHeapSnapshotProgress', progressHandler); + }; + + // Handle file stream errors + file.on('error', (err) => { + error = err; + reject(err); + }); - // Handle file stream errors - file.on('error', (err) => { - error = err; - reject(err); - }); + // Handle successful completion + file.on('finish', () => { + if (!error && isFinished) { + resolve(0); + } + }); - // Handle successful completion - file.on('finish', () => { - if (!error && isFinished) { - console.log('file write finished', filename); - resolve(0); + const scheduleEnd = () => { + if (noChunkTimeout) { + clearTimeout(noChunkTimeout); + } + + // Set new timeout + noChunkTimeout = setTimeout(() => { + cleanup(); + file.end(); + }, 1000); // Wait 1 second after last chunk + }; + + // Set up the chunk handler + chunkHandler = (payload: HeapSnapshotChunk) => { + try { + if (payload.chunk) { + console.log('chunkHandler write chunk', filename, file.writableLength); + file.write(payload.chunk); + scheduleEnd(); } + } catch (err) { + error = err; + console.error('chunkHandler error', err); + cleanup(); + reject(err); + } + }; + + // Set up the progress handler + progressHandler = (params: HeapSnapshotProgress) => { + if (params.finished) { + isFinished = true; + } + }; + + // Add event listeners + client.on('HeapProfiler.addHeapSnapshotChunk', chunkHandler); + client.on('HeapProfiler.reportHeapSnapshotProgress', progressHandler); + + // Start the heap snapshot process + client.send('HeapProfiler.enable') + .then(() => client.send('HeapProfiler.takeHeapSnapshot', { reportProgress: true })) + .catch((err) => { + console.error('HeapProfiler.enable error', err); + error = err; + file.end(); + cleanup(); + reject(err); }); + }); +} - const scheduleEnd = () => { - // Clear any existing timeout - if (noChunkTimeout) { - clearTimeout(noChunkTimeout); - } - - // Set new timeout - noChunkTimeout = setTimeout(() => { - cleanup(); - file.end(); - }, 1000); // Wait 1 second after last chunk - }; - // Set up the chunk handler - const chunkHandler = (params) => { - try { - if (params.chunk) { - console.log('chunkHandler write chunk', filename, file.writableLength); - file.write(params.chunk); - scheduleEnd(); - } - } catch (err) { - error = err; - console.error('chunkHandler error', err); - cleanup(); - reject(err); - } - }; - - // Set up the progress handler - const progressHandler = (params) => { - console.log('progressHandler params', filename, params); - if (params.finished) { - isFinished = true; - } - }; - - // Cleanup function to remove listeners - const cleanup = () => { - client.off('HeapProfiler.addHeapSnapshotChunk', chunkHandler); - client.off('HeapProfiler.reportHeapSnapshotProgress', progressHandler); - }; - - // Add event listeners - client.on('HeapProfiler.addHeapSnapshotChunk', chunkHandler); - client.on('HeapProfiler.reportHeapSnapshotProgress', progressHandler); - - // Start the heap snapshot process - client.send('HeapProfiler.enable') - .then(() => client.send('HeapProfiler.takeHeapSnapshot', { reportProgress: true })) - .catch((err) => { - console.error('HeapProfiler.enable error', err); - error = err; - cleanup(); - file.end(); - reject(err); - }); - }); - } +const isLocal = !process.env.CI; +test('memory', async ({ page }) => { + test.setTimeout(60_000); + const client = await page.context().newCDPSession(page); await page.goto('http://localhost:3000/sheets/'); - await page.waitForTimeout(5000); + await page.waitForTimeout(2000); const memoryAfterFirstInstance = (await getMetrics(page)).JSHeapUsedSize; @@ -131,8 +143,9 @@ test('memory', async ({ page }) => { await page.evaluate(() => window.univer.dispose()); await page.waitForTimeout(2000); - const firstSnapshot = await takeHeapSnapshot(client, 'memory-first.heapsnapshot'); - console.log('firstSnapshot', firstSnapshot); + if (isLocal) { + await takeHeapSnapshot(client, 'memory-first.heapsnapshot'); + } const memoryAfterDisposingFirstInstance = (await getMetrics(page)).JSHeapUsedSize; @@ -141,8 +154,9 @@ test('memory', async ({ page }) => { await page.evaluate(() => window.univer.dispose()); await page.waitForTimeout(2000); - const secondSnapshot = await takeHeapSnapshot(client, 'memory-second.heapsnapshot'); - console.log('secondSnapshot', secondSnapshot); + if (isLocal) { + await takeHeapSnapshot(client, 'memory-second.heapsnapshot'); + } const memoryAfterDisposingSecondUniver = (await getMetrics(page)).JSHeapUsedSize; expect(memoryAfterDisposingSecondUniver - memoryAfterDisposingFirstInstance) From f04df2f2bb124cf7791b86b721d758c2a1beb7fd Mon Sep 17 00:00:00 2001 From: lumixraku Date: Sat, 8 Feb 2025 11:17:56 +0800 Subject: [PATCH 4/8] test: try upload snapshots --- .github/workflows/playwright.yml | 9 +++++++++ e2e/memory/memory.spec.ts | 10 +++------- e2e/perf/scroll.spec.ts | 8 -------- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 757705c23c63..ef32ea28c039 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -53,3 +53,12 @@ jobs: playwright-report/ test-results/ retention-days: 30 + + - name: Upload heap snapshots + if: steps.test-run.outcome == 'failure' # Only upload if test step failed + uses: actions/upload-artifact@v4 + with: + name: heap-snapshots-${{ github.sha }} + path: | + *.heapsnapshot + retention-days: 5 diff --git a/e2e/memory/memory.spec.ts b/e2e/memory/memory.spec.ts index 8d519e1ba29e..4cbda73cf878 100644 --- a/e2e/memory/memory.spec.ts +++ b/e2e/memory/memory.spec.ts @@ -143,9 +143,7 @@ test('memory', async ({ page }) => { await page.evaluate(() => window.univer.dispose()); await page.waitForTimeout(2000); - if (isLocal) { - await takeHeapSnapshot(client, 'memory-first.heapsnapshot'); - } + await takeHeapSnapshot(client, 'memory-first.heapsnapshot'); const memoryAfterDisposingFirstInstance = (await getMetrics(page)).JSHeapUsedSize; @@ -154,13 +152,11 @@ test('memory', async ({ page }) => { await page.evaluate(() => window.univer.dispose()); await page.waitForTimeout(2000); - if (isLocal) { - await takeHeapSnapshot(client, 'memory-second.heapsnapshot'); - } + await takeHeapSnapshot(client, 'memory-second.heapsnapshot'); const memoryAfterDisposingSecondUniver = (await getMetrics(page)).JSHeapUsedSize; expect(memoryAfterDisposingSecondUniver - memoryAfterDisposingFirstInstance) - .toBeLessThanOrEqual(MAX_SECOND_INSTANCE_OVERFLOW); + .toBeLessThanOrEqual(1); expect(memoryAfterDisposingSecondUniver - memoryAfterFirstInstance) .toBeLessThanOrEqual(MAX_UNIVER_MEMORY_OVERFLOW); diff --git a/e2e/perf/scroll.spec.ts b/e2e/perf/scroll.spec.ts index 2f6460d65bf3..c60923020418 100644 --- a/e2e/perf/scroll.spec.ts +++ b/e2e/perf/scroll.spec.ts @@ -135,14 +135,6 @@ async function measureFPS(page: Page, testDuration = 5, deltaX: number, deltaY: const createTest = (title: string, sheetData: IJsonObject, minFpsValue: number, deltaX = 0, deltaY = 0) => { // Default Size Of browser: 1280x720 pixels. And default DPR is 1. test(title, async ({ page }) => { - // dev:e2e open localhost:3000, not 3002 - // let port = 3000; - // if (!isCI) { - // const browser = await chromium.launch({ headless: false }); // launch browser - // page = await browser.newPage(); - // port = 3002; - // } - await page.goto('http://localhost:3000/sheets/'); await page.waitForTimeout(2000); From 2bc78668726415ab18fbb6f2b868204e399fa92d Mon Sep 17 00:00:00 2001 From: lumixraku Date: Sat, 8 Feb 2025 12:08:49 +0800 Subject: [PATCH 5/8] test: in test-results --- .github/workflows/playwright.yml | 13 ++++++------- e2e/memory/memory.spec.ts | 9 ++++----- playwright.config.ts | 1 + 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index ef32ea28c039..f67aa9faa1c5 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -26,7 +26,7 @@ jobs: run: pnpm build:e2e - name: Run Playwright Tests - run: pnpm exec playwright test --output=playwright-assets + run: pnpm exec playwright test - name: 🚀 Deploy to Vercel uses: amondnet/vercel-action@v25 @@ -54,11 +54,10 @@ jobs: test-results/ retention-days: 30 - - name: Upload heap snapshots - if: steps.test-run.outcome == 'failure' # Only upload if test step failed + - name: Upload Snapshots uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} with: - name: heap-snapshots-${{ github.sha }} - path: | - *.heapsnapshot - retention-days: 5 + name: snapshots + path: test-results/ + retention-days: 30 diff --git a/e2e/memory/memory.spec.ts b/e2e/memory/memory.spec.ts index 4cbda73cf878..6c65c2e2298a 100644 --- a/e2e/memory/memory.spec.ts +++ b/e2e/memory/memory.spec.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -/* eslint-disable no-console */ import type { CDPSession } from '@playwright/test'; import { createWriteStream } from 'node:fs'; import { expect, test } from '@playwright/test'; @@ -28,7 +27,7 @@ const MAX_UNIT_MEMORY_OVERFLOW = 1_000_000; // 1MB const MAX_UNIVER_MEMORY_OVERFLOW = 6_000_000; // TODO@wzhudev: temporarily added 300KB // there is a memory leak in the univer object, so we need to make sure that -const MAX_SECOND_INSTANCE_OVERFLOW = 100_000; // Only 100 KB +// const MAX_SECOND_INSTANCE_OVERFLOW = 100_000; // Only 100 KB interface HeapSnapshotChunk { chunk: string; @@ -42,7 +41,7 @@ interface HeapSnapshotProgress { } async function takeHeapSnapshot(client: CDPSession, filename: string) { return new Promise((resolve, reject) => { - const file = createWriteStream(filename); + const file = createWriteStream(`./test-results/${filename}`); let isFinished = false; let error = null; let noChunkTimeout = null; @@ -84,7 +83,7 @@ async function takeHeapSnapshot(client: CDPSession, filename: string) { chunkHandler = (payload: HeapSnapshotChunk) => { try { if (payload.chunk) { - console.log('chunkHandler write chunk', filename, file.writableLength); + // console.log('chunkHandler write chunk', filename, file.writableLength); file.write(payload.chunk); scheduleEnd(); } @@ -120,7 +119,7 @@ async function takeHeapSnapshot(client: CDPSession, filename: string) { }); } -const isLocal = !process.env.CI; +// const isLocal = !process.env.CI; test('memory', async ({ page }) => { test.setTimeout(60_000); const client = await page.context().newCDPSession(page); diff --git a/playwright.config.ts b/playwright.config.ts index d40698aa5246..094abe67db5c 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -18,6 +18,7 @@ const HEADLESS = !!process.env.HEADLESS; */ export default defineConfig({ testDir: './e2e', + outputDir: 'test-results/', // Make sure this is set /* Run tests in files in parallel */ fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ From 4440ab29d85e18b64db49752c2c6a570dadd04a6 Mon Sep 17 00:00:00 2001 From: lumixraku Date: Sat, 8 Feb 2025 12:51:30 +0800 Subject: [PATCH 6/8] test: upload only when failed --- .github/workflows/playwright.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index f67aa9faa1c5..a2bd2468c4c5 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -54,10 +54,10 @@ jobs: test-results/ retention-days: 30 - - name: Upload Snapshots + - name: Upload HeapSnapshots uses: actions/upload-artifact@v4 - if: ${{ !cancelled() }} + if: ${{ failure() }} with: name: snapshots - path: test-results/ + path: test-results/*.heapsnapshot retention-days: 30 From 77c886f9b18aafc360a12b0151b73cbfba4c78ed Mon Sep 17 00:00:00 2001 From: lumixraku Date: Sat, 8 Feb 2025 13:29:16 +0800 Subject: [PATCH 7/8] test: upload only when failed 2 --- .github/workflows/playwright.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index a2bd2468c4c5..645a2e7b64ac 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -49,9 +49,7 @@ jobs: if: ${{ !cancelled() }} with: name: playwright-report - path: | - playwright-report/ - test-results/ + path: playwright-report/ retention-days: 30 - name: Upload HeapSnapshots @@ -60,4 +58,4 @@ jobs: with: name: snapshots path: test-results/*.heapsnapshot - retention-days: 30 + retention-days: 3 From fbf140657a3ee1fe9ab466037d42f4be8be94283 Mon Sep 17 00:00:00 2001 From: lumixraku Date: Sat, 8 Feb 2025 13:43:21 +0800 Subject: [PATCH 8/8] chore: better code --- e2e/memory/memory.spec.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/e2e/memory/memory.spec.ts b/e2e/memory/memory.spec.ts index 6c65c2e2298a..36358ae06397 100644 --- a/e2e/memory/memory.spec.ts +++ b/e2e/memory/memory.spec.ts @@ -27,13 +27,12 @@ const MAX_UNIT_MEMORY_OVERFLOW = 1_000_000; // 1MB const MAX_UNIVER_MEMORY_OVERFLOW = 6_000_000; // TODO@wzhudev: temporarily added 300KB // there is a memory leak in the univer object, so we need to make sure that -// const MAX_SECOND_INSTANCE_OVERFLOW = 100_000; // Only 100 KB +const MAX_SECOND_INSTANCE_OVERFLOW = 100_000; // Only 100 KB interface HeapSnapshotChunk { chunk: string; } - // Type the progress handler parameter interface HeapSnapshotProgress { done: number; total: number; @@ -83,7 +82,6 @@ async function takeHeapSnapshot(client: CDPSession, filename: string) { chunkHandler = (payload: HeapSnapshotChunk) => { try { if (payload.chunk) { - // console.log('chunkHandler write chunk', filename, file.writableLength); file.write(payload.chunk); scheduleEnd(); } @@ -155,7 +153,7 @@ test('memory', async ({ page }) => { const memoryAfterDisposingSecondUniver = (await getMetrics(page)).JSHeapUsedSize; expect(memoryAfterDisposingSecondUniver - memoryAfterDisposingFirstInstance) - .toBeLessThanOrEqual(1); + .toBeLessThanOrEqual(MAX_SECOND_INSTANCE_OVERFLOW); expect(memoryAfterDisposingSecondUniver - memoryAfterFirstInstance) .toBeLessThanOrEqual(MAX_UNIVER_MEMORY_OVERFLOW);