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:
| Entrypoint | Shown as |
|---|---|
| Image: PNG, JPEG, GIF, WebP, AVIF, SVG | The image. SVG files are shown as images, where their scripts never run. |
| Markdown | Formatted 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. |
| JSON | A table for an array of objects, a table of keys and values for an object, indented JSON otherwise. |
| CSV, TSV | A table of the first 1,000 rows. |
| Other text | The text as it is. |
| HTML | The 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.jsonfrom/report/index.htmlreads the artifactmetrics. - 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.
| Message | From | Effect |
|---|---|---|
{ "type": "cadence.ci/height", "height": 640 } | Render | Sets the height of the frame, in pixels, between 160 and 6000. |
{ "type": "cadence.ci/open", "url": "https://example.com" } | Render | Opens an http or https link in a new tab. |
{ "type": "cadence.ci/ready" } | Render | Asks for the theme. |
{ "type": "cadence.ci/theme", "theme": "dark" } | Run page | Gives 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
- Run Artifacts: pushing artifacts, access and retention.
- Storage: the CORS rules renders need on a bucket of your own.
- View Results: the rest of the run page.