Skip to content

Commit 8e31fb7

Browse files
committed
fix: add missing file plus exclude e2e from vitest
1 parent bcafb59 commit 8e31fb7

File tree

5 files changed

+192
-41
lines changed

5 files changed

+192
-41
lines changed

cmp/.github/workflows/ci.yml

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
name: CI
22

33
on:
4+
push:
5+
branches: [main]
46
pull_request:
5-
branches: [main, dev]
7+
branches: [main]
68

79
jobs:
810
lint:
@@ -42,3 +44,34 @@ jobs:
4244
run: pnpm build
4345
- name: Test
4446
run: pnpm test
47+
48+
playwright-e2e:
49+
timeout-minutes: 60
50+
runs-on: ubuntu-latest
51+
steps:
52+
- uses: actions/checkout@v5.0.1
53+
# pnpm version is taken from package.json
54+
- name: Install pnpm
55+
uses: pnpm/action-setup@v4
56+
- name: Use Node.js 20
57+
uses: actions/setup-node@v6.0.0
58+
with:
59+
node-version: 20
60+
cache: "pnpm"
61+
- name: Install dependencies
62+
run: pnpm install
63+
- name: Install Playwright Browsers
64+
working-directory: ./compiler
65+
run: pnpm exec playwright install --with-deps
66+
- name: Prepare tests
67+
working-directory: ./compiler
68+
run: pnpm run test:prepare
69+
- name: Run tests
70+
working-directory: ./compiler
71+
run: pnpm run test:e2e
72+
- uses: actions/upload-artifact@v4
73+
if: ${{ !cancelled() }}
74+
with:
75+
name: playwright-report
76+
path: playwright-report/
77+
retention-days: 30

cmp/.github/workflows/playwright.yml

Lines changed: 0 additions & 37 deletions
This file was deleted.

