chadtmiller.com/knotless
git that lives in your Atmosphere account
1
10
The e2e flows cover every write the pages make
.knotless/workflows/e2e.yml+2−3
| @@ -1,7 +1,6 @@ | ||
# The pages used as people use them, as `just e2e` runs them: in Chromium, | ||
# logging in through the PDS's own approval page, then starring, | ||
# following, opening an issue, commenting, reacting, closing, forking, | ||
# merging, queueing and labelling, each read back on the page and from the PDS | ||
# logging in through the PDS's own approval page, then every write the | ||
# pages make, each read back on the page and from the PDS | ||
# (harness/e2e/flows.spec.mjs), over a world seeded for the run as the | ||
# shots' is. The shots show what the pages draw; this, that what they do | ||
# lands. Each flow that fails leaves the page as it was then among the | ||
docs/development.md+13−3
| @@ -213,9 +213,19 @@ Chromium, as bob and then alice, they: | ||
| ||
- log in through the PDS's own approval page | ||
- star, follow, open an issue, comment, react, close and reopen | ||
- fork, merge a pull, and leave the merge queue and join it again | ||
- label as the repository's owner, logged in to a second account | ||
- switch back, and log out of each | ||
- fork, merge a pull, revert it, and leave the merge queue and join it again | ||
- open a pull from a fork, retarget it, rerun a check, and run a workflow | ||
when asked, at a tag with a variable | ||
- edit, delete, report and hide comments | ||
- create a repository, set a profile, notifications and the theme | ||
- start an organization, invite to it, join it, leave it and end it | ||
- label, as the repository's owner logged in to a second account | ||
- set a description and topics, labels, branches, collaborators, the | ||
triager, secrets, and compact | ||
- merge into a protected branch, rename a repository and offer it to | ||
another account, who takes it up | ||
- archive and delete a repository, and delete an account's knotless data | ||
- switch accounts, and log out | ||
| ||
Each write is checked three ways: on the page at once, as a record in the | ||
PDS, and on the page read anew from the index. | ||
harness/e2e/flows.spec.mjs+454−30
484 lines changed: not loaded until asked for.
harness/e2e/setup.mjs+7−2
| @@ -3,13 +3,18 @@ | ||
// back to (harness/tls-proxy.mjs). Where the pages are and who is in the | ||
// world go to the flows in E2E_WORLD. Returns the teardown. | ||
| ||
import { spawn } from 'node:child_process' | ||
import { execFileSync, spawn } from 'node:child_process' | ||
import { createInterface } from 'node:readline' | ||
import { join } from 'node:path' | ||
import { create, port, root, serve } from '../shots/world.mjs' | ||
import { create, environment, port, root, serve } from '../shots/world.mjs' | ||
| ||
export default async function setup() { | ||
const world = await create() | ||
// A tag on bob's fork, which its workflow run only when asked asks for: | ||
// pushed here, as the shots' world, which shows the fork's tags, has none. | ||
const bob = { cwd: join(world.dir, 'bob/tally'), env: environment(world.net, world.dir, 'bob') } | ||
execFileSync('git', ['tag', 'v0.1.0', 'main'], bob) | ||
execFileSync('git', ['push', '-q', 'origin', 'v0.1.0'], bob) | ||
world.server.kill() | ||
const { cert, key, host } = world.net.gateway | ||
const proxy = spawn('node', [join(root, 'harness/tls-proxy.mjs'), cert, key, String(port)], { | ||
harness/shots/world.mjs+1−1
| @@ -79,7 +79,7 @@ export const page = async (path) => { | ||
| ||
/// The environment `who` runs the CLI, git or the server in: committing | ||
/// `when`, as written `authored`, or then too. | ||
const environment = (net, dir, who, when, authored) => { | ||
export const environment = (net, dir, who, when, authored) => { | ||
const clean = Object.fromEntries(Object.entries(process.env).filter(([k]) => !k.startsWith('KNOTLESS_'))) | ||
const person = people[who] ?? { name: who, email: `${who}@example.com` } | ||
return { | ||
AGENTS.md+7−7
| @@ -216,13 +216,13 @@ on every pull. `main` deploys only once they all pass: | ||
builds. | ||
- `e2e`: `just e2e`: the pages used in Chromium over a world seeded for | ||
the run as the shots' is, served as a gateway behind the harness's | ||
https front: logging in through the PDS's approval page, then | ||
starring, following, opening an issue, commenting, reacting, closing, | ||
forking, merging a pull, leaving and joining the merge queue, | ||
labelling as the owner, switching accounts and logging out, each read | ||
back on the page and from the PDS (`harness/e2e/flows.spec.mjs`). A | ||
flow that fails leaves its page among the check's outputs. A new | ||
control that writes gets a flow there. | ||
https front: logging in through the PDS's approval page, then every | ||
write the pages make, from starring and commenting to merging, | ||
settings, organizations, transfers and deleting an account's data, | ||
as two accounts, each read back on the page and from the PDS | ||
(`harness/e2e/flows.spec.mjs`). A flow that fails leaves its page | ||
among the check's outputs. A new control that writes gets a flow | ||
there. | ||
| ||
A push to `main` at the same tree as a pull's run that passed, as | ||
`knotless merge` leaves it, does not run these again: the runner files | ||
Justfile+2−4
| @@ -195,10 +195,8 @@ shots-up: web | ||
tail -f /dev/null | node harness/shots/world.mjs | ||
| ||
# The pages used as people use them, in a browser: logging in through the | ||
# PDS, then starring, following, opening, commenting, reacting, closing, | ||
# forking, merging, queueing and labelling, each read back on the page and | ||
# from the PDS | ||
# (harness/e2e/flows.spec.mjs), over a world of its own seeded as the | ||
# PDS, then every write the pages make, each read back on the page and | ||
# from the PDS (harness/e2e/flows.spec.mjs), over a world of its own seeded as the | ||
# shots' is. Arguments go to Playwright: -g 'logging in through|starring' | ||
# for one flow, after the login it needs. | ||
e2e *args: web | ||