QA Environment Setup (2025): Cloud-First When Roaming, WSL on the Workstation

Illustration of a two-lane QA environment Setup with Codespaces (cloud) and WSL, feeding one repo and Playwright report.

You move between desk, terrace, and garden. Reinstalling toolchains is waste. This QA environment setup uses two lanes that share one repo and one config: Cloud-First for any device with a browser, and WSL/Ubuntu for fast local runs at the desk.

  • What’s broken: Every device wants fresh installs and ends up drifting from CI.
  • Why it matters: Flaky “works here, not there” releases waste sprint time.
  • What to ignore: Heavy VMs for simple web apps, and sleep-based “stability.”
  • What to do: Two lanes, one truth—Codespaces when roaming, WSL at the desk.
Heads up: You may see display ads (AdSense) and occasional affiliate links. They help keep the content free and the lights on without paywalls. If this saved you time, consider buying me a coffee to keep ads minimal. Read the full disclosure

At a glance: which lane to use (comparison)

Decision pointCloud-First (Codespaces)WSL on Windows
Setup time1–2 minutes per repoOne-time WSL install, then fast
SpeedGood enough for smoke & small suitesFastest feedback on your hardware
OfflineNeeds steady internetWorks offline
Parity with CILinux container = close to CILinux in WSL = close to CI
ArtifactsHTML report in workspace; download if neededHTML report opens locally
Best useRoaming, second device, hotel Wi-FiLong sessions, debugging, heavy runs


Cloud-First QA environment setup (Codespaces)

Status: Actively using & learningTested on: Win11 host, browser IDE — Limitations: needs a stable connection

Why this lane exists: You want to switch devices without reinstalling anything. The environment lives with the repo; the browser is your IDE.

What you’ll have at the end: a green Playwright run and an HTML report you can open immediately.

Steps (with reasons):

  1. Create a Codespace on your repo.
    Reason: Boots a clean Linux box tied to your code.
  2. Install runner inside the container (once):

    npm i -D @playwright/test
    npx playwright install


    Reason: Puts Playwright and browsers in the cloud box, not your laptop.
  3. Add one smoke test (stable locators, no sleeps):

    // tests/smoke.spec.ts
    import { test, expect } from "@playwright/test";
    test("login → dashboard", async ({ page }) => {
    await page.goto("https://example.com/login");
    await page.getByRole("textbox", { name: "Email" }).fill("[email protected]");
    await page.getByRole("textbox", { name: "Password" }).fill("pass123!");
    await page.getByRole("button", { name: "Sign in" }).click();
    await expect(page.getByText("Dashboard")).toBeVisible();
    });
  4. Run and view the report:

    npm test npx playwright show-report

    Reason: Trust comes from artifacts, not vibes.

Failure signals & quick fixes:

  • Timeouts → assert outcomes (await expect(...).toBeVisible()), never waitForTimeout().
  • Selectors break → use role → text → test-id; avoid brittle CSS.
  • Report won’t open → open playwright-report/index.html from the Explorer.

Workstation qa environment setup (WSL on Windows)

Status: Proven in my setupTested on: Win11 + WSL (Ubuntu), Node 20, Playwright — Limitations: none for this scope

Why this lane exists: Fast runs and close parity with Linux CI, without leaving Windows.

Steps (one-time + daily run):

  1. Install WSL + Ubuntu (once): wsl --install -d Ubuntu
  2. Install Node 20 with nvm (once): sudo apt update && sudo apt install -y curl ca-certificates git curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc && nvm install 20
  3. Clone, add Playwright, run (daily): git clone https://github.com/<you>/<repo>.git cd <repo> npm i -D @playwright/test npx playwright install --with-deps npm test npx playwright show-report

What not to do here:

  • Don’t “stabilize” with sleeps—use assertions that wait for results.
  • Don’t let WSL and CI drift—pin Node and commit the lockfile.


One repo, one config (keeps both lanes honest)

Playwright config (portable):

// playwright.config.ts
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
  retries: 1,
  use: {
    screenshot: "only-on-failure",
    trace: "retain-on-failure",
    video: "retain-on-failure"
  },
  projects: [{ name: "chromium", use: { ...devices["Desktop Chrome"] } }]
});

Version pinning:
Create .nvmrc with 20. Commit your lockfile. This keeps your qa environment setup identical in Codespaces, WSL, and CI.

Fresh data (simple, not fancy):
Use a small unique suffix per run (timestamp/random). Example: user+e2e-<timestamp>-<rand>@example.test. Clean up if your app supports delete.


CI: same suite on push/PR (zero surprises)

# .github/workflows/e2e.yml
name: e2e
on:
  push: { branches: [ main ] }
  pull_request:
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci || npm i -D @playwright/test
      - run: npx playwright install --with-deps
      - run: npx playwright test --reporter=html
      - uses: actions/upload-artifact@v4
        with: { name: playwright-report, path: playwright-report }

Done when: the same green run and HTML report appear locally and in CI.


Quick checklist (copy, tick, move on)

  • Cloud lane runs green, report opens
  • WSL lane runs green, report opens
  • One playwright.config.ts in repo
  • .nvmrc + lockfile committed
  • Simple unique data suffix in place
  • CI job attaches the HTML report

FAQ

Can I skip WSL entirely?
Yes. If you’re roaming all week, Codespaces + CI covers you.

Why no Docker here?
For this qa environment setup, WSL + Node is simpler and very close to CI. Add Docker only if the app demands it.

Do I need a remote browser grid?
Only if you require a wide browser/OS/device matrix or predictable high concurrency. Start with this; scale later.

How do I write bug reports that devs don’t hate?
Use evidence and exact steps. Format I use: https://qajourney.net/how-to-write-effective-bug-reports-with-examples/

Jaren Cudilla
Jaren Cudilla
QA Overlord

Two-lane QA setup today: Codespaces when roaming, WSL at the desk so the repo, tests, and results match across devices at QAJourney.net.
I publish what I run: Node 20 + Playwright, role-first selectors, outcome-based waits. One green run and an HTML report then it ships.

1 thought on “QA Environment Setup (2025): Cloud-First When Roaming, WSL on the Workstation”

Comments are closed.