TS_E2E_TESTING_PLAN

TS E2E Testing Plan — gxwf-ui + gxwf-web

Goal: Playwright-driven end-to-end tests exercising the Vue UI against a real gxwf-web backend rooted at an isolated, per-run fixture workspace. First pass covers clean, roundtrip, format conversions (both directions), and exports.

Architectural Shape

One new package: packages/gxwf-e2e/ (private, not published). Owns:

Keeps playwright deps out of gxwf-ui (currently devDep-lean) and off the main release path.

Locator Convention: data-description

Follow Galaxy’s upstream convention — every UI element tests target gets a data-description="..." attribute with a human-readable name, not an opaque id. Examples:

<Button data-description="run clean operation" .../>
<Checkbox data-description="clean dry-run toggle" .../>
<div data-description="clean result panel">...</div>
<Tab data-description="clean tab" value="clean">Clean</Tab>

Tests locate via page.locator('[data-description="run clean operation"]'). Rationale: readable, survives PrimeVue DOM changes, matches Galaxy’s Selenium/Playwright patterns so the mental model ports.

A shared constants module (packages/gxwf-e2e/src/locators.ts) exports the strings used by both specs and component tests — one source of truth, catches typos at compile time.

Fixture Workspace Strategy

Seed layout (committed)

packages/gxwf-e2e/fixtures/workspace-seed/
  iwc/
    <selected IWC .ga files — copied, not submoduled>
    dirty-native.ga         # real IWC file, mutated to contain stale keys
  synthetic/
    simple-format2.gxwf.yml
    simple-format2-with-steps.gxwf.yml
  README.md                 # records IWC provenance (source path + commit sha)

Why copy, not symlink or submodule: tests mutate files; IWC lives outside the monorepo. Copying specific files gives reproducibility + keeps PRs reviewable.

IWC workflow selection

Pick 2–3 small, representative .ga files from /Users/jxc755/projects/repositories/iwc/workflows. Criteria: few steps (fast to parse/roundtrip), no unusual tool versions, realistic tool_state encoding. I’ll evaluate and pick during Step 3 and record provenance (IWC path + commit sha) in fixtures/workspace-seed/README.md so we can refresh intentionally.

Synthetic fixtures (format2 only)

We have no production format2 workflows to draw from, so:

Native-side fixtures are always real IWC workflows, including the “dirty” one. dirty-native.ga is a real IWC file with a surgical mutation adding stale keys and/or legacy tool_state encoding so clean has something to do. Preferring real fixtures for native side so we catch realistic tool_state shapes.

Per-suite cloning

Helper cloneWorkspace(seed): tmpDirfs.cpSync(seed, tmp, { recursive: true }) to os.tmpdir()/gxwf-e2e-<uuid>/. Called in beforeAll (or beforeEach when a suite mutates across tests). Each suite gets its own backend pointed at its clone. Cleanup in afterAll.

Lifecycle

Playwright’s webServer config is too coarse (single global server). Instead:

Tooling Decisions

Test Suites (Pass 1)

Each suite: clone seed → start backend → open UI → drive → assert on both UI state and on-disk filesystem state.

1. Clean workflow

2. Roundtrip

3. Convert .ga → format2

4. Convert format2 → .ga (synthetic)

5. Export .ga → format2

6. Export format2 → .ga

Dashboard / file-browser tests out of scope for pass 1.

Files / Packages to Add

packages/gxwf-e2e/
  package.json                      # private, playwright devDep
  playwright.config.ts
  tsconfig.json
  fixtures/workspace-seed/...       # committed
  src/
    harness.ts                      # TestHarness + cloneWorkspace
    locators.ts                     # data-description string constants
  tests/
    clean.spec.ts
    roundtrip.spec.ts
    convert.spec.ts                 # both directions
    export.spec.ts                  # both directions
  scripts/
    refresh-iwc.ts                  # opt-in helper to refresh chosen IWC files
  README.md                         # running + adding tests

UI edits:

Root:

Implementation Order

  1. Scaffold packages/gxwf-e2e + playwright config, no tests yet
  2. Build TestHarness + cloneWorkspace; smoke-test by hitting /workflows over HTTP
  3. Select IWC workflows, commit seed fixtures (synthetic format2 + chosen IWC files + mutated dirty-native.ga) — record provenance in README
  4. Add data-description attributes to UI + locator constants module
  5. Write clean.spec.ts (smallest surface) — get green end-to-end
  6. Add roundtrip, convert, export specs
  7. Hook into Makefile + CI workflow
  8. Document in packages/gxwf-e2e/README.md

Testing Strategy for the Plan Itself

Resolved Decisions

Remaining Open Items