Skip to content

Commit e52d51e

Browse files
committed
chore(tests): Added variant flag
1 parent 8596086 commit e52d51e

File tree

2 files changed

+104
-5
lines changed

2 files changed

+104
-5
lines changed

dev-packages/e2e-tests/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ Or run only a single E2E test app:
2525
yarn test:run <app-name>
2626
```
2727

28+
Or you can run a single E2E test app with a specific variant:
29+
30+
```bash
31+
yarn test:run <app-name> --variant <variant-name>
32+
```
33+
34+
Variant name matching is case-insensitive and partial. For example, `--variant 13` will match `nextjs-pages-dir (next@13)` if a matching variant is present in the test app's `package.json`.
35+
2836
## How they work
2937

3038
Before running any tests we launch a fake test registry (in our case [Verdaccio](https://verdaccio.org/docs/e2e/)), we

dev-packages/e2e-tests/run.ts

Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
/* eslint-disable no-console */
22
import { spawn } from 'child_process';
33
import * as dotenv from 'dotenv';
4-
import { mkdtemp, rm } from 'fs/promises';
4+
import { mkdtemp, readFile, rm } from 'fs/promises';
55
import { sync as globSync } from 'glob';
66
import { tmpdir } from 'os';
77
import { join, resolve } from 'path';
88
import { copyToTemp } from './lib/copyToTemp';
99
import { registrySetup } from './registrySetup';
1010

11+
interface SentryTestVariant {
12+
'build-command': string;
13+
label: string;
14+
}
15+
16+
interface PackageJson {
17+
sentryTest?: {
18+
variants?: SentryTestVariant[];
19+
optionalVariants?: SentryTestVariant[];
20+
};
21+
}
22+
1123
const DEFAULT_DSN = 'https://username@domain/123';
1224
const DEFAULT_SENTRY_ORG_SLUG = 'sentry-javascript-sdks';
1325
const DEFAULT_SENTRY_PROJECT = 'sentry-javascript-e2e-tests';
@@ -58,14 +70,84 @@ function asyncExec(
5870
});
5971
}
6072

73+
function findMatchingVariant(variants: SentryTestVariant[], variantLabel: string): SentryTestVariant | undefined {
74+
const variantLabelLower = variantLabel.toLowerCase();
75+
76+
return variants.find(variant => variant.label.toLowerCase().includes(variantLabelLower));
77+
}
78+
79+
async function getVariantBuildCommand(
80+
packageJsonPath: string,
81+
variantLabel: string,
82+
testAppPath: string,
83+
): Promise<{ buildCommand: string; testLabel: string; matchedVariantLabel?: string }> {
84+
try {
85+
const packageJsonContent = await readFile(packageJsonPath, 'utf-8');
86+
const packageJson: PackageJson = JSON.parse(packageJsonContent);
87+
88+
const allVariants = [
89+
...(packageJson.sentryTest?.variants || []),
90+
...(packageJson.sentryTest?.optionalVariants || []),
91+
];
92+
93+
const matchingVariant = findMatchingVariant(allVariants, variantLabel);
94+
95+
if (matchingVariant) {
96+
return {
97+
buildCommand: `volta run ${matchingVariant['build-command']}`,
98+
testLabel: matchingVariant.label,
99+
matchedVariantLabel: matchingVariant.label,
100+
};
101+
}
102+
103+
console.log(`No matching variant found for "${variantLabel}" in ${testAppPath}, using default build`);
104+
} catch (error) {
105+
console.log(`Could not read variants from package.json for ${testAppPath}, using default build`);
106+
}
107+
108+
return {
109+
buildCommand: 'volta run pnpm test:build',
110+
testLabel: testAppPath,
111+
};
112+
}
113+
61114
async function run(): Promise<void> {
62115
// Load environment variables from .env file locally
63116
dotenv.config();
64117

65118
// Allow to run a single app only via `yarn test:run <app-name>`
66119
const appName = process.argv[2] || '';
67120
// Forward any additional flags to the test command
68-
const testFlags = process.argv.slice(3);
121+
const allTestFlags = process.argv.slice(3);
122+
123+
// Check for --variant flag
124+
let variantLabel: string | undefined;
125+
let skipNextFlag = false;
126+
127+
const testFlags = allTestFlags.filter((flag, index) => {
128+
// Skip this flag if it was marked to skip (variant value after --variant)
129+
if (skipNextFlag) {
130+
skipNextFlag = false;
131+
return false;
132+
}
133+
134+
// Handle --variant=<value> format
135+
if (flag.startsWith('--variant=')) {
136+
variantLabel = flag.split('=')[1];
137+
return false; // Remove this flag from testFlags
138+
}
139+
140+
// Handle --variant <value> format
141+
if (flag === '--variant') {
142+
if (index + 1 < allTestFlags.length) {
143+
variantLabel = allTestFlags[index + 1];
144+
skipNextFlag = true; // Mark next flag to be skipped
145+
}
146+
return false;
147+
}
148+
149+
return true;
150+
});
69151

70152
const dsn = process.env.E2E_TEST_DSN || DEFAULT_DSN;
71153

@@ -107,11 +189,20 @@ async function run(): Promise<void> {
107189

108190
await copyToTemp(originalPath, tmpDirPath);
109191
const cwd = tmpDirPath;
192+
// Resolve variant if needed
193+
const { buildCommand, testLabel, matchedVariantLabel } = variantLabel
194+
? await getVariantBuildCommand(join(tmpDirPath, 'package.json'), variantLabel, testAppPath)
195+
: { buildCommand: 'volta run pnpm test:build', testLabel: testAppPath };
196+
197+
// Print which variant we're using if found
198+
if (matchedVariantLabel) {
199+
console.log(`Using variant: "${matchedVariantLabel}"`);
200+
}
110201

111-
console.log(`Building ${testAppPath} in ${tmpDirPath}...`);
112-
await asyncExec('volta run pnpm test:build', { env, cwd });
202+
console.log(`Building ${testLabel} in ${tmpDirPath}...`);
203+
await asyncExec(buildCommand, { env, cwd });
113204

114-
console.log(`Testing ${testAppPath}...`);
205+
console.log(`Testing ${testLabel}...`);
115206
// Pass command and arguments as an array to prevent command injection
116207
const testCommand = ['volta', 'run', 'pnpm', 'test:assert', ...testFlags];
117208
await asyncExec(testCommand, { env, cwd });

0 commit comments

Comments
 (0)