Skip to content

test: add render-regression checks to prevent #7079-class bugs#7085

Merged
jstirnaman merged 1 commit intomasterfrom
claude/render-regression-checks
Apr 9, 2026
Merged

test: add render-regression checks to prevent #7079-class bugs#7085
jstirnaman merged 1 commit intomasterfrom
claude/render-regression-checks

Conversation

@jstirnaman
Copy link
Copy Markdown
Contributor

@jstirnaman jstirnaman commented Apr 9, 2026

Summary

Adds four layers of coverage to prevent the class of rendering regression reported in #7079 (whitespace leaks in Hugo render hooks or wrapper shortcode templates causing Goldmark to HTML-escape highlighted code blocks). Each layer catches the bug at a different point in the lifecycle — together they mean this specific regression can't land again without actively defeating every layer.

What shipped

Layer 1 — Site-wide HTML grep after Hugo build

.ci/scripts/check-render-artifacts.sh

Scans every .html file under public/ for three literal patterns that can only appear when a render hook has leaked whitespace into its output:

  • <div class="highlight"
  • <pre tabindex="0"
  • <span class="line"><span class="cl"

Runs in ~1 second on the full built site. Zero curation required — any page anywhere in the site is covered automatically. Verified against a rebuild with the pre-fix render-codeblock.html from commit d80eb2f (correctly reports 54 affected files) and against the current clean build (reports 0).

Layer 2 — Pre-commit lint for render hooks

.ci/scripts/check-render-hook-whitespace.sh + new check-render-hook-whitespace command in lefthook.yml

Enforces the invariant that every action tag inside layouts/_default/_markup/render-*.html uses {{- ... -}} whitespace trimming. Bare {{ ... }} actions leak their surrounding indent and newline into the render-hook output — the exact mechanism that caused #7079. The lint catches this at commit time, before a PR is even opened. Scoped narrowly to render hook files so it doesn't nag on normal Hugo templates where bare actions are fine.

Also hardens render-codeblock.html lines 1 and 19, which had bare {{ ... }} actions that happened to work correctly because surrounding {{- ... -}} operators trimmed their whitespace by accident. Rewriting them as {{- ... -}} makes the file unconditionally correct and lets the lint ship with no exceptions.

Layer 3 — Cypress render-regression spec

cypress/e2e/content/render-regression.cy.js, new test:render-regression and test:render-artifacts npm scripts

