Skip to content

test: Run E2E tests in isolated tmp directory #16783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 32 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fb2320a
test: Run E2E tests in isolated tmp directory
mydea Jul 1, 2025
2a9a7c5
fix paths
mydea Jul 1, 2025
690c13e
update other actions
mydea Jul 1, 2025
9ac1b67
add console.log
mydea Jul 1, 2025
45c46de
make abs
mydea Jul 1, 2025
87630f5
actually make abs
mydea Jul 1, 2025
f6bcc8b
just use __dirname??
mydea Jul 1, 2025
4d3b39e
handle deps
mydea Jul 1, 2025
b60bcd4
more generic link: handling and fix aws-lambda-layer e2e test
mydea Jul 2, 2025
4548516
more tests...
mydea Jul 2, 2025
8fc3bda
bump wrangler
mydea Jul 2, 2025
7b76fda
fix solidstart tests
mydea Jul 2, 2025
7ec4387
align all playwright versions of tests
mydea Jul 2, 2025
1b3f9ab
remove SpanJSON type casting
mydea Jul 2, 2025
293c84f
add more missing deps
mydea Jul 2, 2025
b06743d
add missing dep
mydea Jul 2, 2025
278b93c
use wrangler version?
mydea Jul 2, 2025
bb0cd8d
require volta config
mydea Jul 2, 2025
d8fecf2
deduplicate
mydea Jul 2, 2025
a414d93
no need for nuxt external config
mydea Jul 2, 2025
71fc6a4
add all missing voltas
mydea Jul 2, 2025
75c365a
avoid thingy
mydea Jul 2, 2025
f722e11
avoid copy iitm stuff
mydea Jul 2, 2025
ced990b
fixes for nuxt-3-min
mydea Jul 2, 2025
ae798cd
no need for copy stuff anymore
mydea Jul 2, 2025
b7beaa9
fix vue router for old version ??
mydea Jul 3, 2025
a0e9a7b
avoid core
mydea Jul 3, 2025
79a6b74
avoid core
mydea Jul 3, 2025
b4b6ad8
fix angular tests
mydea Jul 3, 2025
043fe13
fix test
mydea Jul 3, 2025
fef1966
fix test
mydea Jul 3, 2025
65a6c9f
remove overrides
mydea Jul 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -920,19 +920,23 @@ jobs:
env:
E2E_TEST_PUBLISH_SCRIPT_NODE_VERSION: ${{ steps.versions.outputs.node }}

- name: Copy to temp
run: yarn ci:copy-to-temp ./test-applications/${{ matrix.test-application }} ${{ runner.temp }}/test-application
working-directory: dev-packages/e2e-tests

- name: Build E2E app
working-directory: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
working-directory: ${{ runner.temp }}/test-application
timeout-minutes: 7
run: pnpm ${{ matrix.build-command || 'test:build' }}

- name: Install Playwright
uses: ./.github/actions/install-playwright
with:
browsers: chromium
cwd: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
cwd: ${{ runner.temp }}/test-application

- name: Run E2E test
working-directory: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
working-directory: ${{ runner.temp }}/test-application
timeout-minutes: 10
run: pnpm test:assert

Expand All @@ -941,7 +945,7 @@ jobs:
if: failure()
with:
name: playwright-traces-job_e2e_playwright_tests-${{ matrix.test-application}}
path: dev-packages/e2e-tests/test-applications/${{ matrix.test-application}}/test-results
path: ${{ runner.temp }}/test-application/test-results
overwrite: true
retention-days: 7

Expand All @@ -955,7 +959,7 @@ jobs:
if: always()
with:
name: E2E Test Dump (${{ matrix.label || matrix.test-application }})
path: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}/event-dumps
path: ${{ runner.temp }}/test-application/event-dumps
overwrite: true
retention-days: 7
if-no-files-found: ignore
Expand Down Expand Up @@ -1037,19 +1041,23 @@ jobs:
env:
E2E_TEST_PUBLISH_SCRIPT_NODE_VERSION: ${{ steps.versions.outputs.node }}

- name: Copy to temp
run: yarn ci:copy-to-temp ./test-applications/${{ matrix.test-application }} ${{ runner.temp }}/test-application
working-directory: dev-packages/e2e-tests

- name: Build E2E app
working-directory: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
working-directory: ${{ runner.temp }}/test-application
timeout-minutes: 7
run: pnpm ${{ matrix.build-command || 'test:build' }}

- name: Install Playwright
uses: ./.github/actions/install-playwright
with:
browsers: chromium
cwd: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
cwd: ${{ runner.temp }}/test-application

- name: Run E2E test
working-directory: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
working-directory: ${{ runner.temp }}/test-application
timeout-minutes: 10
run: pnpm ${{ matrix.assert-command || 'test:assert' }}

Expand All @@ -1063,20 +1071,19 @@ jobs:
if: always()
with:
name: E2E Test Dump (${{ matrix.label || matrix.test-application }})
path: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}/event-dumps
path: ${{ runner.temp }}/test-application/event-dumps
overwrite: true
retention-days: 7
if-no-files-found: ignore

- name: Deploy Astro to Cloudflare
uses: cloudflare/pages-action@v1
uses: cloudflare/wrangler-action@v3
if: matrix.test-application == 'cloudflare-astro'
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: ${{ secrets.CLOUDFLARE_PROJECT_NAME }}
directory: dist
workingDirectory: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
command: pages deploy dist --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }}
workingDirectory: ${{ runner.temp }}/test-application

job_required_jobs_passed:
name: All required jobs passed or were skipped
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,23 @@ jobs:
env:
E2E_TEST_PUBLISH_SCRIPT_NODE_VERSION: ${{ steps.versions.outputs.node }}

- name: Copy to temp
run: yarn ci:copy-to-temp ./test-applications/${{ matrix.test-application }} ${{ runner.temp }}/test-application
working-directory: dev-packages/e2e-tests

- name: Build E2E app
working-directory: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
working-directory: ${{ runner.temp }}/test-application
timeout-minutes: 7
run: yarn ${{ matrix.build-command }}

- name: Install Playwright
uses: ./.github/actions/install-playwright
with:
browsers: chromium
cwd: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
cwd: ${{ runner.temp }}/test-application

- name: Run E2E test
working-directory: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}
working-directory: ${{ runner.temp }}/test-application
timeout-minutes: 15
run: yarn test:assert

Expand Down
19 changes: 19 additions & 0 deletions dev-packages/e2e-tests/ciCopyToTemp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* eslint-disable no-console */

import { copyToTemp } from './lib/copyToTemp';

async function run(): Promise<void> {
const originalPath = process.argv[2];
const tmpDirPath = process.argv[3];

if (!originalPath || !tmpDirPath) {
throw new Error('Original path and tmp dir path are required');
}

console.log(`Copying ${originalPath} to ${tmpDirPath}...`);

await copyToTemp(originalPath, tmpDirPath);
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises
run();
63 changes: 63 additions & 0 deletions dev-packages/e2e-tests/lib/copyToTemp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* eslint-disable no-console */
import { readFileSync, writeFileSync } from 'fs';
import { cp } from 'fs/promises';
import { join } from 'path';

export async function copyToTemp(originalPath: string, tmpDirPath: string): Promise<void> {
// copy files to tmp dir
await cp(originalPath, tmpDirPath, { recursive: true });

fixPackageJson(tmpDirPath);
}

function fixPackageJson(cwd: string): void {
const packageJsonPath = join(cwd, 'package.json');
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
volta?: Record<string, unknown>;
};

// 1. Fix file dependencies
if (packageJson.dependencies) {
fixFileLinkDependencies(packageJson.dependencies);
}
if (packageJson.devDependencies) {
fixFileLinkDependencies(packageJson.devDependencies);
}

// 2. Fix volta extends
if (!packageJson.volta) {
throw new Error('No volta config found, please provide one!');
}

if (typeof packageJson.volta.extends === 'string') {
const extendsPath = packageJson.volta.extends;
// We add a virtual dir to ensure that the relative depth is consistent
// dirPath is relative to ./../test-applications/xxx
const newPath = join(__dirname, 'virtual-dir/', extendsPath);
packageJson.volta.extends = newPath;
console.log(`Fixed volta.extends to ${newPath}`);
} else {
console.log('No volta.extends found');
}

writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
}

function fixFileLinkDependencies(dependencyObj: Record<string, string>): boolean {
for (const [key, value] of Object.entries(dependencyObj)) {
if (value.startsWith('link:')) {
const dirPath = value.replace('link:', '');

// We add a virtual dir to ensure that the relative depth is consistent
// dirPath is relative to ./../test-applications/xxx
const newPath = join(__dirname, 'virtual-dir/', dirPath);

dependencyObj[key] = `link:${newPath}`;
console.log(`Fixed ${key} dependency to ${newPath}`);
}
}

return false;
}
3 changes: 2 additions & 1 deletion dev-packages/e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"clean": "rimraf tmp node_modules && yarn clean:test-applications && yarn clean:pnpm",
"ci:build-matrix": "ts-node ./lib/getTestMatrix.ts",
"ci:build-matrix-optional": "ts-node ./lib/getTestMatrix.ts --optional=true",
"clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.nuxt,.sveltekit,.react-router,.astro,.output,pnpm-lock.yaml,.last-run.json,test-results}",
"ci:copy-to-temp": "ts-node ./ciCopyToTemp.ts",
"clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.nuxt,.sveltekit,.react-router,.astro,.output,pnpm-lock.yaml,.last-run.json,test-results,.angular,event-dumps}",
"clean:pnpm": "pnpm store prune"
},
"devDependencies": {
Expand Down
18 changes: 14 additions & 4 deletions dev-packages/e2e-tests/run.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
/* eslint-disable no-console */
import { spawn } from 'child_process';
import * as dotenv from 'dotenv';
import { mkdtemp, rm } from 'fs/promises';
import { sync as globSync } from 'glob';
import { resolve } from 'path';
import { tmpdir } from 'os';
import { join, resolve } from 'path';
import { copyToTemp } from './lib/copyToTemp';
import { registrySetup } from './registrySetup';

const DEFAULT_DSN = 'https://username@domain/123';
Expand Down Expand Up @@ -39,7 +42,7 @@ async function run(): Promise<void> {
dotenv.config();

// Allow to run a single app only via `yarn test:run <app-name>`
const appName = process.argv[2];
const appName = process.argv[2] || '';

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

Expand Down Expand Up @@ -74,13 +77,20 @@ async function run(): Promise<void> {
console.log('');

for (const testAppPath of testAppPaths) {
const cwd = resolve('test-applications', testAppPath);
const originalPath = resolve('test-applications', testAppPath);
const tmpDirPath = await mkdtemp(join(tmpdir(), `sentry-e2e-tests-${appName}-`));

console.log(`Building ${testAppPath}...`);
await copyToTemp(originalPath, tmpDirPath);
const cwd = tmpDirPath;

console.log(`Building ${testAppPath} in ${tmpDirPath}...`);
await asyncExec('pnpm test:build', { env, cwd });

console.log(`Testing ${testAppPath}...`);
await asyncExec('pnpm test:assert', { env, cwd });

// clean up (although this is tmp, still nice to do)
await rm(tmpDirPath, { recursive: true });
}
} catch (error) {
console.error(error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"ng": "ng",
"dev": "ng serve",
"proxy": "node start-event-proxy.mjs",
"preview": "http-server dist/angular-17/browser --port 8080",
"preview": "http-server dist/angular-17/browser --port 8080 --silent",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "playwright test",
Expand All @@ -31,6 +31,7 @@
"devDependencies": {
"@playwright/test": "~1.50.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"@sentry/core": "latest || *",
"@angular-devkit/build-angular": "^17.1.1",
"@angular/cli": "^17.1.1",
"@angular/compiler-cli": "^17.1.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';
// Cannot use @sentry/angular here due to build stuff
import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';

test('sends a pageload transaction with a parameterized URL', async ({ page }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"ng": "ng",
"dev": "ng serve",
"proxy": "node start-event-proxy.mjs",
"preview": "http-server dist/angular-18/browser --port 8080",
"preview": "http-server dist/angular-18/browser --port 8080 --silent",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "playwright test",
Expand All @@ -31,6 +31,7 @@
"devDependencies": {
"@playwright/test": "~1.50.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"@sentry/core": "latest || *",
"@angular-devkit/build-angular": "^18.0.0",
"@angular/cli": "^18.0.0",
"@angular/compiler-cli": "^18.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';
// Cannot use @sentry/angular here due to build stuff
import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';

test('sends a pageload transaction with a parameterized URL', async ({ page }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"ng": "ng",
"dev": "ng serve",
"proxy": "node start-event-proxy.mjs",
"preview": "http-server dist/angular-19/browser --port 8080",
"preview": "http-server dist/angular-19/browser --port 8080 --silent",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "playwright test",
Expand Down Expand Up @@ -34,6 +34,7 @@
"@angular/compiler-cli": "^19.0.0",
"@playwright/test": "~1.50.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"@sentry/core": "latest || *",
"@types/jasmine": "~5.1.0",
"http-server": "^14.1.1",
"jasmine-core": "~5.4.0",
Expand All @@ -43,5 +44,8 @@
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.6.2"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';
// Cannot use @sentry/angular here due to build stuff
import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';

test('sends a pageload transaction with a parameterized URL', async ({ page }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"ng": "ng",
"dev": "ng serve",
"proxy": "node start-event-proxy.mjs",
"preview": "http-server dist/angular-20/browser --port 8080",
"preview": "http-server dist/angular-20/browser --port 8080 --silent",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "playwright test",
Expand Down Expand Up @@ -35,6 +35,7 @@
"@angular/compiler-cli": "^20.0.0",
"@playwright/test": "~1.50.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"@sentry/core": "latest || *",
"@types/jasmine": "~5.1.0",
"http-server": "^14.1.1",
"jasmine-core": "~5.4.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';
// Cannot use @sentry/angular here due to build stuff
import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';

test('sends a pageload transaction with a parameterized URL', async ({ page }) => {
Expand Down
3 changes: 3 additions & 0 deletions dev-packages/e2e-tests/test-applications/astro-4/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,8 @@
},
"devDependencies": {
"@astrojs/internal-helpers": "^0.4.1"
},
"volta": {
"extends": "../../package.json"
}
}
3 changes: 3 additions & 0 deletions dev-packages/e2e-tests/test-applications/astro-5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,8 @@
"overrides": {
"esbuild": "0.24.0"
}
},
"volta": {
"extends": "../../package.json"
}
}
Loading
Loading