Skip to content

feat: open Testo HTML reports from the test toolbar - #80

Merged
xepozz merged 10 commits into
j-plugins:mainfrom
roxblnfk:feat/html-report-button
Aug 12, 2026
Merged

feat: open Testo HTML reports from the test toolbar#80
xepozz merged 10 commits into
j-plugins:mainfrom
roxblnfk:feat/html-report-button

Conversation

@roxblnfk

@roxblnfk roxblnfk commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

🔍 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.

image

How it works

  • The button is always live. A report counts as delivered once the process has exited with the file in place and no older than the run — so a stopped run never opens the previous run's report. The icon's colour tells the state: grey with nothing to open, blue once delivered, green while an auto-open stands scheduled.
  • A click before delivery schedules the open and is replayed once the run delivers the file; a second click silences everything for this run behind one flag, leaving the standing checkmarks untouched. The Open in WebView / Open in Browser entries carry independent checkmarks for opening the report unasked — this run only, always in this project, or always everywhere — remembered per report format and name.
  • The path is resolved through the PHP path mapper, then as-is, then as relativePath under the project root, so a report written in a container or behind a remote interpreter stays reachable.
  • Only formats that can be shown as a page get a button; anything else Testo announces is kept but not offered.

Why?

Testo can write an HTML report of a run, and nothing in the IDE led to it.

Review notes

  • intellij.platform.ui.jcef must 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 as 1 missing mandatory dependency in verifyPlugin's report.
  • org.cef is not on the compile classpath, so cefBrowser.reloadIgnoreCache() builds only against a JDK that happens to bundle JCEF (CI's does not). The tab reloads through JBCefBrowser.loadURL instead.

Checklist

  • How was this tested:
    • Tested manually
    • Unit tests added
    • buildPlugin and verifyPlugin pass for both phpApi variants

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
roxblnfk force-pushed the feat/html-report-button branch from c3299d1 to 1376913 Compare August 12, 2026 14:05
@roxblnfk
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>
@xepozz
xepozz merged commit 662ba0a into j-plugins:main Aug 12, 2026
6 checks passed
@roxblnfk
roxblnfk deleted the feat/html-report-button branch August 12, 2026 15:49
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.

2 participants