DOM-level assertion that no pre > code element on a curated page list contains the escaped chroma fragments. Two describe blocks:

  1. Shortcode examples page (/example/) — exhaustive shortcode showcase. Any layout/render-hook change that breaks a documented shortcode will show up here, regardless of which product it affects.

  2. Representative product pages — one page per InfluxDB 3 edition, hand-picked for the wrapper/attribute combination it exercises:

    Page Exercises
    /influxdb3/core/reference/sample-data/ placeholders + custom-timestamps wrapper + code-tab-content
    /influxdb3/enterprise/admin/backup-restore/ placeholders inside tab-content (the page that regressed worst in Broken HTML formatting in sample data pages #7079)
    /influxdb3/cloud-dedicated/reference/sample-data/ placeholders="DATABASE_(TOKEN|NAME)" regex grouping inside custom-timestamps
    /influxdb3/clustered/admin/users/add/ placeholders + callouts in nested expand wrappers
    /influxdb3/cloud-serverless/reference/sample-data/ post-migration fence-attribute syntax

Each test also asserts the page actually has highlighted code blocks (guards against a broken fixture silently passing).

Layer 4 — Example page coverage for the render-hook attributes

content/example.md: new "Render-regression fixtures" section at the end.

Before this PR, content/example.md had zero uses of placeholders= or callout= fence attributes — which meant the shortcode-examples smoke test was structurally blind to #7079-class bugs. This PR adds fixtures for every code path the #7069 regression affected:

  • placeholders="DATABASE_NAME|AUTH_TOKEN" (simple alternation)
  • placeholders="DATABASE_(TOKEN|NAME)" (regex group)
  • callout="--host" (default green)
  • callout="--host" callout-color="magenta" (explicit color)
  • placeholders="DATABASE_NAME" callout="--host" callout-color="orange" (both on one fence)
  • Placeholder fence inside {{% influxdb/custom-timestamps %}}
  • Worst-case nested shape: expand-wrapper > code-tabs-wrapper > code-tab-content > influxdb/custom-timestamps > placeholder fence (the shape every sample-data page uses)

Verified after rebuild: /example/ now renders 11 placeholder wrappers, 3 callouts, and 3 custom-timestamps wrappers.

CI workflow

.github/workflows/pr-render-check.yml

Runs on every pull_request. Two jobs:

  1. check-artifacts — unconditional. Builds the site, runs the grep from layer 1. Runs even on content-only PRs and catches any regression anywhere in the site. Target runtime: <2 min.
  2. cypress-render — gated on a path filter. Only triggers when the PR touches layouts/, assets/, the render-regression spec itself, the check-artifacts script, or this workflow file. Runs the Cypress spec from layer 3.

The unconditional grep is the backstop. Cypress runs on the subset of PRs that can actually cause this class of bug.

How the layers compose

Stage Layer Catches
Author-time Layer 2 (pre-commit lint) The cause of #7079 before a PR opens
PR build, every PR Layer 1 (site-wide grep) Any rendered regression on any page in the site
PR build, layout PRs Layer 3 (Cypress spec) DOM-level verification + fixture liveness
Upstream Layer 4 (example.md fixtures) Smoke test surface for layers 2 and 3

Verification

Not yet done / possible follow-ups

  • Cypress spec was not executed locally because the Cypress binary isn't installed in the sandbox. The spec's assertions were smoke-tested by running the same grep logic against the built HTML for each fixture page (0 artifacts, 1+ highlighted code blocks on each). First CI run will be the real test.
  • Broader forbidden-pattern list ({{<, {{%, ZgotmplZ) deliberately excluded from check-render-artifacts.sh v1 because of pre-existing false positives (Helm template docs with literal {{ content, and a separate pre-existing ZgotmplZ leak on ~4600 pages via data-influxdb-urls). Script header documents the gap. Can be re-added as warnings or after those pre-existing issues are cleaned up.
  • test:shortcode-examples npm script has a pre-existing mismatch: it runs cypress/e2e/content/index.cy.js (which tests the home page, not example.md). Left unchanged to keep this PR focused.

Test plan

Refs #7079

Adds four layers of coverage against the class of rendering bug
reported in #7079: whitespace leaks in Hugo render hooks or wrapper
shortcode templates that cause Goldmark to HTML-escape highlighted
code blocks. Each layer catches the bug at a different point in the
lifecycle — together they mean this specific regression can't land
again without somebody actively defeating every layer.

Layer 1 — Site-wide HTML grep after Hugo build
  .ci/scripts/check-render-artifacts.sh

  Scans every .html file under `public/` for three literal patterns
  that can only appear when a render hook leaked whitespace into its
  output: `&lt;div class=&quot;highlight&quot;`,
  `&lt;pre tabindex=&quot;0&quot;`, and
  `&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;cl&quot;`.
  Runs in ~1 second on the full built site. Catches regressions on
  every page automatically, including pages no test lists explicitly.
  Verified against a rebuild with the pre-fix render-codeblock.html
  from commit d80eb2f — correctly reports 54 affected files — and
  against the current clean build — reports 0.

Layer 2 — Pre-commit lint for render hooks
  .ci/scripts/check-render-hook-whitespace.sh
  lefthook.yml: new pre-commit command `check-render-hook-whitespace`

  Enforces the invariant that every action tag inside
  `layouts/_default/_markup/render-*.html` uses `{{- ... -}}`
  whitespace trimming. Bare `{{ ... }}` actions leak their surrounding
  indent and newline into the render-hook output; the lint catches
  this at commit time, before a PR is even opened. Scoped narrowly to
  render hooks so it doesn't nag on normal Hugo templates where bare
  actions are fine.

  Also hardens render-codeblock.html lines 1 and 19, which had bare
  `{{ ... }}` actions that happened to work correctly because
  surrounding `{{- ... -}}` operators trimmed their whitespace by
  accident. The lint flagged them as fragile; rewriting them as
  `{{- ... -}}` makes the file unconditionally correct and lets the
  lint ship with no exceptions.

Layer 3 — Cypress render-regression spec
  cypress/e2e/content/render-regression.cy.js
  package.json: `test:render-regression`, `test:render-artifacts`

  DOM-level assertion that no `pre > code` element on a curated page
  list contains the escaped chroma fragments. Two sections:

  * Shortcode examples page (/example/) — a single exhaustive
    shortcode fixture that covers every render-hook combination
    documented in the site.

  * Representative product pages — one page per InfluxDB 3 edition,
    hand-picked for the wrapper/attribute combination it exercises:
    - core/reference/sample-data (placeholders + custom-timestamps
      + code-tab-content)
    - enterprise/admin/backup-restore (placeholders inside
      tab-content — the page that regressed worst in #7079)
    - cloud-dedicated/reference/sample-data (placeholders with
      regex grouping inside custom-timestamps)
    - clustered/admin/users/add (placeholders + callouts in nested
      expand wrappers)
    - cloud-serverless/reference/sample-data (post-migration
      fence-attribute syntax)

Layer 4 — Example page coverage for the render-hook attributes
  content/example.md: new "Render-regression fixtures" section

  Adds fence-attribute and wrapper fixtures that exercise every code
  path implicated in #7079: `placeholders=` with and without regex
  grouping, `callout=` with default and explicit color, combined
  `placeholders=` + `callout=`, placeholder fences inside
  `influxdb/custom-timestamps`, and the worst-case nested shape
  (expand > code-tabs > code-tab-content > custom-timestamps >
  placeholder fence) that every sample-data page uses. Before this
  commit `content/example.md` had zero uses of either attribute,
  which meant the shortcode-examples smoke test was blind to
  #7079-class bugs. Verified after rebuild: 11 placeholder wrappers,
  3 callouts, and 3 custom-timestamps wrappers render on /example/.

CI workflow
  .github/workflows/pr-render-check.yml

  Runs on every pull_request. Two jobs:

  * check-artifacts: Unconditional site-wide grep on every PR.
  * cypress-render: Cypress spec, gated on a path filter that only
    triggers when the PR touches layouts/, assets/, the render-regression
    spec itself, the check-artifacts script, or this workflow file.

  The unconditional grep is the backstop — it runs even on content-only
  PRs and catches any regression anywhere in the site. Cypress runs on
  the subset of PRs that can actually cause this class of bug.

Refs #7079
@jstirnaman jstirnaman requested a review from a team as a code owner April 9, 2026 22:33
@jstirnaman jstirnaman requested review from sanderson and removed request for a team April 9, 2026 22:33
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Vale Style Check Results

Metric Count
Errors 0
Warnings 0
Suggestions 1

Check passed

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

PR Preview Action v1.4.8
🚀 Deployed preview to https://influxdata.github.io/docs-v2/pr-preview/pr-7085/
on branch gh-pages at 2026-04-09 22:35 UTC

@jstirnaman jstirnaman added area:site-ui Documentation site UI: templates, styles, JS/TS area:ci continuous integration pipeline (verify, test, validate, publish) labels Apr 9, 2026
@jstirnaman
Copy link
Copy Markdown
Contributor Author

👍

@jstirnaman jstirnaman merged commit e4cad3c into master Apr 9, 2026
16 of 17 checks passed
github-actions bot added a commit that referenced this pull request Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:ci continuous integration pipeline (verify, test, validate, publish) area:site-ui Documentation site UI: templates, styles, JS/TS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants