Skip to content

Add new section for e2e testing#6899

Open
ryancbahan wants to merge 3 commits intomainfrom
e2e-testing
Open

Add new section for e2e testing#6899
ryancbahan wants to merge 3 commits intomainfrom
e2e-testing

Conversation

@ryancbahan
Copy link
Contributor

@ryancbahan ryancbahan commented Feb 26, 2026

WHY are these changes introduced?

The CLI team manually runs a ~30-step QA checklist before every release. This is time-consuming and error-prone.
Cucumber suite tests CLI commands non-interactively but cannot handle interactive CLI prompts, long-running dev servers, auth, or browser verification. We should have better e2e test infra that allows us to automate QA, as well as provide better regression testing for CLI features. This is now possible with Shopify infra. for automating auth. We can leverage well-established packages Playwright and Node-pty for drivers/runners.

WHAT is this pull request doing?

Introduces a new packages/e2e/ package with Playwright + node-pty infrastructure for automated end-to-end testing of the full CLI workflow.

Package setup:

  • package.json, tsconfig.json, project.json, playwright.config.ts
  • pnpm-workspace.yaml updated to allowlist node-pty native builds

Fixtures:

  • env.ts — worker-scoped XDG directory isolation and env var management
  • cli-process.ts — CLI execution via execa (non-interactive) and node-pty (interactive PTY with output matching, key sending, and process lifecycle)

Helpers:

  • strip-ansi.ts, wait-for-port.ts, file-edit.ts

Smoke tests:

  • smoke.spec.ts — validates execa path (shopify version)
  • smoke-pty.spec.ts — validates PTY path (shopify version via node-pty)

Subsequent PRs in this stack add OAuth login, app scaffold/deploy/dev tests, and CI integration.

How to test your changes?

cp packages/e2e/.env.example packages/e2e/.env
# Fill in credentials (see .env.example for details)
cd packages/e2e
npx playwright install chromium
npx playwright test tests/smoke.spec.ts tests/smoke-pty.spec.ts

Measuring impact

n/a - this is test infrastructure

Copy link
Contributor Author

ryancbahan commented Feb 26, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@ryancbahan ryancbahan changed the title add new section for e2e testing Add new section for e2e testing Feb 27, 2026
New packages/e2e/ package with Playwright test runner, node-pty for
interactive CLI testing, and isolated XDG environments.

Includes:
- Package config (package.json, tsconfig, playwright.config, project.json)
- Fixtures: env (XDG isolation, auth tokens), cli-process (execa + PTY)
- Helpers: strip-ansi, wait-for-port, file-edit
- Smoke tests validating both execa and PTY execution paths
@ryancbahan ryancbahan marked this pull request as ready for review February 27, 2026 20:23
@ryancbahan ryancbahan requested a review from a team as a code owner February 27, 2026 20:23
@github-actions
Copy link
Contributor

github-actions bot commented Feb 27, 2026

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements 78.81% 14512/18415
🟡 Branches 73.14% 7215/9864
🟡 Functions 79.01% 3690/4670
🟡 Lines 79.15% 13719/17334

Test suite run success

3778 tests passing in 1448 suites.

Report generated by 🧪jest coverage report action from c96d6b9

@@ -0,0 +1,19 @@
# Required: Client ID of the primary test app (must be in the genghis account's org)
# CI secret: E2E_CLIENT_ID
SHOPIFY_FLAG_CLIENT_ID=
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For initial E2E tests, we won't create new apps but instead use existing ones. We should 100% evolve this, but we need a starting point to monitor and observe stability of this job.

waiter.reject(new Error(`Process exited (code ${code}) while waiting for output: "${waiter.text}"`))
}
outputWaiters.length = 0
})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

waitForExit() only supports a single waiter; subsequent calls can deadlock

The implementation stores only one exitResolve callback. If waitForExit() is called twice before the process exits, the second call overwrites exitResolve, leaving the first promise unresolved forever. Evidence: single-slot let exitResolve: ((code: number) => void) | undefined; waitForExit assigns exitResolve = (code) => { ... resolve(code) } overwriting any prior waiter; onExit calls only the last assigned exitResolve.

@binks-code-reviewer
Copy link

🤖 Code Review · #projects-dev-ai for questions
React with 👍/👎 or reply — all feedback helps improve the agent.

Complete - 1 findings

📋 History

✅ 1 findings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant