Skip to Content

Renders

A green check mark says little about what a run found. A render shows it: a coverage badge, a benchmark table, a test report, a whole web application built by the pipeline, right in the run page.

A render is a run artifact with an entrypoint, the file it opens, such as index.html: the program pushing the artifact gives it. The run page shows the renders of a run under Renders, one tab per render, above its artifacts; public run pages show the public ones.

Built-in Views

The run page shows most files itself, chosen by the media type of the entrypoint, which comes from its extension:

EntrypointShown as
Image: PNG, JPEG, GIF, WebP, AVIF, SVGThe image. SVG files are shown as images, where their scripts never run.
MarkdownFormatted text, with its tables. Raw HTML is left out; images and links of the same artifact work, and images from elsewhere stay links, so that their host never learns who views the run.
JSONA table for an array of objects, a table of keys and values for an object, indented JSON otherwise.
CSV, TSVA table of the first 1,000 rows.
Other textThe text as it is.
HTMLThe page itself, on a domain of its own.

The run page reads the file through its stable address, up to 5 MB of text or 50 MB of image; larger files are offered for download.

HTML Renders

An HTML entrypoint runs in a frame, served from a domain of its own, one subdomain per viewing grant: to the browser, every render is another site. It reaches neither the dashboard’s storage nor another render’s, and frameworks relying on localStorage keep working. A grant lasts an hour, and the run page renews it shortly before it ends. Open in a new tab opens the render on its own.

  • Relative paths reach the files of the artifact, and the other artifacts of the run: ../metrics/data.json from /report/index.html reads the artifact metrics.
  • Loads come from the render’s own address and from the storage holding the run’s artifacts. Every other origin, CDNs and web fonts included, is blocked: bundle what the page needs. Inline scripts and styles work.
  • Size: an artifact with an entrypoint holds 50 MB at most.
  • Public renders of public runs are open to anyone, through public grants that only reach public artifacts.

Talking to the Run Page

A render and the run page exchange messages with postMessage. The page accepts those coming from the render’s own origin, and ignores any other.

MessageFromEffect
{ "type": "cadence.ci/height", "height": 640 }RenderSets the height of the frame, in pixels, between 160 and 6000.
{ "type": "cadence.ci/open", "url": "https://example.com" }RenderOpens an http or https link in a new tab.
{ "type": "cadence.ci/ready" }RenderAsks for the theme.
{ "type": "cadence.ci/theme", "theme": "dark" }Run pageGives the theme, light or dark, once the frame is loaded, when asked, and whenever it changes.

A render following the theme and its own height:

const post = (message) => window.parent.postMessage(message, "*") addEventListener("message", (event) => { if (event.source === window.parent && event.data?.type === "cadence.ci/theme") { document.documentElement.dataset.theme = event.data.theme } }) new ResizeObserver(() => { post({ type: "cadence.ci/height", height: document.documentElement.scrollHeight }) }).observe(document.body) post({ type: "cadence.ci/ready" })

Going Further