diff --git a/packages/e2e/setup/env.ts b/packages/e2e/setup/env.ts index 4ed7602724e..e58e4b37b24 100644 --- a/packages/e2e/setup/env.ts +++ b/packages/e2e/setup/env.ts @@ -116,6 +116,33 @@ export function requireEnv(env: E2EEnv, ...keys: (keyof Pick = { + deploy1: 'dep1', + deploy2: 'dep2', + scaffold: 'scaf', + 'ext-only': 'exto', + 'ext-gen': 'extg', + 'hot-reload': 'hrel', + 'hot-create': 'hcrt', + 'hot-delete': 'hdel', + 'multi-cfg': 'mcfg', + 'mcfg-def': 'mdef', + 'toml-deploy': 'tdep', + 'toml-dev': 'tdev', +} + +/** + * Generate a short E2E app name that can be clustered by GitHub Actions run. + */ +export function e2eAppName(prefix: string): string { + const runId = process.env.GITHUB_RUN_ID + const runAttempt = process.env.GITHUB_RUN_ATTEMPT ?? '1' + const runSegment = runId ? `r${BigInt(runId).toString(36)}a${runAttempt}` : 'local' + const timestampSegment = Date.now().toString(36) + + return `E2E-${E2E_APP_PREFIXES[prefix] ?? prefix}-${runSegment}-${timestampSegment}` +} + /** * Worker-scoped fixture providing environment configuration. * Env vars are optional — tests that need them should call requireEnv(). diff --git a/packages/e2e/tests/app-deploy.spec.ts b/packages/e2e/tests/app-deploy.spec.ts index 1c316fcd386..7243493edd5 100644 --- a/packages/e2e/tests/app-deploy.spec.ts +++ b/packages/e2e/tests/app-deploy.spec.ts @@ -1,7 +1,7 @@ import {appTestFixture as test, createApp, deployApp, versionsList, configLink} from '../setup/app.js' import {teardownAll} from '../setup/teardown.js' import {TEST_TIMEOUT} from '../setup/constants.js' -import {requireEnv} from '../setup/env.js' +import {e2eAppName, requireEnv} from '../setup/env.js' import {stripAnsi} from '../helpers/strip-ansi.js' import {expect} from '@playwright/test' import * as fs from 'fs' @@ -79,8 +79,8 @@ test.describe('App deploy', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-deploy1-${Date.now()}` - const secondaryAppName = `E2E-deploy2-${Date.now()}` + const appName = e2eAppName('deploy1') + const secondaryAppName = e2eAppName('deploy2') let primaryAppUrl: string | undefined let secondaryAppUrl: string | undefined diff --git a/packages/e2e/tests/app-dev-server.spec.ts b/packages/e2e/tests/app-dev-server.spec.ts index ae8305debb9..41f1991b038 100644 --- a/packages/e2e/tests/app-dev-server.spec.ts +++ b/packages/e2e/tests/app-dev-server.spec.ts @@ -1,7 +1,7 @@ import {createApp} from '../setup/app.js' import {teardownAll} from '../setup/teardown.js' import {CLI_TIMEOUT, TEST_TIMEOUT} from '../setup/constants.js' -import {requireEnv} from '../setup/env.js' +import {e2eAppName, requireEnv} from '../setup/env.js' import {storeTestFixture as test} from '../setup/store.js' import {expect} from '@playwright/test' import * as fs from 'fs' @@ -13,7 +13,7 @@ test.describe('App dev server', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-dev-${Date.now()}` + const appName = e2eAppName('dev') try { // Step 1: Create an extension-only app (no scopes needed) diff --git a/packages/e2e/tests/app-scaffold.spec.ts b/packages/e2e/tests/app-scaffold.spec.ts index a53d9d66229..31270c39a4b 100644 --- a/packages/e2e/tests/app-scaffold.spec.ts +++ b/packages/e2e/tests/app-scaffold.spec.ts @@ -2,7 +2,7 @@ import {appTestFixture as test, createApp, buildApp, generateExtension} from '../setup/app.js' import {teardownAll} from '../setup/teardown.js' import {TEST_TIMEOUT} from '../setup/constants.js' -import {requireEnv} from '../setup/env.js' +import {e2eAppName, requireEnv} from '../setup/env.js' import {expect} from '@playwright/test' import * as fs from 'fs' import * as path from 'path' @@ -13,7 +13,7 @@ test.describe('App scaffold', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-scaffold-${Date.now()}` + const appName = e2eAppName('scaffold') try { // Step 1: Create a new app from the react-router template @@ -63,7 +63,7 @@ test.describe('App scaffold', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-ext-only-${Date.now()}` + const appName = e2eAppName('ext-only') try { const initResult = await createApp({ @@ -101,7 +101,7 @@ test.describe('App scaffold', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-ext-gen-${Date.now()}` + const appName = e2eAppName('ext-gen') try { const initResult = await createApp({ diff --git a/packages/e2e/tests/dev-hot-reload.spec.ts b/packages/e2e/tests/dev-hot-reload.spec.ts index b16c9c6d5b3..c67f354cd7b 100644 --- a/packages/e2e/tests/dev-hot-reload.spec.ts +++ b/packages/e2e/tests/dev-hot-reload.spec.ts @@ -3,7 +3,7 @@ import {createApp, injectFixtureToml} from '../setup/app.js' import {teardownAll} from '../setup/teardown.js' import {CLI_TIMEOUT, TEST_TIMEOUT} from '../setup/constants.js' -import {requireEnv} from '../setup/env.js' +import {e2eAppName, requireEnv} from '../setup/env.js' import {storeTestFixture as test} from '../setup/store.js' import {updateTomlValues} from '@shopify/toml-patch' import {expect} from '@playwright/test' @@ -44,7 +44,7 @@ test.describe('Dev hot reload', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-hot-reload-${Date.now()}` + const appName = e2eAppName('hot-reload') try { const initResult = await createApp({cli, parentDir, name: appName, template: 'none', orgId: env.orgId}) @@ -102,7 +102,7 @@ test.describe('Dev hot reload', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-hot-create-${Date.now()}` + const appName = e2eAppName('hot-create') try { const initResult = await createApp({cli, parentDir, name: appName, template: 'none', orgId: env.orgId}) @@ -154,7 +154,7 @@ test.describe('Dev hot reload', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-hot-delete-${Date.now()}` + const appName = e2eAppName('hot-delete') try { const initResult = await createApp({cli, parentDir, name: appName, template: 'none', orgId: env.orgId}) diff --git a/packages/e2e/tests/multi-config-dev.spec.ts b/packages/e2e/tests/multi-config-dev.spec.ts index 5d2810c8d5b..5c2316cf443 100644 --- a/packages/e2e/tests/multi-config-dev.spec.ts +++ b/packages/e2e/tests/multi-config-dev.spec.ts @@ -3,7 +3,7 @@ import {createApp, extractClientId, injectFixtureToml} from '../setup/app.js' import {teardownAll} from '../setup/teardown.js' import {CLI_TIMEOUT, TEST_TIMEOUT} from '../setup/constants.js' -import {requireEnv} from '../setup/env.js' +import {e2eAppName, requireEnv} from '../setup/env.js' import {storeTestFixture as test} from '../setup/store.js' import {expect} from '@playwright/test' import * as fs from 'fs' @@ -19,7 +19,7 @@ test.describe('Multi-config dev', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-multi-cfg-${Date.now()}` + const appName = e2eAppName('multi-cfg') try { const initResult = await createApp({cli, parentDir, name: appName, template: 'none', orgId: env.orgId}) @@ -106,7 +106,7 @@ extensions_summary = "E2E staging app extensions" requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-mcfg-def-${Date.now()}` + const appName = e2eAppName('mcfg-def') try { const initResult = await createApp({cli, parentDir, name: appName, template: 'none', orgId: env.orgId}) diff --git a/packages/e2e/tests/toml-config.spec.ts b/packages/e2e/tests/toml-config.spec.ts index e20fce43cf1..79189b99822 100644 --- a/packages/e2e/tests/toml-config.spec.ts +++ b/packages/e2e/tests/toml-config.spec.ts @@ -3,7 +3,7 @@ import {createApp, injectFixtureToml} from '../setup/app.js' import {teardownAll} from '../setup/teardown.js' import {CLI_TIMEOUT, TEST_TIMEOUT} from '../setup/constants.js' -import {requireEnv} from '../setup/env.js' +import {e2eAppName, requireEnv} from '../setup/env.js' import {storeTestFixture as test} from '../setup/store.js' import {expect} from '@playwright/test' import * as fs from 'fs' @@ -19,7 +19,7 @@ test.describe('TOML config regression', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-toml-deploy-${Date.now()}` + const appName = e2eAppName('toml-deploy') try { const initResult = await createApp({cli, parentDir, name: appName, template: 'none', orgId: env.orgId}) @@ -53,7 +53,7 @@ test.describe('TOML config regression', () => { requireEnv(env, 'orgId') const parentDir = fs.mkdtempSync(path.join(env.tempDir, 'app-')) - const appName = `E2E-toml-dev-${Date.now()}` + const appName = e2eAppName('toml-dev') try { const initResult = await createApp({cli, parentDir, name: appName, template: 'none', orgId: env.orgId})