feat: open Testo HTML reports from the test toolbar - #80
Merged
Conversation
fix: keep the run clock stopped when the process outlives the output buffer A run that exits in under a second gets processTerminated before the platform has worked through its output, so onTestingStarted arrived after the clock had already been stopped, was read as a second session, and restarted a clock that nothing was left to stop. The new-session gate is now the results form's own finish event, whose two events are ordered per session. Testo announces every report it writes with `##teamcity[testoReport …]`, before the first test — after the root suite closes the platform stops feeding the converter, so anything later would vanish. The button therefore waits for the file itself and an activity bump after the run re-asks about it, and it stays visible-but-disabled because RunTab snapshots the toolbar's actions and a button hidden at that moment never gets a component. Only formats the button can show as a page are offered; the store keeps the rest so a coverage report can later fill the Coverage tool window instead. JCEF is declared for both platforms (bundled plugin on 262, monolith module on 252) yet asked for by reflection: a named reference to an absent JBCefApp throws at class verification, before any try can catch it, which took the whole action group down with it. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The toolbar has to show the name Testo announces, and no stock widget could: a plain button draws the icon alone and leaves the text as a tooltip, SplitButtonAction paints its own component without any text, ComboBoxAction turns the first click into a dropdown, and an expanded ActionGroup loses RightAlignedToolbarAction so its children land among the buttons on the left. Hence a panel of hand-drawn cells inside a single right-aligned action, the way the run summary beside it already works. The panel exists from the start and hides itself while empty, because RunTab snapshots the toolbar's actions; each cell polls for its file, which is what distinguishes announced-but-unwritten from ready and turns a button off again if the report is deleted. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A report is announced when Testo starts writing it, over the path the previous run wrote to — so checking the disk during the run found that run's report and offered it as this one's, with the button already enabled at startup. The check now waits for processTerminated, and a second session in the same console puts the flag back. fix: no raw NUL in TestoReportStore `|x` unescaped to U+0000 rather than U+0085, and having the character in the source verbatim made git read the whole file as binary. Written as an escape, alongside the `|l`/`|p` that were missing. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The NUL that separates channel from label was in the source verbatim; as an escape it is visible in a diff and cannot be lost to an editor. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…uild loading fix: reload the report through JBCefBrowser instead of org.cef fix: read a report announcement off raw output as well refactor: drop the debug logging left around the report button perf: refresh a report cell only when its state changed docs: state the report notes as rules rather than as what was fixed intellij.platform.ui.jcef lives inside 262s bundled JCEF plugin, and on 252 JCEF is part of the monolith and needs no declaration at all, so naming the module in the shared <dependencies> left the 252 artifact with a missing mandatory dependency. verifyPlugin now reports Compatible on IU-252/253/261 and IU-262. org.cef is absent from the compile classpath: cefBrowser.reloadIgnoreCache() built only against a JDK that happens to bundle JCEF, which CIs Zulu 21 does not. TestoReportRef.fromServiceMessageLine was never called, so an announcement behind a colour escape reached the console as plain text and was lost. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A stopped run kills Testo before it rewrites the report, and the path never changes between runs, so the file already sitting there was enabling the button as if it belonged to the run just cancelled. It now has to be no older than the run start, which also covers a Testo that died before its reporter ran. The mark is floored to a whole second: a filesystem that keeps mtime at that granularity would date a report written moments after the start before it. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
feat: the report menu shows the file in the file manager The choices — WebView and browser independently, for this run, this project or every project — are keyed by the report's format and name, its identity across runs. The button stays live the whole run: a click before delivery arms the open, a second click silences everything for this run behind one flag without unchecking the standing choices. The icon's colour carries the state: grey with nothing to open, blue once delivered, green while an open stands scheduled. Assisted-By: Claude Fable 5 <noreply@anthropic.com>
roxblnfk
force-pushed
the
feat/html-report-button
branch
from
August 12, 2026 14:05
c3299d1 to
1376913
Compare
roxblnfk
marked this pull request as ready for review
August 12, 2026 14:08
Digits are measured and drawn in tabular slots — every digit takes the widest digit's width — so the row moves only when a count gains a digit. Java2D cannot ask an arbitrary font for tabular figures itself. Assisted-By: Claude Fable 5 <noreply@anthropic.com>
The mapper's answer spelled the project-relative form, which on Linux is the same string, so the dedup folded the two and the list came up short. Assisted-By: Claude Fable 5 <noreply@anthropic.com>
… the constraints Assisted-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔍 What was changed
One button per report Testo announces with
##teamcity[testoReport …], at the far right of the test toolbar, labelled with the announced name. A click opens the report in a JCEF editor tab; the arrow on it offers the external browser, the file manager, and copying the path.How it works
relativePathunder the project root, so a report written in a container or behind a remote interpreter stays reachable.Why?
Testo can write an HTML report of a run, and nothing in the IDE led to it.
Review notes
intellij.platform.ui.jcefmust not be named in<dependencies>: that form is mandatory, and the module exists only inside 262's bundled JCEF plugin, so the 252 artifact stops loading entirely. Nothing fails at build time — it surfaces only as1 missing mandatory dependencyinverifyPlugin's report.org.cefis not on the compile classpath, socefBrowser.reloadIgnoreCache()builds only against a JDK that happens to bundle JCEF (CI's does not). The tab reloads throughJBCefBrowser.loadURLinstead.Checklist
buildPluginandverifyPluginpass for bothphpApivariants