-
-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathsuite.ts
129 lines (106 loc) · 3.32 KB
/
suite.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import fs from 'node:fs';
import path from 'node:path';
import { execSync } from 'node:child_process';
import * as vitest from 'vitest';
import { installAddon, type AddonMap, type OptionMap } from 'sv';
import {
addPnpmBuildDependendencies,
createProject,
startPreview,
type CreateProject,
type ProjectVariant
} from 'sv/testing';
import { chromium, type Browser, type Page } from '@playwright/test';
import { fileURLToPath } from 'node:url';
const cwd = vitest.inject('testDir');
const templatesDir = vitest.inject('templatesDir');
const variants = vitest.inject('variants');
const SETUP_DIR = fileURLToPath(new URL('.', import.meta.url));
type Fixtures<Addons extends AddonMap> = {
page: Page;
run(variant: ProjectVariant, options: OptionMap<Addons>): Promise<string>;
};
export function setupTest<Addons extends AddonMap>(addons: Addons) {
let create: CreateProject;
let browser: Browser;
const test = vitest.test.extend<Fixtures<Addons>>({} as any);
vitest.beforeAll(async () => {
browser = await chromium.launch();
return async () => {
await browser.close();
};
});
vitest.beforeAll(({ name }) => {
const testName = path.parse(name).name.replace('.test', '');
// constructs a builder for create test projects
create = createProject({ cwd, templatesDir, testName });
// creates a pnpm workspace in each addon dir
fs.writeFileSync(
path.resolve(cwd, testName, 'pnpm-workspace.yaml'),
"packages:\n - '**/*'",
'utf8'
);
// creates a barebones package.json in each addon dir
fs.writeFileSync(
path.resolve(cwd, testName, 'package.json'),
JSON.stringify({
name: `${testName}-workspace-root`,
private: true
})
);
});
// runs before each test case
vitest.beforeEach<Fixtures<Addons>>(async (ctx) => {
const browserCtx = await browser.newContext();
ctx.page = await browserCtx.newPage();
ctx.run = async (variant, options) => {
const cwd = create({ testId: ctx.task.id, variant });
// test metadata
const metaPath = path.resolve(cwd, 'meta.json');
fs.writeFileSync(metaPath, JSON.stringify({ variant, options }, null, '\t'), 'utf8');
// run addon
const { pnpmBuildDependencies } = await installAddon({
cwd,
addons,
options,
packageManager: 'pnpm'
});
addPnpmBuildDependendencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]);
return cwd;
};
return async () => {
await browserCtx.close();
// ...other tear downs
};
});
return {
test,
variants,
prepareServer
};
}
/**
* Installs dependencies, builds the project, and spins up the preview server
*/
async function prepareServer({ cwd, page }: { cwd: string; page: Page }) {
// install deps
execSync('pnpm install --no-frozen-lockfile', { cwd, stdio: 'pipe' });
// ...do commands and any other extra stuff
// build project
execSync('npm run build', { cwd, stdio: 'pipe' });
// start preview server `vite preview`
const { url, close } = await startPreview({ cwd });
// navigate to the page
await page.goto(url);
return { url, close };
}
/**
* Applies a fixture to the target path
*/
export function fixture({ name, target }: { name: string; target: string }) {
const fixturePath = path.resolve(SETUP_DIR, '..', 'fixtures', name);
if (!fs.existsSync(fixturePath)) {
throw new Error(`Fixture does not exist at: ${fixturePath}`);
}
fs.copyFileSync(fixturePath, target);
}