Skip to content

Commit 9a121fe

Browse files
authored
chore(repo): Introduce integration test for vite with sdk-node (clerk#1921)
* feat(repo): Add integration test for express + vite * feat(repo): Enable express tests in CICD * fix(repo): Copy integration tests to OS temp path This change will help us avoid accidentally using top-level node_modules/ from the current monorepo and will allow us to run tests isolated from the monorepo related dependencies. We had to use a folder outside the monorepo for the integration tests to avoid having the npm module resolution algorithm find unrelated dependencies. * fix(repo): Exit integration tests on application error exit code * fix(repo): Link local clerk packages when version is missing * fix(repo): Fix `npm run nuke` yalc cleanup
1 parent dd57030 commit 9a121fe

26 files changed

Lines changed: 322 additions & 24 deletions

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ jobs:
132132

133133
strategy:
134134
matrix:
135-
test-name: [ 'generic', 'nextjs' ]
135+
test-name: [ 'generic', 'nextjs', 'express' ]
136136

137137
steps:
138138
- name: Checkout Repo

integration/constants.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/* eslint-disable turbo/no-undeclared-env-vars */
2+
import * as os from 'node:os';
23
import * as path from 'node:path';
34

45
export const constants = {
5-
TMP_DIR: path.join(process.cwd(), '.temp_integration'),
6-
APPS_STATE_FILE: path.join(process.cwd(), '.temp_integration', 'state.json'),
6+
TMP_DIR: path.join(os.tmpdir(), '.temp_integration'),
7+
APPS_STATE_FILE: path.join(os.tmpdir(), '.temp_integration', 'state.json'),
78
/**
89
* A URL to a running app that will be used to run the tests against.
910
* This is usually used when running the app has been started manually,

integration/models/application.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@ export const application = (config: ApplicationConfig, appDirPath: string, appDi
6161
stderr: opts.detached ? fs.openSync(stderrFilePath, 'a') : undefined,
6262
log: opts.detached ? undefined : log,
6363
});
64-
// TODO @dimitris: Fail early if server exits
65-
// const shouldRetry = () => proc.exitCode !== 0 && proc.exitCode !== null;
66-
await waitForServer(serverUrl, { log, maxAttempts: Infinity });
64+
const shouldExit = () => !!proc.exitCode && proc.exitCode !== 0;
65+
await waitForServer(serverUrl, { log, maxAttempts: Infinity, shouldExit });
6766
log(`Server started at ${serverUrl}, pid: ${proc.pid}`);
6867
cleanupFns.push(() => awaitableTreekill(proc.pid, 'SIGKILL'));
6968
state.serverUrl = serverUrl;
@@ -85,7 +84,6 @@ export const application = (config: ApplicationConfig, appDirPath: string, appDi
8584
serve: async (opts: { port?: number; manualStart?: boolean } = {}) => {
8685
const port = opts.port || (await getPort());
8786
const serverUrl = `http://localhost:${port}`;
88-
const log = logger.child({ prefix: 'serve' }).info;
8987
// If this is ever used as a background process, we need to make sure
9088
// it's not using the log function. See the dev() method above
9189
const proc = run(scripts.serve, { cwd: appDirPath, env: { PORT: port.toString() } });

integration/models/applicationConfig.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as path from 'node:path';
22

3+
import { constants } from '../constants';
34
import { createLogger, fs } from '../scripts';
45
import { application } from './application.js';
56
import type { EnvironmentConfig } from './environment';
@@ -62,10 +63,9 @@ export const applicationConfig = () => {
6263
commit: async (opts?: { stableHash?: string }) => {
6364
const { stableHash } = opts || {};
6465
logger.info(`Creating project "${name}"`);
65-
const TMP_DIR = path.join(process.cwd(), '.temp_integration');
6666

6767
const appDirName = stableHash || `${name}__${Date.now()}__${hash()}`;
68-
const appDirPath = path.resolve(TMP_DIR, appDirName);
68+
const appDirPath = path.resolve(constants.TMP_DIR, appDirName);
6969

7070
// Copy template files
7171
for (const template of templates) {

integration/presets/express.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { constants } from '../constants';
2+
import { applicationConfig } from '../models/applicationConfig';
3+
import { templates } from '../templates';
4+
5+
const clerkNodeLocal = `file:${process.cwd()}/packages/sdk-node`;
6+
const vite = applicationConfig()
7+
.setName('express-vite')
8+
.useTemplate(templates['express-vite'])
9+
.setEnvFormatter('public', key => `VITE_${key}`)
10+
.addScript('setup', 'npm i --prefer-offline')
11+
.addScript('dev', 'npm run dev')
12+
.addScript('build', 'npm run build')
13+
.addScript('serve', 'npm run start')
14+
.addDependency('@clerk/clerk-sdk-node', constants.E2E_CLERK_VERSION || clerkNodeLocal);
15+
16+
export const express = {
17+
vite,
18+
} as const;

integration/presets/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { envs } from './envs';
2+
import { express } from './express';
23
import { createLongRunningApps } from './longRunningApps';
34
import { next } from './next';
45
import { react } from './react';
56
import { remix } from './remix';
67

78
export const appConfigs = {
89
envs,
10+
express,
911
longRunningApps: createLongRunningApps(),
1012
next,
1113
react,

integration/presets/longRunningApps.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { LongRunningApplication } from '../models/longRunningApplication';
22
import { longRunningApplication } from '../models/longRunningApplication';
33
import { envs } from './envs';
4+
import { express } from './express';
45
import { next } from './next';
56
import { react } from './react';
67
import { remix } from './remix';
@@ -12,6 +13,7 @@ import { remix } from './remix';
1213
*/
1314
export const createLongRunningApps = () => {
1415
const configs = [
16+
{ id: 'express.vite.withEmailCodes', config: express.vite, env: envs.withEmailCodes },
1517
{ id: 'react.vite.withEmailCodes', config: react.vite, env: envs.withEmailCodes },
1618
{ id: 'react.vite.withEmailLinks', config: react.vite, env: envs.withEmailLinks },
1719
{ id: 'remix.node.withEmailCodes', config: remix.remixNode, env: envs.withEmailCodes },

integration/presets/next.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { constants } from '../constants';
22
import { applicationConfig } from '../models/applicationConfig.js';
33
import { templates } from '../templates/index.js';
44

5+
const clerkNextjsLocal = `file:${process.cwd()}/packages/nextjs`;
56
const appRouter = applicationConfig()
67
.setName('next-app-router')
78
.useTemplate(templates['next-app-router'])
@@ -11,7 +12,7 @@ const appRouter = applicationConfig()
1112
.addScript('build', 'npm run build')
1213
.addScript('serve', 'npm run start')
1314
.addDependency('next', constants.E2E_NEXTJS_VERSION)
14-
.addDependency('@clerk/nextjs', constants.E2E_CLERK_VERSION);
15+
.addDependency('@clerk/nextjs', constants.E2E_CLERK_VERSION || clerkNextjsLocal);
1516

1617
const appRouterTurbo = appRouter
1718
.clone()

integration/presets/react.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { constants } from '../constants';
22
import { applicationConfig } from '../models/applicationConfig';
33
import { templates } from '../templates';
44

5+
const clerkReactLocal = `file:${process.cwd()}/packages/react`;
6+
const clerkThemesLocal = `file:${process.cwd()}/packages/themes`;
7+
58
const cra = applicationConfig()
69
.setName('react-cra')
710
.useTemplate(templates['react-cra'])
@@ -10,8 +13,8 @@ const cra = applicationConfig()
1013
.addScript('dev', 'npm run start')
1114
.addScript('build', 'npm run build')
1215
.addScript('serve', 'npm run start')
13-
.addDependency('@clerk/clerk-react', constants.E2E_CLERK_VERSION)
14-
.addDependency('@clerk/themes', constants.E2E_CLERK_VERSION);
16+
.addDependency('@clerk/clerk-react', constants.E2E_CLERK_VERSION || clerkReactLocal)
17+
.addDependency('@clerk/themes', constants.E2E_CLERK_VERSION || clerkThemesLocal);
1518

1619
const vite = cra
1720
.clone()

integration/presets/remix.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1+
import { constants } from '../constants';
12
import { applicationConfig } from '../models/applicationConfig.js';
23
import { templates } from '../templates/index.js';
34

5+
const clerkRemixLocal = `file:${process.cwd()}/packages/remix`;
46
const remixNode = applicationConfig()
57
.setName('remix-node')
68
.useTemplate(templates['remix-node'])
79
.setEnvFormatter('public', key => `${key}`)
810
.addScript('setup', 'npm i --prefer-offline')
911
.addScript('dev', 'npm run dev')
10-
.addScript('build', 'npm run build');
11-
// .addScript('serve', 'npm run start');
12+
.addScript('build', 'npm run build')
13+
.addScript('serve', 'npm run start')
14+
.addDependency('@clerk/remix', constants.E2E_CLERK_VERSION || clerkRemixLocal);
1215

1316
export const remix = {
1417
remixNode,

0 commit comments

Comments
 (0)