fix(web-app-docs): assert the yaml page on the tree the run deployed

The spec asserted /latest/compose.html. latest is the released tag built
from the git mirror, so no working-tree change can ever reach it; deployed
is the unlisted version built from the tree under test. Pointing the spec at
deployed makes it fail for a broken tree instead of passing on a stale one.

That move changes what the readiness gate has to wait for. There is no
version-state entry for deployed, so the poll now asks the page itself for a
200, and that request is what triggers the on-demand Sphinx build. The
budgets follow test-languages.js, which already waits for the same build:
50 minutes for the test, 45 for the poll, probed every 30 seconds instead of
continuously. The previous pairing could not work in either mode. Without a
per-test override the config allows 300000 ms, exactly the old poll budget,
so the test was killed at the instant the poll was due to report; on an
onion target resolveTimeout scales the poll to 25 minutes against a 15
minute test budget.

The poll also had to survive a refused connection. The server refuses while
it builds, and a callback that throws ends expect.poll rather than retrying
it, so the first refusal failed the test outright.

The heading is matched by prefix because docutils appends its permalink
pilcrow as a bare text node. The theme hides `.headerlink > *`, which
matches no element, so the accessible name is `compose.yml¶` and an exact
match can never succeed.

On-demand builds of the deployed tree are why three specs in this role carry
a timeout far above the suite default; each names the build it waits for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-09-27 00:59:48 +02:00
1 parent 68983daa02
commit 59e7b0a2a7
1 file changed
+22 -7
@@ -2,26 +2,41 @@ const { test, expect } = require("@playwright/test");
const { resolveTimeout } = require("./timeouts");
const { gotoOnion } = require("./personas");
const YAML_PAGE = "/latest/compose.html";
const YAML_PAGE = "/deployed/compose.html";
const FIRST_KEY = "x-ci-defaults";
const LATER_KEY = "dns_opt";
exports.register = function (shared) {
test("a yaml source page shows the file as one highlighted block", async ({ page, request }) => {
test.setTimeout(resolveTimeout(3_000_000)); // the English Sphinx build of the deployed working tree
await expect
.poll(() => shared.versionState(request, "latest"), {
message: "Expected the latest site to finish building before its pages are asserted",
timeout: resolveTimeout(300_000),
.poll(async () => {
try {
const response = await request.get(`${shared.appBaseUrl}${YAML_PAGE}`, {
failOnStatusCode: false,
timeout: resolveTimeout(30_000),
});
return response.status();
} catch {
return 0; // the server refuses connections while it builds; a throw would end the poll
}
}, {
message: "Expected the deployed YAML page to finish building before it is asserted",
timeout: resolveTimeout(2_700_000),
intervals: [30_000],
})
.toBe("ready");
.toBe(200);
const response = await gotoOnion(page, `${shared.appBaseUrl}${YAML_PAGE}`);
expect(response, `Expected a response for ${YAML_PAGE}`).toBeTruthy();
expect(response.status(), `Expected ${YAML_PAGE} to be served`).toBe(200);
await expect(
page.getByRole("heading", { name: "compose.yml", exact: true }),
"Expected the page to be titled after the file, which the yaml parser supplies",
page.getByRole("heading", { name: /^compose\.yml/ }),
"Expected the page to be titled after the file, which the yaml parser supplies. " +
"The name is matched by prefix because docutils appends its permalink pilcrow as a " +
"bare text node, which the theme hides through `.headerlink > *` and therefore never " +
"hides at all, so the accessible name is `compose.yml¶`",
).toBeVisible({ timeout: resolveTimeout(30_000) });
const block = page.locator("div.highlight-yaml pre");