Skip to content

test(ui): each on-display UI test gets its own config directory, so a --gtest_repeat run never opens on the layout the last one saved (#2932) - #2941

Merged
mgradwohl merged 1 commit into
mainfrom
test/2932-scenario-config-isolation
Oct 25, 2026
Merged

mgradwohl merged 1 commit into
mainfrom
test/2932-scenario-config-isolation

Conversation

@mgradwohl

Copy link
Copy Markdown
Owner

Description

Each --gtest_repeat iteration of UiScenarioTest used to open on the Processes table layout the previous iteration saved to config.toml on close. PID got 40 px wider every time until its right border was out of view, and from then on every other iteration failed. #2931 worked around this in the resize step by narrowing PID once it was wide. This PR isolates each test's config instead.

  • tests/App/ScratchConfigDir.h (new): TestSupport::ScratchConfigDirTest, a gtest fixture.
    • SetUp() makes a new, empty temporary directory. It points Core::ConfigDirOverride::active() at that directory (each Core::Application's PathService reads it; the user themes folder lives there). It also points UserConfig at it with resetConfigPathForTesting(), so config.toml is read from there and every setting starts at its default.
    • TearDown() puts back the previous override, the previous config path and the previous settings, then removes the directory.
  • Why not just reset the variable: TASKSMACK_CONFIG_DIR is read once per process (active() caches it, and UserConfig is a singleton that keeps the path it built from it), so setting the variable again would change nothing. The variable itself isn't touched, so it has nothing to restore.
  • Background saves ([Perf] UserConfig::save() on a Settings click runs on the UI thread (#2731 leftover) #2916/fix(app): settings saves from the UI are written by a worker, coalesced, and flushed at exit (#2916) #2930): resetConfigPathForTesting() waits for a background save that is queued or being written before it repoints, so nothing can write into the directory after TearDown removes it. ShellLayer::onDetach() has also already saved synchronously by then, because the test's Core::Application is destroyed inside the test body, before TearDown runs.
  • src/Core/ConfigDirOverride.{h,cpp}: the value active() returns is now a function-local static that can be changed, behind a new setActiveForTesting() seam. It is documented as test-only and not thread-safe (call it only while no Application or worker is running). Behaviour without the seam is the same: the variable is read on first use, the path is made absolute and the directory is created.
  • UiScenarioTest and UiLayersOnDisplayTest: both now derive from the fixture, so TEST becomes TEST_F. Suite names don't change, so the ctest SUITE_PROPERTIES (synthetic machine, RUN_SERIAL) still apply. UiLayersOnDisplayTest runs in the same process and shares the same UserConfig, and three of its tests save or read config there. Its first-run golden test no longer has to empty the shared directory by hand: it now checks that the fixture gave it an empty one.
  • test(ui): the sign-off scenario's drag and key steps retry from fresh geometry until they take, so a late layout can't time them out (#2906) #2931's workaround removed: the column-resized step no longer narrows PID. With isolation, PID always starts at its default width, so the step always widens it by 40 px. Nothing else needed the workaround.

Fixes #2932

PR Size

Medium: 210 lines changed (170 added, 40 removed), most of it the new fixture header and the 15 TEST to TEST_F renames.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Build/CI improvement (test isolation; the only src/ change is a test-only seam)

Checklist

  • I have read the CONTRIBUTING guidelines
  • My code follows the project's coding standards
  • I have run clang-tidy and addressed any warnings (on the touched .cpp files: no findings in the new or changed code. The local clang-tidy also reports readability-trailing-comma on unchanged steps.push_back({...}) initializers and MSVC STL analyzer noise, both already there on main.)
  • I have run clang-format on my changes
  • I have run pre-commit run --all-files or installed pre-commit hooks (pre-commit run --files on the touched files, plus the commit hook)
  • I have added tests that prove my fix/feature works (the repeat run below is the proof)
  • All new and existing tests pass
  • I have updated documentation as needed (comments in AppTestsMain.cpp and ConfigDirOverride.h)

Testing

Windows 11, win-debug:

cmake --build --preset win-debug -j 4
$env:TASKSMACK_SYNTHETIC = 'processes=120,seed=2711'
build\win-debug\tests\TaskSmackAppTests.exe --gtest_filter=UiScenarioTest.* --gtest_repeat=30
ctest --preset win-debug -R "UiLayersOnDisplayTest|UiScenarioTest|ConfigDirOverride|EnvHooks"
build\win-debug\tests\TaskSmackAppTests.exe --gtest_filter=UiLayersOnDisplayTest.* --gtest_repeat=3
build\win-debug\tests\TaskSmackAppTests.exe --gtest_filter=-UiScenarioTest.*   # every other app suite in one process
Run Result
Before: origin/main with #2931's narrowing turned off, --gtest_repeat=30 24/30. Runs 1-18 pass, then 19, 21, 23, 25, 27 and 29 fail in column-resized: PID is 826 px wide on run 19 and 40 px wider on each failure after, its right border at x=1304 against the table's 1234.
After: this branch, workaround removed, --gtest_repeat=30 30/30, no tasksmack_test_config_* directories left in %TEMP%
ctest -R UiScenarioTest pass
UiLayersOnDisplayTest once (ctest) and --gtest_repeat=3 15/15 each time
All other TaskSmackAppTests suites in one process 24 pass; 2 AccessNoticeOnDisplayTest tests skipped, as on main (they need an Administrator session)
ConfigDirOverrideTest, EnvHooksTest pass

Additional Notes

  • The other on-display suites in TaskSmackAppTests (ScreenshotOnDisplayTest, AccessNoticeOnDisplayTest, SettingsThemeApplyTest) still use AppTestsMain.cpp's directory, as before. The fixture can be adopted there later if they ever need it.
  • No backport label: this is test infrastructure for v0.10.0.

🤖 Generated with Claude Code

… --gtest_repeat run never opens on the layout the last one saved (#2932)

UiScenarioTest and UiLayersOnDisplayTest now derive from
TestSupport::ScratchConfigDirTest (tests/App/ScratchConfigDir.h). SetUp()
makes a new, empty temporary directory and points both
Core::ConfigDirOverride::active() (new setActiveForTesting() seam; what each
Core::Application's PathService reads) and UserConfig
(resetConfigPathForTesting(): config.toml, settings back to defaults) at it.
TearDown() restores both and the settings, then removes the directory;
resetConfigPathForTesting() first waits for a queued or in-flight
background save (#2916), so nothing writes into the directory once it is
gone.

With isolation, #2931's narrowing workaround in the column-resized step is
gone: PID always starts at its default width and is widened 40 px.

Before (workaround disabled, shared config): --gtest_repeat=30 passed runs
1-18, then failed 19, 21, 23, 25, 27 and 29 (PID 826 px and wider, its
right border out of view). After: 30/30.

Fixes #2932

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mgradwohl mgradwohl added this to the v0.10.0 milestone Oct 25, 2026
@mgradwohl mgradwohl added testing agent:Windows Owned by the Windows Claude session (bug-fix conveyor) labels Oct 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@mgradwohl
mgradwohl merged commit 7272473 into main Oct 25, 2026
32 checks passed
@mgradwohl
mgradwohl deleted the test/2932-scenario-config-isolation branch October 25, 2026 19:14
@mgradwohl mgradwohl mentioned this pull request Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:Windows Owned by the Windows Claude session (bug-fix conveyor) testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Testing] The on-display UI scenario suites share one config dir across --gtest_repeat runs, so the table layout a run saves skews the next

1 participant