Skip to content

fix(ui): open S3-hosted files via redirect instead of the JSON envelope - #277

Merged
skylenet merged 1 commit into
masterfrom
fix-s3-fill-report-links
Jul 9, 2026
Merged

fix(ui): open S3-hosted files via redirect instead of the JSON envelope#277
skylenet merged 1 commit into
masterfrom
fix-s3-fill-report-links

Conversation

@skylenet

@skylenet skylenet commented Jul 9, 2026

Copy link
Copy Markdown
Member

Problem

On the suite details Source tab, the EEST Build Metadata "Fill report" buttons (and the embedded report iframe) opened a page showing a raw JSON payload instead of the report, when the API is enabled with files on S3:

{"url":"https://benchmarkoor-results.….r2.cloudflarestorage.com/…/report_fill.html?X-Amz-Algorithm=…&X-Amz-Signature=…"}

Root cause

In S3 + API mode the /api/v1/files/... endpoint returns a {"url": <presigned>} JSON envelope by default — intended for programmatic fetch (the client parses .url and fetches it). It only 302-redirects to the presigned URL when ?redirect=true is set (added precisely so <a href> / curl -L work).

Several components built direct-navigation targets straight from getDataUrl(...), so in S3 mode the browser navigated to the envelope endpoint and rendered the JSON:

  • EEST Build Metadata (suite Source tab): "Open fill report", "View fixture index (JSON)", and the embedded fill-report <iframe>.
  • State-actor config files: the "Open raw" link.

FilesPanel already worked around this by inlining ?redirect=true in S3 mode — so the fix pattern was already established, just not applied consistently.

Fix

Extract the pattern into a shared getNavigableDataUrl() helper and route all direct-navigation URLs (anchor href, iframe src, download links) through it. In S3 + API mode it appends ?redirect=true so the browser follows the 302 to the presigned URL and loads the actual file; local mode serves bytes directly and is untouched (no redirect appended). FilesPanel's two inline copies are de-duplicated onto the helper.

Verification

  • tsc -b typecheck, eslint, and full vite build all clean.
  • Local mode unaffected (helper only appends redirect=true when isS3Mode && api.baseUrl).

Note: presigned relative assets inside the report HTML are a separate, pre-existing limitation and out of scope — this restores the report itself loading instead of showing JSON.

In S3 + API mode the /files endpoint returns a {"url": <presigned>} JSON
envelope by default (for programmatic fetch), and only 302-redirects to the
presigned URL when ?redirect=true is set. Several direct-navigation links built
their href/src straight from getDataUrl, so in S3 mode they opened a page
showing the JSON envelope instead of the file:

- EEST Build Metadata (suite Source tab): "Open fill report", "View fixture
  index (JSON)" and the embedded fill-report iframe.
- State-actor config files: the "Open raw" link.

FilesPanel already worked around this by inlining `?redirect=true` in S3 mode.
Extract that into a shared getNavigableDataUrl() helper and route all
direct-navigation URLs through it, so the browser follows the 302 to the
presigned URL and loads the actual file. Local mode serves bytes directly and
is unaffected (no redirect appended).
@skylenet
skylenet merged commit 3a780ef into master Jul 9, 2026
7 checks passed
@skylenet
skylenet deleted the fix-s3-fill-report-links branch July 9, 2026 15:10
skylenet added a commit that referenced this pull request Jul 9, 2026
…278)

## Problem

Follow-up to #277. With the report links now redirecting to the
presigned S3 URL, the EEST fill report opened/embedded **unstyled**. The
pytest-html report links its stylesheet **relatively**:

```html
<link href="assets/style.css" rel="stylesheet" type="text/css"/>
```

When the report loads from a presigned S3 URL
(`…/report_fill.html?X-Amz-Signature=…`), the browser resolves
`assets/style.css` to an **unsigned** S3 URL → **403** on the private
bucket → no styling. (Verified against a real report: it's pytest-html,
one inline `<script>`, and a single external asset `assets/style.css`.)

## Fix

Add `--self-contained-html` to `PYTEST_ADDOPTS` for the fill run.
pytest-html then **inlines the CSS** into `report_fill.html`, so the
report is a single self-contained file with **no `assets/` references**
and renders fully styled from any URL — including the presigned S3 URL
and the iframe embed.

EEST's filler plugin only sets `htmlpath` (`.meta/report_fill.html`) and
does **not** set `self_contained_html`, so the flag is honored
(confirmed in `execution-specs` `filler.py`). The JS is already inline,
so nothing else needs bundling.

## Why this over a server-side proxy

The alternative — streaming the report + its assets through the API so
relative URLs resolve on the API origin — would serve our HTML
**same-origin as the API**, giving up the origin isolation the presigned
S3 URL provides (the report can't touch API cookies from the S3 origin).
Fixing it at generation time keeps that isolation, needs no new route,
and removes the sub-resource entirely instead of proxying it.

## Scope

- Applies to **newly filled** fixtures. Existing reports already on S3
keep their relative `assets/` link until their next build re-generates
the report.
- No behavior change for the JSON sidecars or fixtures — only the
pytest-html report output format.

`go build` + golangci-lint (`--new-from-rev=origin/master`) clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant