Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
# The Go counterpart to the `complexity` rule the page scripts are linted
# with. Pinned so a later gocyclo release cannot change the verdict on a
# tree that did not change.
- run: go run github.com/fzipp/gocyclo/cmd/gocyclo@v0.6.0 -over 5 ./src
- run: go run github.com/fzipp/gocyclo/cmd/gocyclo@v0.6.0 -over 4 ./src
timeout-minutes: 2
# Coverage is measured and reported, not gated. A threshold set before the
# number is known is a guess; this prints it so a later one can be set at
Expand Down
12 changes: 11 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ the fixtures shared by every test that drives a real request.
drive real requests through it without a listening socket. Anything that pulls
configuration out of the environment belongs in `main`, not in a handler.

The live feed is the exception. A WebSocket upgrade needs a real connection
underneath it, so `sockets_test.go` starts an application of its own on a
loopback port and dials it. Everything else stays on the in-memory transport.

## The Playwright suite covers screens and page scripts separately

`e2e/tests` holds one spec per subject. A `*-screen.spec.ts` drives a screen
Expand All @@ -44,6 +48,12 @@ helpers do. Fixtures used by more than one spec live in
`tests/support/harness.ts`, which is also the one place a type is asserted
rather than proven, at the `JSON.parse` and `response.json()` boundaries.

Screens are reached through `getByTestId`. `testIdAttribute` in
`playwright.config.ts` points it at the `data-test` attribute the templates
carry, so a test names a hook and never spells an attribute selector. An element
a test reaches for gets a `data-test`; anything a reader can identify by its
role or its text is reached that way instead.

## Comments

Comments describe what the code does now and warn about non-obvious constraints
Expand Down Expand Up @@ -141,7 +151,7 @@ not change the verdict on a tree that did not change.
asserting the value beside it, and a `t.Fatal` on every teardown call reads worse
than it protects.

The complexity ceiling stays separate. `gocyclo -over 5` is a ratchet rather
The complexity ceiling stays separate. `gocyclo -over 4` is a ratchet rather
than a correctness check, and it is documented alongside the ESLint one.

## Database standards
Expand Down
4 changes: 2 additions & 2 deletions docs/scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ ships a stray Go package once the npm tooling is installed.
Check cyclomatic complexity:

```bash
go run github.com/fzipp/gocyclo/cmd/gocyclo@v0.6.0 -over 5 ./src
go run github.com/fzipp/gocyclo/cmd/gocyclo@v0.6.0 -over 4 ./src
go run github.com/fzipp/gocyclo/cmd/gocyclo@v0.6.0 -top 10 ./src
```

Both sides carry a ceiling, and both are set at the worst score the tree
currently holds: `-over 5` for Go, and `complexity` at 6 in `eslint.config.mjs`
currently holds: `-over 4` for Go, and `complexity` at 5 in `eslint.config.mjs`
for the page scripts and the Playwright suite. The JavaScript side carries two
more ratchets set the same way, `max-params` at 3 and `max-depth` at 2. `-top`
takes no position and is the one to run when deciding what to simplify next.
Expand Down
5 changes: 5 additions & 0 deletions e2e/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export default defineConfig({
baseURL: BASE_URL,
trace: "on-first-retry",
permissions: ["clipboard-read", "clipboard-write"],
// The templates mark their test hooks with data-test, so getByTestId reads
// them directly. Spelling the attribute here rather than writing the
// selector at each call site keeps a hook's name the only thing a test
// states about it.
testIdAttribute: "data-test",
},
projects: [
{
Expand Down
4 changes: 2 additions & 2 deletions e2e/tests/contact-screen.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ test.describe("Contact screen", () => {
await page.locator('input[name="name"]').fill("John Doe");
await page.locator('input[name="email"]').fill("john@doe.test");
await page.locator('textarea[name="message"]').fill("Hello, World!");
await expect(page.locator('button[data-test="send-form"]')).toBeEnabled();
await expect(page.getByTestId("send-form")).toBeEnabled();
});

test("every field is labelled and required", async ({ page }) => {
Expand All @@ -32,7 +32,7 @@ test.describe("Contact screen", () => {
});

test("an empty form does not submit", async ({ page }) => {
await page.locator('button[data-test="send-form"]').click();
await page.getByTestId("send-form").click();
await expect(page).toHaveURL(/\/contact$/);
});

Expand Down
Loading
Loading