cmp/compiler/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,14 @@
117117
"clean": "rm -rf build",
118118
"test": "vitest --run",
119119
"test:watch": "vitest -w",
120-
"test:prepare": "tsx tests/helpers/prepare-fixtures.ts",
120+
"test:prepare": "pnpm build && tsx tests/helpers/prepare-fixtures.ts",
121121
"test:e2e": "playwright test",
122122
"test:e2e:next": "playwright test --grep next",
123123
"test:e2e:vite": "playwright test --grep vite",
124124
"test:e2e:shared": "playwright test tests/e2e/shared",
125125
"test:e2e:dev": "playwright test --ui",
126126
"test:e2e:debug": "playwright test --debug",
127-
"test:e2e:report": "playwright show-report",
128-
"playwright:install": "playwright install chromium"
127+
"test:e2e:report": "playwright show-report"
129128
},
130129
"keywords": [],
131130
"author": "",
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import * as fs from "fs/promises";
2+
import * as fsSync from "fs";
3+
import * as path from "path";
4+
import * as crypto from "crypto";
5+
6+
export interface FileChecksum {
7+
path: string;
8+
hash: string;
9+
}
10+
11+
export interface FixtureChecksums {
12+
framework: "next" | "vite";
13+
generatedAt: string;
14+
files: FileChecksum[];
15+
}
16+
17+
/**
18+
* Generate SHA-256 hash for a file
19+
*/
20+
async function hashFile(filePath: string): Promise<string> {
21+
const content = await fs.readFile(filePath);
22+
return crypto.createHash("sha256").update(content).digest("hex");
23+
}
24+
25+
/**
26+
* Recursively get all files in a directory (excluding specified patterns)
27+
*/
28+
async function getAllFiles(
29+
dir: string,
30+
baseDir: string,
31+
exclude: string[] = [],
32+
): Promise<string[]> {
33+
const files: string[] = [];
34+
const entries = await fs.readdir(dir, { withFileTypes: true });
35+
36+
for (const entry of entries) {
37+
const fullPath = path.join(dir, entry.name);
38+
const relativePath = path.relative(baseDir, fullPath);
39+
40+
// Skip excluded paths
41+
if (exclude.some((pattern) => relativePath.includes(pattern))) {
42+
continue;
43+
}
44+
45+
if (entry.isDirectory()) {
46+
const subFiles = await getAllFiles(fullPath, baseDir, exclude);
47+
files.push(...subFiles);
48+
} else {
49+
files.push(relativePath);
50+
}
51+
}
52+
53+
return files;
54+
}
55+
56+
/**
57+
* Generate checksums for all source files in a fixture
58+
*/
59+
export async function generateFixtureChecksums(
60+
fixturePath: string,
61+
framework: "next" | "vite",
62+
): Promise<FixtureChecksums> {
63+
console.log(` Generating checksums for ${framework} fixture...`);
64+
65+
// Get all files except build artifacts, dependencies, and generated files
66+
const exclude = [
67+
"node_modules",
68+
".next",
69+
"dist",
70+
".lingo",
71+
".turbo",
72+
"pnpm-lock.yaml",
73+
".DS_Store",
74+
"routeTree.gen.ts", // TanStack Router generated file
75+
];
76+
77+
const files = await getAllFiles(fixturePath, fixturePath, exclude);
78+
79+
// Generate checksums for each file
80+
const checksums: FileChecksum[] = [];
81+
for (const file of files) {
82+
const fullPath = path.join(fixturePath, file);
83+
const hash = await hashFile(fullPath);
84+
checksums.push({ path: file, hash });
85+
}
86+
87+
return {
88+
framework,
89+
generatedAt: new Date().toISOString(),
90+
files: checksums,
91+
};
92+
}
93+
94+
function getChecksumFilePath(fixturePath: string) {
95+
return path.join(fixturePath, ".lingo", "checksums.json");
96+
}
97+
98+
/**
99+
* Save checksums to a JSON file
100+
*/
101+
export async function saveChecksums(
102+
fixturePath: string,
103+
checksums: FixtureChecksums,
104+
): Promise<void> {
105+
const checksumsPath = getChecksumFilePath(fixturePath);
106+
await fs.mkdir(path.dirname(checksumsPath), { recursive: true });
107+
await fs.writeFile(checksumsPath, JSON.stringify(checksums, null, 2));
108+
console.log(` ✅ Checksums saved to ${checksumsPath}`);
109+
}
110+
111+
/**
112+
* Load checksums from a fixture
113+
*/
114+
export async function loadChecksums(
115+
fixturePath: string,
116+
): Promise<FixtureChecksums> {
117+
const checksumsPath = getChecksumFilePath(fixturePath);
118+
const content = await fs.readFile(checksumsPath, "utf-8");
119+
return JSON.parse(content);
120+
}
121+
122+
/**
123+
* Verify fixture integrity by comparing current hashes with saved checksums
124+
*/
125+
export async function verifyFixtureIntegrity(
126+
fixturePath: string,
127+
): Promise<{ valid: boolean; errors: string[] }> {
128+
const errors: string[] = [];
129+
130+
const checksumsPath = getChecksumFilePath(fixturePath);
131+
if (!fsSync.existsSync(checksumsPath)) {
132+
errors.push(
133+
"Checksums file not found. Please run 'pnpm test:prepare' to generate it.",
134+
);
135+
return { valid: false, errors };
136+
}
137+
138+
const savedChecksums = await loadChecksums(fixturePath);
139+
140+
for (const { path: filePath, hash: expectedHash } of savedChecksums.files) {
141+
const fullPath = path.join(fixturePath, filePath);
142+
143+
if (!fsSync.existsSync(fullPath)) {
144+
errors.push(`File missing: ${filePath}`);
145+
continue;
146+
}
147+
148+
const currentHash = await hashFile(fullPath);
149+
if (currentHash !== expectedHash) {
150+
errors.push(`File modified: ${filePath}`);
151+
}
152+
}
153+
154+
return { valid: errors.length === 0, errors };
155+
}

cmp/compiler/vitest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ export default defineConfig({
55
globals: true,
66
environment: "node",
77
snapshotSerializers: ["./src/react/shared/test-serializer.ts"],
8+
exclude: ["**/tests/e2e/**"],
89
},
910
});

0 commit comments

Comments
 (0)