2 Commits
Author SHA1 Message Date
clawbot a2de3b2b94 test/viewport/README.md: rework against the review findings
check / check (push) Canceled after 0s
The opening paragraph has one short sentence per step, and the header
check names `/` and `/no-such-page`. The checks section no longer says
every check runs at every width: `tap-targets-44px` runs only at touch
widths, and each width gets one of the two row-layout checks. The wait
for 5 latency figures is described per width, as the test opens the page
once per width. For #197, part of
#189.

Model: fable-5-1
2026-10-26 04:07:04 +00:00
clawbot a468b14c1e test/viewport/README.md rewritten sentence by sentence
What the test does comes first, then the widths, the checks, the
canned network, what it cannot check, the files, and its relation to
the unit tests. The repo's history and issue references are gone;
every sentence is under about 30 words.

Model: fable-5-1
2026-10-26 04:00:16 +00:00
3 changed files with 605 additions and 448 deletions
+582 -415
View File
File diff suppressed because it is too large Load Diff
-4
View File
@@ -23,10 +23,6 @@ Run `make frontend-viewport-test` in CI as its own step; it is not part of
# Completed Steps # Completed Steps
- 2026-10-26: `README.md`, `TODO.md` and `test/viewport/README.md` are rewritten
sentence by sentence ([#189](https://git.eeqj.de/sneak/netwatch/issues/189)).
Each sentence reads on the first pass: one idea, under about 30 words, the
verb early. Every statement matches the code on `next`.
- 2026-10-26: a target whose home page answers with a redirect is checked at - 2026-10-26: a target whose home page answers with a redirect is checked at
`/robots.txt` on the same host, which answers without one `/robots.txt` on the same host, which answers without one
([#194](https://git.eeqj.de/sneak/netwatch/issues/194)). These are the AWS ([#194](https://git.eeqj.de/sneak/netwatch/issues/194)). These are the AWS
+23 -29
View File
@@ -17,18 +17,17 @@ layout inside the page and checks the measurements in Node. The checks decide
pass or fail. Screenshots and a `results.json` land in `tmp/viewport/`, for a pass or fail. Screenshots and a `results.json` land in `tmp/viewport/`, for a
person to look at when a check fails. person to look at when a check fails.
The test is not part of `make check`: it takes minutes, and `make test` has to The test is not part of `make check`: it needs Docker and takes minutes, and
finish in under 60 seconds. `make test` has to finish in under 60 seconds.
## The widths ## The widths
The breakpoints are read from the page's own files. `viewports.js` reads the The widths come from the page's own CSS. `viewports.js` reads every `min-width`
`min-width` and `max-width` conditions out of the `@media` blocks in and `max-width` condition out of the `@media` blocks in `web/src/styles.css`. It
`web/src/styles.css`. It also looks in `web/src/main.js` and `web/index.html` also looks in `web/src/main.js` and `web/index.html` for Tailwind's responsive
for Tailwind's responsive class prefixes, such as `md:`, and takes their class prefixes, such as `md:`, and takes their breakpoints. Each breakpoint is
breakpoints. Each breakpoint is tested at one pixel below it, exactly on it, and tested at one pixel below it, exactly on it, and one pixel above it. Today the
one pixel above it. Today the CSS has one breakpoint, `max-width: 768px`, and no CSS has one breakpoint, `max-width: 768px`, and no responsive prefix is used.
responsive prefix is used.
A `max-width: 768px` block matches at 768 pixels. Testing both sides of each A `max-width: 768px` block matches at 768 pixels. Testing both sides of each
breakpoint catches a layout that switches one pixel too early or too late. A breakpoint catches a layout that switches one pixel too early or too late. A
@@ -50,8 +49,6 @@ Four more widths are fixed, each for a stated reason:
touch device touch device
- 1280 by 800 pixels: a desktop window - 1280 by 800 pixels: a desktop window
Every width but 1280 by 800 is tested as a touch device.
## The checks ## The checks
A failed check does not stop the others. A failed check does not stop the others.
@@ -63,11 +60,11 @@ A failed check does not stop the others.
failure, the widest content is named. failure, the widest content is named.
- `nothing-past-viewport-edge`: no visible element extends past the window's - `nothing-past-viewport-edge`: no visible element extends past the window's
edge. edge.
- `no-clipped-text`: no element hides its text behind `overflow: hidden` or - `no-clipped-text`: no element hides its text behind `overflow: hidden`. Text
`overflow: clip`. Text cut with an ellipsis is allowed: that cut is a design cut with an ellipsis, as Tailwind's `truncate` does on host names and URLs, is
choice, not a defect. Tailwind's `truncate` cuts host names and URLs that way. allowed.
- `tap-targets-44px`, on touch widths: each measured control is at least 44 by - `tap-targets-44px`, on touch widths: every interactive control is at least 44
44 CSS pixels. The controls are `#pause-btn`, `#interval-select`, by 44 CSS pixels. The controls are `#pause-btn`, `#interval-select`,
`#debug-toggle` and the `.pin-btn` in each WAN host row. The check also `#debug-toggle` and the `.pin-btn` in each WAN host row. The check also
demands that each selector matches enough visible elements: one of each single demands that each selector matches enough visible elements: one of each single
control, and one pin button per WAN host row. A renamed class would otherwise control, and one pin button per WAN host row. A renamed class would otherwise
@@ -80,10 +77,9 @@ A failed check does not stop the others.
is `row` and the graph sits to the right of the details. A row that only is `row` and the graph sits to the right of the details. A row that only
shrank its fixed 420-pixel column fails. shrank its fixed 420-pixel column fails.
- `probing-still-runs`: the page sent at least one check to a target at this - `probing-still-runs`: the page sent at least one check to a target at this
width. The narrow layout must not skip the checks. width.
- `gateway-detection-still-runs`: the `Local Gateway` row is present at this - `gateway-detection-still-runs`: the `Local Gateway` row is present at this
width, so the gateway was looked for and found. The narrow layout must not width, so the gateway was looked for and found.
skip that search.
### The tap-target size ### The tap-target size
@@ -101,8 +97,7 @@ from a fixed table of delays: 2, 45, 123, 456 and 780 milliseconds. Which delay
a target gets depends on its URL, and about one target in seven fails outright. a target gets depends on its URL, and about one target in seven fails outright.
So the rows show one-, two- and three-digit latencies and some unreachable rows, So the rows show one-, two- and three-digit latencies and some unreachable rows,
and the layout is tested against that spread. The request to and the layout is tested against that spread. The request to
`http://192.168.1.1` is answered after 5 milliseconds, so the `Local Gateway` `http://192.168.1.1` is answered, so the `Local Gateway` row appears.
row appears.
At each width, the test sets the interval to 1 second and waits until at least 5 At each width, the test sets the interval to 1 second and waits until at least 5
rows show a latency before it measures. The page discards its first round, so rows show a latency before it measures. The page discards its first round, so
@@ -118,8 +113,8 @@ this reaches a filled page without waiting out two rounds at 3 seconds.
- Physical pixels. The device pixel ratio is set, but antialiasing, colour - Physical pixels. The device pixel ratio is set, but antialiasing, colour
rendering and legibility at a given physical size are not measured. rendering and legibility at a given physical size are not measured.
- Fonts. The container has DejaVu, not a phone's own monospace font. Text is - Fonts. The container has DejaVu, not a phone's own monospace font. Text is
about as wide as on a real device, but not exactly. A layout that fits here by close to, but not the same width as, text on a real device. A layout that fits
a few pixels might not fit there. here by a few pixels might not fit there.
- Performance. The cost of redrawing the graphs, battery use and behaviour on a - Performance. The cost of redrawing the graphs, battery use and behaviour on a
slow connection are not measured. slow connection are not measured.
- The browser's own frame. The address bar, safe-area insets and notch cutouts - The browser's own frame. The address bar, safe-area insets and notch cutouts
@@ -138,9 +133,8 @@ this reaches a filled page without waiting out two rounds at 3 seconds.
## Relation to the unit tests ## Relation to the unit tests
The unit tests in `test/unit/` call the functions that `web/src/main.js` The unit tests in `test/unit/`, which `make test` runs with Node's built-in test
exports, with no browser. `make test` runs them with Node's built-in test runner, call the functions `web/src/main.js` exports, with no browser. This test
runner. This test runs the built page in a real browser engine and is the only runs the built page in a real browser engine and is the only test here that can
test here that can see a media query. Neither replaces the other. Checks on see a media query. Checks on computed styles and element geometry belong here;
computed styles and element geometry belong here; checks on functions belong in checks on functions belong in `test/unit/`.
`test/unit/`.