test(e2e): legacy customer account flow e2e tests #8893
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 🚀 CI | |
| on: | |
| pull_request: | |
| push: | |
| branches: | |
| - main | |
| jobs: | |
| check-node-version: | |
| name: 🔧 Node version sync | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 1 | |
| steps: | |
| - name: ⬇️ Checkout repo | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Validate .nvmrc matches dev.yml | |
| run: | | |
| NVMRC_VERSION=$(tr -d 'v\n' < .nvmrc) | |
| # Expects dev.yml format: | |
| # - node: | |
| # version: vXX.YY.ZZ | |
| DEV_YML_RAW=$(grep -A3 '^\s*- node:' dev.yml | grep 'version:' | grep -oE 'v?[0-9]+\.[0-9]+\.[0-9]+' | head -1) | |
| DEV_YML_VERSION=$(echo "$DEV_YML_RAW" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+') | |
| if [ -z "$NVMRC_VERSION" ]; then | |
| echo "::error::Could not parse version from .nvmrc" | |
| echo " .nvmrc contents: '$(cat .nvmrc)'" | |
| echo " dev.yml raw: '$DEV_YML_RAW'" | |
| exit 1 | |
| fi | |
| if [ -z "$DEV_YML_RAW" ]; then | |
| echo "::error::Could not find node version in dev.yml" | |
| echo " .nvmrc version: '$NVMRC_VERSION'" | |
| echo " Searched for: '- node:' followed by 'version:' line in dev.yml" | |
| echo " Relevant dev.yml lines:" | |
| grep -A3 'node:' dev.yml | sed 's/^/ /' | |
| exit 1 | |
| fi | |
| if [ -z "$DEV_YML_VERSION" ]; then | |
| echo "::error::dev.yml must specify a FULL Node version (X.Y.Z format)" | |
| echo "" | |
| echo "Found: '$DEV_YML_RAW'" | |
| echo ".nvmrc version: '$NVMRC_VERSION'" | |
| echo "Expected format: 'vX.Y.Z' (e.g., 'v20.19.5')" | |
| echo "" | |
| echo "The Shopify 'dev' tool requires a specific installable version," | |
| echo "not just a major version like 'v20'. Nix needs the exact version" | |
| echo "to fetch from its package cache." | |
| exit 1 | |
| fi | |
| NVMRC_MAJOR=$(echo "$NVMRC_VERSION" | cut -d. -f1) | |
| DEV_YML_MAJOR=$(echo "$DEV_YML_VERSION" | cut -d. -f1) | |
| if [ "$NVMRC_MAJOR" != "$DEV_YML_MAJOR" ]; then | |
| echo "::error::Node version mismatch between .nvmrc and dev.yml" | |
| echo "" | |
| echo "┌─────────────────────────────────────────────────────────────────┐" | |
| echo "│ IMPORTANT: This is NOT a configuration oversight! │" | |
| echo "│ │" | |
| echo "│ The Shopify 'dev' tool CANNOT read from .nvmrc - it requires │" | |
| echo "│ an explicit version. These files serve different tools: │" | |
| echo "│ • .nvmrc → used by nvm (flexible major version like 'v20') │" | |
| echo "│ • dev.yml → used by dev tool (needs exact version 'v20.x.x') │" | |
| echo "│ │" | |
| echo "│ Both files MUST be updated TOGETHER when changing Node version.│" | |
| echo "└─────────────────────────────────────────────────────────────────┘" | |
| echo "" | |
| echo "Current state:" | |
| echo " .nvmrc major version: v$NVMRC_MAJOR" | |
| echo " dev.yml major version: v$DEV_YML_MAJOR" | |
| echo "" | |
| echo "To fix: Update both files to use the same Node major version." | |
| exit 1 | |
| fi | |
| echo "✅ Node versions in sync (major version: v$NVMRC_MAJOR)" | |
| lint: | |
| name: ⬣ ESLint | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| concurrency: | |
| group: ci-lint-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: ⬇️ Checkout repo | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: 📦 Setup pnpm | |
| uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 | |
| with: | |
| run_install: false | |
| - name: ⎔ Setup node | |
| uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 | |
| with: | |
| node-version: '22' | |
| cache: 'pnpm' | |
| cache-dependency-path: 'pnpm-lock.yaml' | |
| - name: 📥 Install dependencies | |
| run: | | |
| pnpm install --frozen-lockfile | |
| - name: 🔬 Lint | |
| run: pnpm run lint | |
| format: | |
| name: ⬣ Prettier | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| concurrency: | |
| group: ci-format-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: ⬇️ Checkout repo | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: 📦 Setup pnpm | |
| uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 | |
| with: | |
| run_install: false | |
| - name: ⎔ Setup node | |
| uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 | |
| with: | |
| node-version: '22' | |
| cache: 'pnpm' | |
| cache-dependency-path: 'pnpm-lock.yaml' | |
| - name: 📥 Install dependencies | |
| run: | | |
| pnpm install --frozen-lockfile | |
| - name: 🔬 Check Formatting | |
| run: pnpm run format:check | |
| typecheck: | |
| name: Typescript | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| concurrency: | |
| group: ci-typecheck-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: ⬇️ Checkout repo | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: 📦 Setup pnpm | |
| uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 | |
| with: | |
| run_install: false | |
| - name: ⎔ Setup node | |
| uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 | |
| with: | |
| node-version: '22' | |
| cache: 'pnpm' | |
| cache-dependency-path: 'pnpm-lock.yaml' | |
| - name: 📥 Install dependencies | |
| run: | | |
| pnpm install --frozen-lockfile | |
| # Enabling the turbo cache causes deployments to fail intermittently. | |
| # The build step fails with dependency issues. More investigation needed. | |
| # - name: 💾 Turbo cache | |
| # id: turbo-cache | |
| # uses: actions/cache@v3 | |
| # with: | |
| # path: | | |
| # node_modules/.cache/turbo | |
| # **/.turbo | |
| # key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }} | |
| # restore-keys: | | |
| # turbo-${{ github.job }}-${{ github.ref_name }}- | |
| - name: 📦 Build packages and templates | |
| run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false pnpm run build:all | |
| - name: ✅ Typecheck | |
| run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false pnpm run typecheck | |
| - name: 🧑💻 CLI manifest check | |
| run: 'test -z "$(git status --porcelain "packages/cli/oclif.manifest.json" )" || { echo -e "Run pnpm --dir packages/cli run generate:manifest before pushing new commands or flags. Diff here:\n\n$(git diff)" ; exit 1; }' | |
| test_e2e: | |
| name: ⬣ E2E tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| concurrency: | |
| group: ci-e2e-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: ⬇️ Checkout repo | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: 📦 Setup pnpm | |
| uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 | |
| with: | |
| run_install: false | |
| - name: ⎔ Setup node | |
| uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 | |
| with: | |
| node-version: '22' | |
| cache: 'pnpm' | |
| cache-dependency-path: 'pnpm-lock.yaml' | |
| - name: 📥 Install dependencies | |
| run: | | |
| pnpm install --frozen-lockfile | |
| - name: 📦 Build packages and templates | |
| run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false pnpm run build:all | |
| - name: 🎭 Install Playwright Chromium | |
| run: pnpm exec playwright install chromium --with-deps | |
| - name: 🔐 Install ejson | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y golang-go | |
| go install github.com/Shopify/ejson/cmd/ejson@latest | |
| echo "$HOME/go/bin" >> $GITHUB_PATH | |
| - name: 🧪 Run E2E tests | |
| # Customer Account tests are run separately in a different job | |
| # because they require a static redirect URL so we have a different CI | |
| # job to test Customer Account specific features. | |
| # The @customer-account tag is defined in e2e/specs/skeleton/customerAccount.spec.ts | |
| run: pnpm exec playwright test --grep-invert "@customer-account" | |
| env: | |
| EJSON_PRIVATE_KEY: ${{ secrets.EJSON_PRIVATE_KEY }} | |
| - name: 📤 Upload Playwright Report | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| if: ${{ always() && !cancelled() }} | |
| with: | |
| name: playwright-report | |
| path: playwright-report/ | |
| if-no-files-found: warn | |
| retention-days: 30 | |
| test_scaffolding: | |
| name: ⬣ Scaffolding tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| concurrency: | |
| group: ci-scaffolding-${{ matrix.pm }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # TODO: Re-enable bun once @shopify/cli releases with @shopify/cli-hydrogen that supports bun.lock | |
| pm: [npm, pnpm, yarn] | |
| include: | |
| - pm: npm | |
| lockfile: package-lock.json | |
| - pm: pnpm | |
| lockfile: pnpm-lock.yaml | |
| - pm: yarn | |
| lockfile: yarn.lock | |
| steps: | |
| - name: ⬇️ Checkout repo | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| # Explicit version required because pnpm/action-setup doesn't auto-detect | |
| # from packageManager field in this context. The version must match | |
| # engines.pnpm in package.json (>=10.16.1) | |
| - name: 📦 Setup pnpm | |
| uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 | |
| with: | |
| version: 10.16.1 | |
| run_install: false | |
| - name: ⎔ Setup node | |
| uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| cache: 'pnpm' | |
| cache-dependency-path: 'pnpm-lock.yaml' | |
| - name: 📦 Setup ${{ matrix.pm }} | |
| if: matrix.setup | |
| run: ${{ matrix.setup }} | |
| - name: 📥 Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: 📦 Build packages | |
| run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false pnpm run build:pkg | |
| - name: 🧪 Scaffold with ${{ matrix.pm }} | |
| run: | | |
| node packages/create-hydrogen/dist/create-app.js \ | |
| --path "$RUNNER_TEMP/h2-test-${{ matrix.pm }}" \ | |
| --language ts \ | |
| --mock-shop \ | |
| --install-deps \ | |
| --no-git \ | |
| --package-manager ${{ matrix.pm }} \ | |
| --no-shortcut \ | |
| --routes \ | |
| --markets none \ | |
| --styling none | |
| - name: ✅ Verify lockfile | |
| run: test -f "$RUNNER_TEMP/h2-test-${{ matrix.pm }}/${{ matrix.lockfile }}" | |
| - name: ✅ Verify app builds | |
| run: | | |
| cd "$RUNNER_TEMP/h2-test-${{ matrix.pm }}" | |
| ${{ matrix.pm }} run build | |
| test_e2e_customer_account: | |
| name: ⬣ E2E Customer Account tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 25 | |
| concurrency: | |
| # Serialized because all runs deploy to the same Oxygen storefront URL — | |
| # concurrent deploys would overwrite each other and cause test flakes. | |
| group: oxygen-deploy-customer-account-e2e | |
| cancel-in-progress: false | |
| # Required secrets: | |
| # OXYGEN_DEPLOYMENT_TOKEN_1000108386 — deploy token for the benchmark shop's Oxygen storefront | |
| # EJSON_PRIVATE_KEY — decrypts secrets.ejson to provide customer_account_email and loadtest_header | |
| # These correspond to the benchmark shop (drru00-at.myshopify.com / storefront 1000108386). | |
| # Update both if the test shop changes. | |
| steps: | |
| - name: ⬇️ Checkout repo | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: 📦 Setup pnpm | |
| uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 | |
| with: | |
| run_install: false | |
| - name: ⎔ Setup node | |
| uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 | |
| with: | |
| node-version: '22' | |
| cache: 'pnpm' | |
| cache-dependency-path: 'pnpm-lock.yaml' | |
| - name: 📥 Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: 📦 Build packages | |
| run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false pnpm run build:pkg | |
| #! oxygen_storefront_id: 1000108386 | |
| - name: 🚀 Deploy skeleton to Oxygen | |
| id: deploy | |
| working-directory: templates/skeleton | |
| run: pnpm exec shopify hydrogen deploy --no-lockfile-check --force --auth-bypass-token --env-file ../../e2e/envs/.env.customerAccount | |
| env: | |
| SHOPIFY_HYDROGEN_DEPLOYMENT_TOKEN: ${{ secrets.OXYGEN_DEPLOYMENT_TOKEN_1000108386 }} | |
| - name: 📋 Extract deployment URL | |
| id: deployment_info | |
| working-directory: templates/skeleton | |
| run: | | |
| URL="$(jq -r '.url' h2_deploy_log.json)" | |
| TOKEN="$(jq -r '.authBypassToken // empty' h2_deploy_log.json)" | |
| if [ -z "$URL" ] || [ "$URL" = "null" ]; then | |
| echo "::error::Deployment URL is empty — h2_deploy_log.json may be missing or malformed" | |
| exit 1 | |
| fi | |
| if [ -z "$TOKEN" ]; then | |
| echo "::error::Auth bypass token is empty — deploy may not have generated one" | |
| exit 1 | |
| fi | |
| echo "::add-mask::$TOKEN" | |
| echo "url=$URL" >> "$GITHUB_OUTPUT" | |
| echo "auth_bypass_token=$TOKEN" >> "$GITHUB_OUTPUT" | |
| - name: 🩺 Wait for deployment to be healthy | |
| env: | |
| DEPLOYMENT_URL: ${{ steps.deployment_info.outputs.url }} | |
| AUTH_BYPASS_TOKEN: ${{ steps.deployment_info.outputs.auth_bypass_token }} | |
| run: | | |
| # Poll the deployment until it returns 200 (not 302 redirect). | |
| # Oxygen deployments can take a few seconds to propagate after | |
| # the deploy command reports success. | |
| MAX_ATTEMPTS=30 | |
| POLL_INTERVAL_IN_SECONDS=3 | |
| for i in $(seq 1 $MAX_ATTEMPTS); do | |
| STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ | |
| -H "oxygen-auth-bypass-token: $AUTH_BYPASS_TOKEN" \ | |
| "$DEPLOYMENT_URL") | |
| if [ "$STATUS" = "200" ]; then | |
| echo "Deployment is healthy (HTTP $STATUS) after $((i * POLL_INTERVAL_IN_SECONDS))s" | |
| exit 0 | |
| fi | |
| echo "Attempt $i/$MAX_ATTEMPTS: HTTP $STATUS — waiting ${POLL_INTERVAL_IN_SECONDS}s..." | |
| sleep $POLL_INTERVAL_IN_SECONDS | |
| done | |
| echo "::error::Deployment did not become healthy within $((MAX_ATTEMPTS * POLL_INTERVAL_IN_SECONDS))s (last status: $STATUS)" | |
| exit 1 | |
| - name: 🎭 Install Playwright Chromium | |
| run: pnpm exec playwright install chromium --with-deps | |
| - name: 🔐 Install ejson | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y golang-go | |
| go install github.com/Shopify/ejson/cmd/ejson@latest | |
| echo "$HOME/go/bin" >> $GITHUB_PATH | |
| - name: 🧪 Run Customer Account E2E tests | |
| run: pnpm exec playwright test --project=skeleton e2e/specs/skeleton/customerAccount.spec.ts | |
| env: | |
| CUSTOMER_ACCOUNT_URL: ${{ steps.deployment_info.outputs.url }} | |
| OXYGEN_AUTH_BYPASS_TOKEN: ${{ steps.deployment_info.outputs.auth_bypass_token }} | |
| EJSON_PRIVATE_KEY: ${{ secrets.EJSON_PRIVATE_KEY }} | |
| - name: 📤 Upload Playwright Report | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| if: ${{ always() && !cancelled() }} | |
| with: | |
| name: playwright-report-customer-account | |
| path: playwright-report/ | |
| if-no-files-found: warn | |
| retention-days: 30 | |
| test_unit: | |
| name: ⬣ Unit tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| concurrency: | |
| group: ci-test-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: ⬇️ Checkout repo | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: 📦 Setup pnpm | |
| uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 | |
| with: | |
| run_install: false | |
| - name: ⎔ Setup node | |
| uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 | |
| with: | |
| node-version: '22' | |
| cache: 'pnpm' | |
| cache-dependency-path: 'pnpm-lock.yaml' | |
| - name: 📥 Install dependencies | |
| run: | | |
| pnpm install --frozen-lockfile | |
| - name: 📦 Build packages and templates | |
| run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false pnpm run build:all | |
| - name: 🔬 Test | |
| run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false pnpm run test | |
| validate_recipes: | |
| name: ⬣ Validate Recipes | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| concurrency: | |
| group: ci-validate-recipes-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: ⬇️ Checkout repo | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: 📦 Setup pnpm | |
| uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 | |
| with: | |
| run_install: false | |
| - name: ⎔ Setup node | |
| uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 | |
| with: | |
| node-version: '22' | |
| cache: 'pnpm' | |
| cache-dependency-path: 'pnpm-lock.yaml' | |
| - name: 📥 Install dependencies | |
| run: | | |
| pnpm install --frozen-lockfile | |
| - name: 📦 Build packages | |
| run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false pnpm run build:pkg | |
| - name: 📝 Validate schema | |
| working-directory: cookbook | |
| run: pnpm run cookbook -- schema && git diff --exit-code recipe.schema.json | |
| - name: 🧐 Validate Recipes | |
| working-directory: cookbook | |
| run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false pnpm run cookbook -- validate |