Publish a live demo report to GitHub Pages on every merge - #458
Conversation
Pages has been enabled on this repository for some time -- build_type "workflow", public, https://xctesthtmlreport.github.io/XCTestHTMLReport/ -- with zero builds ever pushed to it. Meanwhile the README's only pictures of this tool's output are two imgur uploads that predate 4.0 and that nobody here controls or can update. Rendering the sample report from the current tree on every merge to main replaces both problems with one artifact that cannot go stale and cannot be taken down by a third party. The build job reuses .github/actions/fixture-cache-key with the same key and the same paths as test.yml, so a merge normally finds the cache already warm and publishes without booting a simulator at all. Deploy is split onto ubuntu so the macOS runner is released early and so the pages/id-token scopes live only on the job that needs them. Rendered with -i. Verified locally against the release binary: one self-contained 8.6 MB index.html carrying 11 PNGs, 4 mp4s, 9 text attachments and 2 HTML attachments as data: URIs, with no external or relative references at all. The default linking mode emits 460 KB whose src attributes point back into the .xcresult bundle, which would 404 every screenshot and video on the published site. TestResults is the fixture rendered because it is the richest one -- failures, retries, screen recordings, and attachment filenames full of quotes and angle brackets. The demo showing red tests is deliberate: the failure UI is what people come to this tool to look at. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
Warning Review limit reached
Next review available in: 50 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
Comment |
…#463) An attachment filename containing `"` terminated the `data="…"` attribute it was written into, so `<GreaterThan>` from the fixture's hostile filename was parsed as a start tag and entered the DOM. The report is published to a public GitHub Pages URL on every merge (#458), which makes this a stored-injection surface rather than a local-file curiosity. Two halves, because escaping alone is not enough: `stringByEscapingXMLChars` now runs over every leaf value the `HTML` seam substitutes — not just `Attachment`'s, but the titles, log source, device fields and screenshot-flow sources that `Test`, `Iteration`, `Run`, `RunDestination` and `TestScreenshotFlow` contribute. Values that are already rendered markup keep passing through untouched; `HTML.swift` now documents which case a new placeholder falls into, since nothing can enforce it. Escaping cannot fix `onclick="showText('[[SOURCE]]')"`, though: a browser resolves `'` back to `'` before compiling the attribute as JavaScript, so an escaped filename is still a live breakout. The five attachment handlers now read the `data` attribute they already carry instead of interpolating anything — `showText(this.getAttribute('data'))`. `toggle` and `selectDevice` keep interpolating, deliberately: what they pass is an `IdentifierPath.identifier`, a hex digest by construction, and a test pins that shape. The escaping also repairs the feature the injection broke. A truncated `data` attribute meant the preview opened a prefix of the filename; it now opens the file it names. `SummarySeamTests.testHostileAttachmentFilenameDoesNotBreakOutOfAttribute` loses its `XCTExpectFailure` here — an unexpected pass would otherwise fail the suite on a correct fix. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Why
Pages is already enabled on this repo —
build_type: workflow, public,https://xctesthtmlreport.github.io/XCTestHTMLReport/— with zero builds ever pushed to it. Meanwhile the README's only pictures of this tool's output are two imgur uploads (README.md:8,:14) that predate 4.0 and that nobody here controls or can update.Rendering the sample report from the current tree on every merge replaces both with one artifact that can't go stale and can't be taken down by a third party.
What
New
pages.yml: build on macOS → deploy on ubuntu../.github/actions/fixture-cache-keywith the same key and the same paths astest.yml, so a merge normally finds the cache warm and publishes without booting a simulator.pages: write/id-token: writelive only on the job that needs them. Top level stayscontents: read.concurrency: pageswithcancel-in-progress: false— Pages has one live deployment, and a merge landing mid-run should still publish rather than be dropped.README gets one line linking the live report. The stale imgur images are left alone deliberately — replacing them needs a committed screenshot, which is the headless-renderer work, not this.
Verification
Ran the exact workflow command locally against the release binary:
→ one self-contained 8.6 MB
_site/index.html. Served it over HTTP and opened it in a browser: renders correctly (16 tests, 9 passed / 1 skipped / 6 failed, device sidebar populated), and an inlined attachment previews fine from the standalone file. Payloads emitted asdata:URIs:image/pngvideo/mp4text/plaintext/htmlZero external or relative refs. Linking mode would have emitted 460 KB whose
srcattributes point back into the.xcresult, 404ing every screenshot and video on the published site.zizmor --min-severity lowandactionlintboth clean.Note
The demo will show failing tests.
TestResults.xcresultdeliberately contains failures, retries, and attachment filenames full of quotes and angle brackets. That's the point — the failure UI is what people come to this tool to look at — but it's public and permanent, so flagging it explicitly.🤖 Generated with Claude Code