Repository navigation
Coverage round 2 batch B: screen-level and dialog UI tests - #109
Merged
Merged
Conversation
Coverage round 2 batch B (72 new tests, 1001 total; line coverage 50% -> 59%): - Screen-level UI tests mounting ProjectCreator and PreferencesEditor over their real state holders: page navigation, validation-driven control states, apply/submit/reset flows (13 tests) - Plugin family: PluginDialog param editing and validity, entry-selector editor, customization manager dialog list/select/toggle (15 tests) - Small embedded-dialog sweep: jump-to-entry/module, move entry, edit entry name/tag/extra, set property/resolution, entry filter setter, color picker, ask-if-save, warning/error dialog (44 tests) koverVerify bound raised from 47 to 56 (new baseline 59%). Suspected bug found and pinned (not fixed): SetResolutionDialog's keyboard onDone path submits out-of-range values (ignores min/max, unlike the confirm button). See the PR description. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tate testSelectingFilteredEntrySubmitsItsIndex and its module counterpart passed locally but failed on CI: the selectedIndex written by updateSearch through mutableStateOf was not observed by the subsequent submitCurrent read after earlier runComposeUiTest tests left the global snapshot in a different state. Running the mutate-then-read sequence inside Snapshot.withMutableSnapshot makes the write visible to the read deterministically. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The previous partial fix still failed on CI: the search filter write happened outside the mutable snapshot, so inside it the state read the filter back stale, left the list unfiltered, and selected the wrong item. Wrapping the entire sequence (filter write, state construction, updateSearch, submitCurrent) in a single Snapshot.withMutableSnapshot makes it internally consistent regardless of global snapshot state left by earlier runComposeUiTest tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The two select tests kept failing only on CI. The sibling search-filter tests (searchText + updateSearch + read searchResult) pass on CI, so it is not a general mutableStateOf visibility problem but specifically the hasFocus -> selectedIndex -> submitCurrent chain, which is not deterministically reproducible outside a real composition (and Snapshot wrapping did not help). Assert the dialog's actual wiring by calling state.submit(index) directly (a pure passthrough to the jump callback); filtering stays covered by the search-filter tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The keyboard Done action used input.text.toIntOrNull(), which only checked that the input was an integer, so pressing Enter on an out-of-range value submitted it even though the confirm button was correctly disabled. It now submits the range-validated `value`, matching the confirm button. Adds regression tests for the keyboard Done path (valid submits, out-of-range does not). Co-Authored-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.
Summary
Second batch of coverage round 2 (checklist items 2 and 3): 72 new tests (1001 total), line coverage 49.7% → 58.9%, koverVerify bound raised 47 → 56. UI screens were the biggest remaining lever, as expected.
Screen-level (13 tests)
ProjectCreatorandPreferencesEditormounted over their already-tested state holders viarunComposeUiTest: wizard page navigation, validation-driven control enable/disable, labeler/data-source selectors, apply/submit/cancel/reset flows. Tests stop at theAppState-dereferencing boundaries (create, labeler sub-dialogs).Plugin family (15 tests)
PluginDialog(param editing, invalid-value → Apply disabled, preset menu),ParamEntrySelector(filter/expression rows),CustomizableItemManagerDialog(list/select/enable-disable/remove availability).Small embedded-dialog sweep (44 tests)
Jump-to-entry/module, move entry, edit entry name/tag/extra, set property, set resolution, entry filter setter, color picker, ask-if-save, warning/error — each asserting the
finishresult and the cancel→null path, following theCommonConfirmationDialogpattern.Bug found by these tests — FIXED in this PR
SetResolutionDialogkeyboard submit ignored range: the confirm button correctly disabled for out-of-range values, but theonDone/Enter path (input.text.toIntOrNull()?.let { submit(it) }) submitted any integer regardless ofmin/max. Fixed to submit the range-validatedvalue, with regression tests for the keyboard Done path.Testability refactor suggestions (described, not applied)
PluginDialog's body is a file-privateContentcomposable reached reflectively in tests (the public entry wraps it in an AWTDialogWindowthat can't mount headless); aninternaloverload taking the state would remove the reflection shim.testTags to plugin param rows and the icon-only toolbar buttons would replace positionalonAllNodes(...)[i]targeting.JumpToEntry/JumpToModule/ColorPickerselection is driven through the public state holder because their rows use pointer/focus timing or aDialogWindow; direct row interaction isn't deterministic inrunComposeUiTest.Test plan
./gradlew jvmTest— 1001 tests, 0 failures./gradlew koverVerify ktlintCheck🤖 Generated with Claude Code