From 96b89e922d889d6eaaeec5ce7817c8a77904a476 Mon Sep 17 00:00:00 2001 From: systemfsoftware-bot Date: Thu, 29 Oct 2026 15:28:30 -0400 Subject: [PATCH] feat(effect-e2e-cli): scaffold example tests titled in the Should_When form Ported from systemfsoftware/systemfsoftware#873 (the effect-e2e parts). The oxlint-plugin e2e lane stays in the monorepo. Claude-Session: https://claude.ai/code/session_017rX35xUAHEjVVaDKVVzubW --- packages/effect-e2e-cli/README.md | 2 ++ .../effect-e2e-cli/src/templates/example-agent.template.ts | 2 +- packages/effect-e2e-cli/src/templates/example.template.ts | 2 +- .../effect-e2e-conformance/tests/cli-init.integration.test.ts | 4 ++-- .../tests/cli-run-web.integration.test.ts | 4 ++-- packages/effect-e2e/README.md | 2 +- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/effect-e2e-cli/README.md b/packages/effect-e2e-cli/README.md index c1117f7..7efd86e 100644 --- a/packages/effect-e2e-cli/README.md +++ b/packages/effect-e2e-cli/README.md @@ -10,6 +10,8 @@ Add it as a devDependency. It is distributed as a workspace tarball of the [syst `effect-e2e init --dir --engine web --gateway openrouter` scaffolds a suite: `e2e.config.ts`, `vitest.config.ts`, `runner.ts`, `global-setup.ts`, a deterministic example and an agent example under `tests/`, a `test:e2e` script and a `.e2e/` ignore entry. It asks for any choice not given as a flag, refuses to replace an existing file without `--force`, and installs the suite's dependencies unless `--no-install` is given. +The example tests `init` writes are titled in the `Should__When_` form that `@systemfsoftware/oxlint-config-recommended` requires. `init` writes no lint configuration, so a suite linted with that preset declares the end-to-end role in its lint config: `settings: { '@systemfsoftware/oxlint-plugin-test-discipline': { role: 'e2e' } }`. + `effect-e2e run --dir [files...]` runs the suite under Vitest in the same process and prints one report: the one the run's global setup merged into the output directory (`.e2e/` unless the config or `--output` moves it); without `--dir` it uses the nearest directory holding `e2e.config.ts`. `--reporter` picks `list` (the default), `json`, `junit` (writes `junit.xml`) or `markdown` (writes `summary.md`). The process exits with the report's code: 0 passed, 1 failed, 3 blocked, 4 error, 130 interrupted, and 2 when nothing reached a report: a config the runner refuses, a missing suite root, conflicting flags, a `vitest.config.ts` without the effect-e2e global setup, or a Vitest load error. A refused config never reads an older report. | Flag | Effect | diff --git a/packages/effect-e2e-cli/src/templates/example-agent.template.ts b/packages/effect-e2e-cli/src/templates/example-agent.template.ts index 2cde75c..488c384 100644 --- a/packages/effect-e2e-cli/src/templates/example-agent.template.ts +++ b/packages/effect-e2e-cli/src/templates/example-agent.template.ts @@ -3,7 +3,7 @@ export const exampleAgentTemplate = (): string => import { agentSkip } from '../e2e.config.ts' -test('a visitor reaches the top of the home page', { skip: agentSkip }, async ({ app, agent }) => { +test('Should_ReachTheTopOfThePage_When_TheAgentScrolls', { skip: agentSkip }, async ({ app, agent }) => { await app.open('/') await agent.act('scroll to the top of the page') await agent.assert('the page shows a heading') diff --git a/packages/effect-e2e-cli/src/templates/example.template.ts b/packages/effect-e2e-cli/src/templates/example.template.ts index fd79a6d..98d9b9a 100644 --- a/packages/effect-e2e-cli/src/templates/example.template.ts +++ b/packages/effect-e2e-cli/src/templates/example.template.ts @@ -1,7 +1,7 @@ export const exampleTemplate = (): string => `import { expect, test } from '@systemfsoftware/effect-e2e/runner' -test('the home page shows a heading', async ({ app, screen }) => { +test('Should_ShowAHeading_When_TheHomePageOpens', async ({ app, screen }) => { await app.open('/') await expect(screen.getByRole('heading')).toBeVisible() }) diff --git a/packages/effect-e2e-conformance/tests/cli-init.integration.test.ts b/packages/effect-e2e-conformance/tests/cli-init.integration.test.ts index 40115a5..1dc6de4 100644 --- a/packages/effect-e2e-conformance/tests/cli-init.integration.test.ts +++ b/packages/effect-e2e-conformance/tests/cli-init.integration.test.ts @@ -8,8 +8,8 @@ import { servedHeadingSite } from './__fixtures__/heading-site-server.js' const Feature = makeFeature({ it }) -const DETERMINISTIC = 'the home page shows a heading' -const AGENT = 'a visitor reaches the top of the home page' +const DETERMINISTIC = 'Should_ShowAHeading_When_TheHomePageOpens' +const AGENT = 'Should_ReachTheTopOfThePage_When_TheAgentScrolls' const NEVER_HOLDS = 'a sum that never holds' const NEVER_HOLDING_TEST = `import { expect, test } from '@systemfsoftware/effect-e2e/runner' diff --git a/packages/effect-e2e-conformance/tests/cli-run-web.integration.test.ts b/packages/effect-e2e-conformance/tests/cli-run-web.integration.test.ts index 1b355a7..66e93a5 100644 --- a/packages/effect-e2e-conformance/tests/cli-run-web.integration.test.ts +++ b/packages/effect-e2e-conformance/tests/cli-run-web.integration.test.ts @@ -8,8 +8,8 @@ import { servedHeadingSite } from './__fixtures__/heading-site-server.js' const Feature = makeFeature({ it }) -const DETERMINISTIC = 'the home page shows a heading' -const AGENT = 'a visitor reaches the top of the home page' +const DETERMINISTIC = 'Should_ShowAHeading_When_TheHomePageOpens' +const AGENT = 'Should_ReachTheTopOfThePage_When_TheAgentScrolls' const NOTHING_LISTENS = 'http://127.0.0.1:9' diff --git a/packages/effect-e2e/README.md b/packages/effect-e2e/README.md index b12fa6d..db5c8b4 100644 --- a/packages/effect-e2e/README.md +++ b/packages/effect-e2e/README.md @@ -69,7 +69,7 @@ export default defineConfig({ ```ts import { expect, test } from '@systemfsoftware/effect-e2e/runner' -test('the home page shows a heading', async ({ app, screen }) => { +test('Should_ShowAHeading_When_TheHomePageOpens', async ({ app, screen }) => { await app.open('/') await expect(screen.getByRole('heading')).toBeVisible() })