From b4cbe7b604788974bd2d81188caa88208afb94c1 Mon Sep 17 00:00:00 2001 From: Rui Figueira Date: Mon, 29 Jul 2024 20:22:37 +0100 Subject: [PATCH] test(trace-viewer): use latch to control test execution --- tests/spawn-trace-viewer.spec.ts | 21 ++++++++++++--------- tests/utils.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/tests/spawn-trace-viewer.spec.ts b/tests/spawn-trace-viewer.spec.ts index e2c9b9ef3..e6b13ccaf 100644 --- a/tests/spawn-trace-viewer.spec.ts +++ b/tests/spawn-trace-viewer.spec.ts @@ -86,25 +86,28 @@ test('should not open trace viewer if test did not run', async ({ activate }) => await expect.poll(() => traceViewerInfo(vscode)).toBeUndefined(); }); -test('should refresh trace viewer while test is running', async ({ activate }) => { +test('should refresh trace viewer while test is running', async ({ activate, createLatch }) => { + const latch = createLatch(); + const { vscode, testController } = await activate({ 'playwright.config.js': `module.exports = { testDir: 'tests' }`, 'tests/test.spec.ts': ` import { test } from '@playwright/test'; - test('should pass', async () => await new Promise(r => setTimeout(r, 1000))); + test('should pass', async () => ${latch.blockingCode}); `, }); await testController.expandTestItems(/test.spec/); selectTestItem(testController.findTestItems(/pass/)[0]); - await Promise.all([ - testController.run(), - expect.poll(() => traceViewerInfo(vscode)).toMatchObject({ - type: 'spawn', - traceFile: expect.stringMatching(/\.json$/), - }), - ]); + const testRunPromise = testController.run(); + await expect.poll(() => traceViewerInfo(vscode)).toMatchObject({ + type: 'spawn', + traceFile: expect.stringMatching(/\.json$/), + }); + + latch.open(); + await testRunPromise; await expect.poll(() => traceViewerInfo(vscode)).toMatchObject({ type: 'spawn', diff --git a/tests/utils.ts b/tests/utils.ts index e1b871422..e96c35e7d 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -18,6 +18,8 @@ import { expect as baseExpect, test as baseTest, Browser, chromium, Page } from import { Extension } from '../out/extension'; import { TestController, VSCode, WorkspaceFolder, TestRun, TestItem } from './mock/vscode'; +import crypto from 'crypto'; +import fs from 'fs'; import path from 'path'; type ActivateResult = { @@ -26,11 +28,18 @@ type ActivateResult = { workspaceFolder: WorkspaceFolder; }; +type Latch = { + blockingCode: string; + open: () => void; + close: () => void; +}; + type TestFixtures = { vscode: VSCode, activate: (files: { [key: string]: string }, options?: { rootDir?: string, workspaceFolders?: [string, any][], env?: Record }) => Promise; showTrace: boolean; envRemoteName?: string; + createLatch: () => Latch; }; export type WorkerOptions = { @@ -160,6 +169,18 @@ export const test = baseTest.extend({ for (const vscode of instances) vscode.dispose(); }, + + // Copied from https://github.com/microsoft/playwright/blob/7e7319da7d84de6648900e27e6d844bec9071222/tests/playwright-test/ui-mode-fixtures.ts#L132 + createLatch: async ({}, use, testInfo) => { + await use(() => { + const latchFile = path.join(testInfo.project.outputDir, createGuid() + '.latch'); + return { + blockingCode: `await ((${waitForLatch})(${JSON.stringify(latchFile)}))`, + open: () => fs.writeFileSync(latchFile, 'ok'), + close: () => fs.unlinkSync(latchFile), + }; + }); + }, }); export async function connectToSharedBrowser(vscode: VSCode) { @@ -234,3 +255,13 @@ export async function singleWebViewByPanelType(vscode: VSCode, viewType: string) export function traceViewerInfo(vscode: VSCode): { type: 'spawn' | 'embedded', serverUrlPrefix?: string, testConfigFile: string } | undefined { return vscode.extensions[0].traceViewerInfoForTest(); } + +async function waitForLatch(latchFile: string) { + const fs = require('fs'); + while (!fs.existsSync(latchFile)) + await new Promise(f => setTimeout(f, 250)); +} + +function createGuid(): string { + return crypto.randomBytes(16).toString('hex'); +}