8000 chore: Speed up tests (#527) · svelte-add/svelte-add@228cdbe · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Oct 20, 2024. It is now read-only.

Commit 228cdbe

Browse files
authored
chore: Speed up tests (#527)
* restructure installs * fix out of order cases * reuse browser instance * execute storybook tests asynchronously * changeset * only return `page`
1 parent 7c036e5 commit 228cdbe

File tree

6 files changed

+95
-41
lines changed

6 files changed

+95
-41
lines changed

.changeset/clever-moons-buy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@svelte-add/testing-library': patch
3+
---
4+
5+
chore: restructured execution order of tests

adders/storybook/config/tests.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { defineAdderTests } from '@svelte-add/core';
22
import { options } from './options.js';
33

4+
let port = 6006;
5+
46
export const tests = defineAdderTests({
57
options,
68
optionValues: [],
7-
// If you run multiple of these tests in parallel, most of the times randomly one test
8-
// will fail while executing some npx command with an exit code of 7.
9-
// In order to get consistent results, we execute those tests one after the other.
10-
runSynchronously: true,
11-
command: 'storybook',
9+
get command() {
10+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
11+
return `storybook -p ${port++}`;
12+
},
1213
files: [],
1314
tests: [
1415
{

packages/testing-library/index.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import path from 'node:path';
2+
import fs from 'node:fs';
13
import { rm } from 'node:fs/promises';
24
import { generateTestCases, runTestCases } from './utils/test-cases';
35
import { getTemplatesDirectory } from './utils/workspace';
4-
import { downloadProjectTemplates } from './utils/create-project';
6+
import { downloadProjectTemplates, ProjectTypes } from './utils/create-project';
57
import { remoteControl } from '@svelte-add/core/internal';
68
import type { AdderWithoutExplicitArgs } from '@svelte-add/core/adder/config';
79

@@ -18,6 +20,21 @@ export async function testAdder(adder: AdderWithoutExplicitArgs, options: TestOp
1820
export async function testAdders(adders: AdderWithoutExplicitArgs[], options: TestOptions) {
1921
await prepareTests(options);
2022

23+
const dirs: string[] = [];
24+
for (const type of Object.values(ProjectTypes)) {
25+
dirs.push(...adders.map((a) => ` - '${a.config.metadata.id}/${type}/*'`));
26+
}
27+
28+
const pnpmWorkspace = `pack 6D40 ages:\n${dirs.join('\n')}\n`;
29+
fs.writeFileSync(path.join(options.outputDirectory, 'pnpm-workspace.yaml'), pnpmWorkspace, {
30+
encoding: 'utf8',
31+
});
32+
33+
const testRootPkgJson = JSON.stringify({ name: 'test-root', version: '0.0.0', type: 'module' });
34+
fs.writeFileSync(path.join(options.outputDirectory, 'package.json'), testRootPkgJson, {
35+
encoding: 'utf8',
36+
});
37+
2138
remoteControl.enable();
2239
await executeTests(adders, options);
2340
remoteControl.disable();
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
import { chromium, type Browser, type Page } from 'playwright';
1+
import { chromium, type Browser } from 'playwright';
22

3-
export async function startBrowser(url: string, headless: boolean) {
4-
const browser = await chromium.launch({ headless });
3+
let browser: Browser;
4+
5+
export async function startBrowser(headless: boolean) {
6+
browser = await chromium.launch({ headless });
7+
}
8+
9+
export async function openPage(url: string) {
510
const page = await browser.newPage();
611

712
await page.goto(url, { timeout: 60_000 });
@@ -11,10 +16,9 @@ export async function startBrowser(url: string, headless: boolean) {
1116
// of each developer and thus leads to inconsistent test results.
1217
await page.emulateMedia({ colorScheme: 'light' });
1318

14-
return { browser, page };
19+
return page;
1520
}
1621

17-
export async function stopBrowser(browser: Browser, page: Page) {
18-
await page.close();
22+
export async function stopBrowser() {
1923
await browser.close();
2024
}

packages/testing-library/utils/test-cases.ts

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ProjectTypesList } from './create-project';
44
import { runTests } from './test';
55
import { uid } from 'uid';
66
import { startDevServer, stopDevServer } from './dev-server';
7-
import { startBrowser, stopBrowser } from './browser-control';
7+
import { openPage, startBrowser, stopBrowser } from './browser-control';
88
import {
99
getTemplatesDirectory,
1010
installDependencies,
@@ -58,7 +58,7 @@ export function generateTestCases(adders: AdderWithoutExplicitArgs[]) {
5858
return testCases;
5959
}
6060

61-
export async function runAdderTests(
61+
export async function setupAdder(
6262
template: string,
6363
adder: AdderWithoutExplicitArgs,
6464
options: OptionValues<Record<string, Question>>,
@@ -81,10 +81,17 @@ export async function runAdderTests(
8181

8282
await runAdder(adder, workingDirectory, options);
8383

84-
await installDependencies(workingDirectory);
84+
return workingDirectory;
85+
}
8586

86-
const { url, devServer } = await startDevServer(workingDirectory, adder.tests.command ?? 'dev');
87-
const { browser, page } = await startBrowser(url, testOptions.headless);
87+
export async function executeAdderTests(
88+
workingDirectory: string,
89+
adder: AdderWithoutExplicitArgs,
90+
options: OptionValues<Record<string, Question>>,
91+
testOptions: TestOptions,
92+
) {
93+
const { url, devServer } = await startDevServer(workingDirectory, adder.tests?.command ?? 'dev');
94+
const page = await openPage(url);
8895

8996
try {
9097
const errorOcurred = await page.$('vite-error-overlay');
@@ -96,7 +103,7 @@ export async function runAdderTests(
96103

97104
await runTests(page, adder, options);
98105
} finally {
99-
await stopBrowser(browser, page);
106+
await page.close();
100107
await stopDevServer(devServer);
101108
}
102109
}
@@ -112,30 +119,50 @@ export async function runTestCases(testCases: Map<string, TestCase[]>, testOptio
112119
const syncTasks: Array<() => Promise<void>> = [];
113120
const asyncTestCaseInputs: TestCase[] = [];
114121
const syncTestCaseInputs: TestCase[] = [];
122+
const tests: { testCase: TestCase; cwd: string }[] = [];
123+
124+
console.log('executing adders');
115125
for (const values of testCases.values()) {
116126
for (const testCase of values) {
117-
const taskExecutor = async () => {
118-
try {
119-
await runAdderTests(testCase.template, testCase.adder, testCase.options, testOptions);
120-
} catch (e) {
121-
const error = e as Error;
122-
const adderError: AdderError = {
123-
name: 'AdderError',
124-
adder: testCase.adder.config.metadata.id,
125-
template: testCase.template,
126-
message: error.message,
127-
};
128-
throw adderError;
129-
}
130-
};
127+
const cwd = await setupAdder(
128+
testCase.template,
129+
testCase.adder,
130+
testCase.options,
131+
testOptions,
132+
);
131133

132-
if (testCase.runSynchronously) {
133-
syncTasks.push(taskExecutor);
134-
syncTestCaseInputs.push(testCase);
135-
} else {
136-
asyncTasks.push(taskExecutor);
137-
asyncTestCaseInputs.push(testCase);
134+
tests.push({ testCase, cwd });
135+
}
136+
}
137+
138+
console.log('installing dependencies');
139+
await installDependencies(testOptions.outputDirectory);
140+
141+
await startBrowser(testOptions.headless);
142+
143+
console.log('running tests');
144+
for (const { cwd, testCase } of tests) {
145+
const taskExecutor = async () => {
146+
try {
147+
await executeAdderTests(cwd, testCase.adder, testCase.options, testOptions);
148+
} catch (e) {
149+
const error = e as Error;
150+
const adderError: AdderError = {
151+
name: 'AdderError',
152+
adder: testCase.adder.config.metadata.id,
153+
template: testCase.template,
154+
message: error.message,
155+
};
156+
throw adderError;
138157
}
158+
};
159+
160+
if (testCase.runSynchronously) {
161+
syncTasks.push(taskExecutor);
162+
syncTestCaseInputs.push(testCase);
163+
} else {
164+
asyncTasks.push(taskExecutor);
165+
asyncTestCaseInputs.push(testCase);
139166
}
140167
}
141168

@@ -173,6 +200,8 @@ export async function runTestCases(testCases: Map<string, TestCase[]>, testOptio
173200
},
174201
});
175202

203+
await stopBrowser();
204+
176205
const rejectedAsyncPromisesResult = allAsyncResults.rejectedIndexes.map<AdderError>(
177206
(x) => allAsyncResults.taskResults[x] as unknown as AdderError,
178207
);

packages/testing-library/utils/workspace.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ export function getTemplatesDirectory(options: TestOptions) {
1212

1313
export async function installDependencies(output: string) {
1414
try {
15-
// Since tests are executed and installed within this repo (packages/tests/.outputs),
16-
// we need to add the `--ignore-workspace` flag so that our root lockfile isn't modified
17-
await executeCli('pnpm', ['install', '--ignore-workspace'], output, { stdio: 'pipe' });
15+
await executeCli('pnpm', ['install'], output, { stdio: 'pipe' });
1816
} catch (error) {
1917
const typedError = error as Error;
2018
throw new Error('unable to install dependencies: ' + typedError.message);

0 commit comments

Comments
 (0)
0