From 71274df0917d79c6fff54720a3749d30a4e28f6b Mon Sep 17 00:00:00 2001 From: Carolina Gonzalez Date: Fri, 14 Nov 2025 11:25:39 -0500 Subject: [PATCH 1/2] fix(e2e): ensure tests run in dashboard and correct org when not in CI --- .github/workflows/e2e.yml | 2 +- apps/kitchensink-react/playwright.config.ts | 9 ++++++++- apps/kitchensink-react/sanity.cli.ts | 3 ++- apps/kitchensink-react/vite.config.mjs | 3 ++- package.json | 2 ++ packages/@repo/e2e/README.md | 9 +++++---- packages/@repo/e2e/src/helpers/pageContext.ts | 5 ++++- packages/@repo/e2e/src/index.ts | 14 ++++++-------- packages/@repo/e2e/src/setup/auth.setup.ts | 7 +++---- turbo.json | 4 ++-- 10 files changed, 35 insertions(+), 23 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 0191d3b9b..47e4fc7dc 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -62,7 +62,7 @@ jobs: strategy: fail-fast: false matrix: - browser: [chromium, firefox, webkit, dashboard-chromium] + browser: [chromium, firefox, webkit] # Shared env required by the SDK E2E helpers. Configure these in the repo → Settings → Secrets / Variables env: diff --git a/apps/kitchensink-react/playwright.config.ts b/apps/kitchensink-react/playwright.config.ts index 8130f6e39..ca027d6f6 100644 --- a/apps/kitchensink-react/playwright.config.ts +++ b/apps/kitchensink-react/playwright.config.ts @@ -1,5 +1,8 @@ import {createPlaywrightConfig} from '@repo/e2e' +const isWebkitProject = + process.argv.includes('--project=webkit') || process.argv.some((arg) => arg.includes('webkit')) + export default createPlaywrightConfig({ testDir: './e2e', /* Run your local dev server before starting the tests */ @@ -7,9 +10,13 @@ export default createPlaywrightConfig({ ? {} // In CI, don't start a webServer since it's started manually : { webServer: { - command: 'pnpm dev --mode e2e', + command: isWebkitProject ? 'pnpm exec vite --port 3333' : 'pnpm dev', reuseExistingServer: true, stdout: 'pipe', + env: { + // Pass e2e organization ID to sanity dev + SDK_E2E_ORGANIZATION_ID: process.env['SDK_E2E_ORGANIZATION_ID'] || '', + }, }, }), }) diff --git a/apps/kitchensink-react/sanity.cli.ts b/apps/kitchensink-react/sanity.cli.ts index e2c9a7fc4..c3322343c 100644 --- a/apps/kitchensink-react/sanity.cli.ts +++ b/apps/kitchensink-react/sanity.cli.ts @@ -9,7 +9,8 @@ import { export default defineCliConfig({ app: { - organizationId: 'oblZgbTFj', + // Use e2e organization ID if provided, otherwise use dev organization ID + organizationId: process.env['SDK_E2E_ORGANIZATION_ID'] || 'oblZgbTFj', entry: './src/App.tsx', id: 'wkyoigmzawwnnwx458zgoh46', }, diff --git a/apps/kitchensink-react/vite.config.mjs b/apps/kitchensink-react/vite.config.mjs index a39204f46..e7e922d21 100644 --- a/apps/kitchensink-react/vite.config.mjs +++ b/apps/kitchensink-react/vite.config.mjs @@ -14,7 +14,8 @@ export default defineConfig(({mode}) => { const rootDir = resolve(process.cwd(), '../..') const env = loadEnv(mode, rootDir, '') - const isE2E = mode === 'e2e' + // Check if we're in e2e mode - either explicitly set or if SDK_E2E_ORGANIZATION_ID is present + const isE2E = mode === 'e2e' || !!process.env['SDK_E2E_ORGANIZATION_ID'] return { server: { diff --git a/package.json b/package.json index 966e198a8..4c2b7fba1 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "test:coverage": "vitest run --coverage", "test:coverage:open": "open coverage/index.html", "test:e2e": "turbo run test:e2e", + "test:e2e:dashboard": "turbo run test:e2e --filter=@sanity/kitchensink-react -- --project=chromium --project=firefox", + "test:e2e:webkit": "turbo run test:e2e --filter=@sanity/kitchensink-react -- --project=webkit", "test:watch": "vitest watch", "ts:check": "turbo run ts:check --filter='./packages/*' --filter='./apps/*'", "depcheck": "DEPCHECK=true knip", diff --git a/packages/@repo/e2e/README.md b/packages/@repo/e2e/README.md index 5c969b8cd..633f66b66 100644 --- a/packages/@repo/e2e/README.md +++ b/packages/@repo/e2e/README.md @@ -10,7 +10,7 @@ The tests expect to find the below env variables. Either define them in your she - `SDK_E2E_ORGANIZATION_ID`: We use oFvj4MZWQ internally - `SDK_E2E_USER_ID`: sdk+e2e@sanity.io - `SDK_E2E_USER_PASSWORD`: found in 1Password -- `RECAPTCHA_E2E_STAGING_KEY`: found in 1Password +- `RECAPTCHA_E2E_STAGING_KEY`: found in 1Password as "E2E staging reCAPTCHA bypass token" in Dev Secrets - `SDK_E2E_DATASET_0`=production - `SDK_E2E_DATASET_1`=testing @@ -38,18 +38,19 @@ test('can click a button', async ({page, getPageContext}) => { ## Running tests -To run E2E tests run the following commands from the root of the project +Right now, tests are split into two separate commands to make local testing easier. This is because we run our tests in the Dashboard, and Safari struggles with an iframed app in localhost. To run E2E tests run the following commands from the root of the project - Run all the tests ```sh - pnpm test:e2e + pnpm test:e2e:dashboard + pnpm test:e2e:webkit ``` - Run files that have my-spec or my-spec-2 in the file name ```sh - pnpm test:e2e -- my-spec my-spec-2 + pnpm test:e2e:dashboard -- my-spec my-spec-2 ``` - For help, run diff --git a/packages/@repo/e2e/src/helpers/pageContext.ts b/packages/@repo/e2e/src/helpers/pageContext.ts index 44fac534c..56ee01813 100644 --- a/packages/@repo/e2e/src/helpers/pageContext.ts +++ b/packages/@repo/e2e/src/helpers/pageContext.ts @@ -9,7 +9,10 @@ export type PageContext = Pick await page.goto(loginUrl.toString()) // Wait for the redirect to complete AND network to be idle - await Promise.all([page.waitForURL(config.expectedRedirectUrl)]) + await page.waitForURL(config.expectedRedirectUrl) await page.close() } @@ -68,13 +68,12 @@ setup('setup authentication', async ({browser}) => { const context = await browser.newContext() try { - // Authenticate for standalone apps + // Authenticate for standalone (webkit) await authenticateUser(context, { origin: 'http://localhost:3333', expectedRedirectUrl: 'http://localhost:3333', }) - - // Authenticate for embedded apps (Dashboard) + // Authenticate for Dashboard (other browsers) await authenticateUser(context, { origin: 'https://www.sanity.work/api/dashboard/authenticate', expectedRedirectUrl: `https://www.sanity.work/@${env.SDK_E2E_ORGANIZATION_ID}`, diff --git a/turbo.json b/turbo.json index d37caf616..6e4407fc5 100644 --- a/turbo.json +++ b/turbo.json @@ -28,8 +28,8 @@ "dependsOn": ["^build"], "outputs": ["docs/**"] }, - "check-types": { - "dependsOn": ["^check-types"] + "ts:check": { + "dependsOn": ["^ts:check"] }, "clean": {}, "cleanup": { From 666759895558656bdddf0b236c3b749c81cb41fb Mon Sep 17 00:00:00 2001 From: Carolina Gonzalez Date: Thu, 20 Nov 2025 08:02:10 -0500 Subject: [PATCH 2/2] fix: also ensure dev:e2e works --- .github/workflows/e2e.yml | 2 +- apps/kitchensink-react/playwright.config.ts | 1 - apps/kitchensink-react/vite.config.mjs | 8 ++++-- package.json | 2 +- packages/@repo/e2e/README.md | 6 ++-- turbo.json | 32 ++++----------------- 6 files changed, 18 insertions(+), 33 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 47e4fc7dc..5f4f707f1 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -113,7 +113,7 @@ jobs: - name: 🚀 Start preview server run: | cd apps/kitchensink-react - pnpm build --mode e2e && pnpm run preview --mode e2e --port 3333 & + pnpm build && pnpm run preview --port 3333 & timeout 60 bash -c 'until curl -f -s http://localhost:3333 > /dev/null; do echo "Waiting for server..."; sleep 2; done' echo "Server is ready!" diff --git a/apps/kitchensink-react/playwright.config.ts b/apps/kitchensink-react/playwright.config.ts index ca027d6f6..1ce1371b9 100644 --- a/apps/kitchensink-react/playwright.config.ts +++ b/apps/kitchensink-react/playwright.config.ts @@ -5,7 +5,6 @@ const isWebkitProject = export default createPlaywrightConfig({ testDir: './e2e', - /* Run your local dev server before starting the tests */ ...(process.env['CI'] ? {} // In CI, don't start a webServer since it's started manually : { diff --git a/apps/kitchensink-react/vite.config.mjs b/apps/kitchensink-react/vite.config.mjs index e7e922d21..29db0d500 100644 --- a/apps/kitchensink-react/vite.config.mjs +++ b/apps/kitchensink-react/vite.config.mjs @@ -14,8 +14,12 @@ export default defineConfig(({mode}) => { const rootDir = resolve(process.cwd(), '../..') const env = loadEnv(mode, rootDir, '') - // Check if we're in e2e mode - either explicitly set or if SDK_E2E_ORGANIZATION_ID is present - const isE2E = mode === 'e2e' || !!process.env['SDK_E2E_ORGANIZATION_ID'] + // This variable is usually always going to be present in the user's env files, + // but only comes into play when explicitly injected into the env. + // (`sanity dev` will otherwise ignore all env variables that don't start with `SANITY_APP_`) + // 1. Playwright explicitly injects the env variables + // 2. `pnpm dev:e2e` sets it as part of the command in the root package.json + const isE2E = !!process.env['SDK_E2E_ORGANIZATION_ID'] return { server: { diff --git a/package.json b/package.json index 4c2b7fba1..03fcbffee 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "cleanup:e2e": "turbo run cleanup --filter=@repo/e2e", "dev": "pnpm dev:kitchensink", "dev:kitchensink": "turbo run dev --filter=@sanity/kitchensink-react", - "dev:e2e": "turbo run dev --filter=@sanity/kitchensink-react -- --mode=e2e", + "dev:e2e": "SANITY_INTERNAL_ENV=staging SDK_E2E_ORGANIZATION_ID=oFvj4MZWQ turbo run dev --filter=@sanity/kitchensink-react", "deploy:kitchensink": "turbo run deploy --filter=@sanity/kitchensink-react", "format": "prettier --write --cache --ignore-unknown .", "lint": "turbo run lint -- --fix && eslint . --fix", diff --git a/packages/@repo/e2e/README.md b/packages/@repo/e2e/README.md index 633f66b66..1fb9f23df 100644 --- a/packages/@repo/e2e/README.md +++ b/packages/@repo/e2e/README.md @@ -60,7 +60,9 @@ Right now, tests are split into two separate commands to make local testing easi Other useful helper commands -- "dev:e2e": Starts the Kitchensink pointing to the E2E project and dataset. This server can be used by both you as a developer and the e2e tests at the same time for debugging purposes. +- `dev:e2e`: Starts the Kitchensink pointing to the E2E project and dataset. This server can be used by both you as a developer and the e2e tests at the same time for debugging purposes. + +NOTE: The `dev:e2e` command hardcodes the Sanity staging environment and the SDK e2e test organization as part of its command. If you'd like to run in a different target organization, you will have to temporarily change the command. For more useful commands, see the [Playwright Command Line](https://playwright.dev/docs/test-cli) documentation. @@ -70,6 +72,6 @@ You can run your tests in your editor with the help of some useful editor plugin ### Running in CI mode -These tests run in CI with a built application (rather than dev server). It also runs its tests in the Dashboard. If you'd like to replicate that, you should add the following variables to your .env.local file: +These tests run in CI with a built application (rather than dev server). It also has more workers and retries. If you'd like to replicate that, you should add the following variables to your .env.local file: - `CI`: true diff --git a/turbo.json b/turbo.json index 6e4407fc5..2f8049976 100644 --- a/turbo.json +++ b/turbo.json @@ -6,13 +6,7 @@ "PKG_VERSION", "NPM_CONFIG_PROVENANCE", "CI", - "SDK_E2E_PROJECT_ID", - "SDK_E2E_ORGANIZATION_ID", - "SDK_E2E_DATASET_0", - "SDK_E2E_DATASET_1", - "SDK_E2E_SESSION_TOKEN", - "SDK_E2E_USER_ID", - "SDK_E2E_USER_PASSWORD", + "SDK_E2E_*", "RECAPTCHA_E2E_STAGING_KEY" ], "tasks": { @@ -34,19 +28,15 @@ "clean": {}, "cleanup": { "cache": false, - "env": [ - "SDK_E2E_PROJECT_ID", - "SDK_E2E_DATASET_0", - "SDK_E2E_DATASET_1", - "SDK_E2E_SESSION_TOKEN" - ] + "env": ["SDK_E2E_*"] }, "depcheck": { "env": ["DEPCHECK"] }, "dev": { "persistent": true, - "cache": false + "cache": false, + "env": ["SANITY_INTERNAL_ENV"] }, "docs": { "dependsOn": ["^build"], @@ -55,7 +45,7 @@ "dev:e2e": { "persistent": true, "cache": false, - "env": ["SDK_E2E_PROJECT_ID", "SDK_E2E_DATASET_0", "SDK_E2E_DATASET_1"] + "env": ["SDK_E2E_*", "SANITY_INTERNAL_ENV"] }, "lint": { "cache": false @@ -72,17 +62,7 @@ }, "test:e2e": { "cache": false, - "env": [ - "SDK_E2E_PROJECT_ID", - "SDK_E2E_ORGANIZATION_ID", - "SDK_E2E_DATASET_0", - "SDK_E2E_DATASET_1", - "SDK_E2E_SESSION_TOKEN", - "NODE_ENV", - "SDK_E2E_USER_ID", - "SDK_E2E_USER_PASSWORD", - "RECAPTCHA_E2E_STAGING_KEY" - ], + "env": ["SDK_E2E_*", "NODE_ENV", "RECAPTCHA_E2E_STAGING_KEY"], "dependsOn": ["@repo/e2e#build"], "outputs": ["e2e/test-results/**", "e2e/test-report/**"] },