10 KiB
Executable File
title, date, tags, status
| title | date | tags | status | ||||
|---|---|---|---|---|---|---|---|
| macOS tests: worktrees from the 2026-10-14 session | 2026-10-14 |
|
in-progress |
macOS tests: worktrees from the 2026-10-14 session
All worktrees are in /Users/admin/DuckDuckGo/apple-browsers.git/<name>, on branch alex/<name>. Nothing is committed.
Summary
| Worktree | Created from | Purpose | Status |
|---|---|---|---|
macos-unit-tests-no-app-delegate |
origin/main ca834f869a |
Unit tests no longer use the app delegate, buildable folder, test plans | Done, not committed |
fix-address-bar-tests-flakiness |
origin/main ddb1a82283 |
Fix flaky AddressBarTests: mocks plus two leak root causes |
Done, not committed |
fix-ask-ai-chat-button-animation-leak |
origin/main e698211924 |
Ask AI Chat button animation leak plus regression test | Done, not committed |
animation-leak-audit |
origin/main e698211924 |
Audit NSAnimationContext completion handlers for leaks |
Done: no leaks found; worktree and branch removed |
fix-fire-window-video-leak |
origin/main e698211924 |
Video keeps playing after a Fire Window is closed: reproduce, fix, regression test | Not reproduced: 4 guard tests only, no fix (see update below) |
spm-browser-tests (existing) |
— | Source of the unit-test changes (SwiftPM variant) | Not changed |
macos-unit-tests-no-app-delegate
Branch alex/macos-unit-tests-no-app-delegate. 207 files changed, +5553/−7870 lines of uncommitted changes. Most of the deletions are pbxproj entries.
- Ported from
spm-browser-tests. Four commits (915209f987, d22aa6ca14, 966cad8578, 7f39ce3952) take the unit tests off the app delegate, move tests that build a main window to the integration tests, and skip disabled tests in code. The commit that turns the app into a Swift package was left out. Unit Tests stays an Xcode target. macOS/UnitTestsis a buildable folder (pbxproj objectVersion 70), with exceptions for the 12 files main never compiled.DataImportResourcesis listed inexplicitFolders.privacy-reference-testsstays a folder reference.
- Test plans:
UnitTests/Unit Tests.xctestplan,TestPlans/macOS Browser.xctestplan, andTestPlans/macOS Browser App Store.xctestplan. They set language en/US, keep code coverage, and keep the App Store skip. - No app delegate in unit tests: for
runType == .unitTests,Application.initcreates neitherAppDelegatenor the main menu, so any access to the delegate crashes.- Every place unit tests still reached the delegate was found with a trace and a default-argument scanner, then given a mock.
- App code takes those dependencies as parameters that default to the app's values: AIChat omnibar, PermissionAuthorizationView, BookmarkManagementDetailViewController, BookmarksEmptyStateView, SyncDeviceButtonModel, NewTabPageCoordinator/ActionsManager, NewTabPageOmnibarActionsHandler, and others.
open(_ bookmark:)andopen(_ historyEntry:)moved into theWindowControllersManagerProtocolextension.BookmarksBarShownTriggerTestsmoved to the integration tests.
- No network in unit tests:
allowsUpdatesis false for unit tests, so there is no Sparkle appcast check, andSuggestionContainerTestsuses a URL session mock. - Results:
- Unit: all pass except 10 snapshot tests, which require macOS 27 (this machine runs 26.7.1).
- Full plan: 9484 passed. Besides the snapshot tests, 6
AddressBarTestsfail; they also fail on origin/main and are fixed in the next worktree. - App Store scheme builds.
- swiftlint --strict is clean on 315 files.
- Note: the privacy-reference-tests submodule had to be initialized in this worktree.
fix-address-bar-tests-flakiness
Branch alex/fix-address-bar-tests-flakiness. 3 files, +100/−6.
- Root cause: the tests didn't actually hang. In DEBUG,
ensureObjectDeallocated(... .interrupt)sends SIGINT when an object is still alive. Two causes:TestRunHelperreadNSApp.windows, which autoreleased the address bar's suggestions window. Fixed withautoreleasepool.- The
animateAskAIChatButtonContraction()completion handler capturedselfstrongly. Fixed with[weak self]. The audit refined this finding: it isn't a permanent leak. While the display is asleep, the completion is held until it wakes.
- Mocks and settings in
AddressBarTests:- OHHTTPStubs answers
duckduckgo.com/ac/and blocks all other external network. - AI Chat settings are pinned in
NSArgumentDomain. - The user's settings are saved and restored.
- OHHTTPStubs answers
- Results:
- Isolated: 7 out of 7 runs with 0 failures and 0 restarts. Before the fix, origin/main had 1–6 failures per run.
- Full Integration Tests ×2: 0 AddressBarTests failures.
- The 3 remaining failures also fail on main because of this machine's settings: FireCoordinator (locale) and NTP search (
aichat.enabled=0).
- The comment in
AddressBarButtonsViewControllerwas reworded on 2026-10-15 to say the completion is held until the animation ends. The handler change is now identical to the one infix-ask-ai-chat-button-animation-leak.
fix-ask-ai-chat-button-animation-leak
Branch alex/fix-ask-ai-chat-button-animation-leak, based on origin/main e698211924. Done, not committed. 2 files, +63/−3.
- Fix in
AddressBarButtonsViewController.animateAskAIChatButtonContraction():[weak self]plusguard let self.- The comment explains why: the completion is deferred until the animation ends, indefinitely while the display link is paused.
isAskAIChatButtonExpandedchanged fromprivatetoprivate(set)so the test can read it.- The rest of the file was checked: the expansion animation has no completion handler, and the
asyncAfterandsinkclosures already use[weak self].
- Regression test:
AddressBarTests.testWhenWindowIsClosedWhileAskAIChatButtonContracts_windowObjectsAreDeallocated.- It sets text in the address bar so the button expands, then calls
makeFirstResponder(nil)to start the contraction. - In the same autorelease pool, it closes and releases the window.
- It immediately asserts that
AddressBarButtonsViewControllerandTabCollectionViewModelare released. There are no sleeps or waits, so the result doesn't depend on display state.
- It sets text in the address bar so the button expands, then calls
- Results:
- main: 10/10 FAIL (5 with the display awake, 5 asleep).
- fix: 15/15 pass (asleep, awake, and
-test-iterations 5). - Full
AddressBarTests: 0 failures.test_WhenControlTextDidChange…sometimes crashes with SIGINT; that is theTestRunHelperautorelease problem fixed infix-address-bar-tests-flakiness. - Lint: 0.
- Overlap:
fix-address-bar-tests-flakinesscontains the same handler fix (the comment was aligned on 2026-10-15; the change is identical). Whichever lands first, the other must drop or rebase this hunk.
animation-leak-audit (removed)
Checked with standalone AppKit harnesses (in the session scratchpad: scratchpad/anim/exp*.swift). No permanent leaks were found, and the code was not changed. The worktree and branch were removed.
- Key finding: AppKit does call
runAnimationGroupcompletion handlers after the window is closed.- Animations of a view's
alphaValue/frame,performBatchUpdates, andscrollalways complete. - Display-link-driven animations (
NSLayoutConstraint.animator().constant,NSWindow.animator().alphaValue) stall while the display is asleep. Their completion, along with any strong captures, is held until the display wakes. - This Mac has
displaysleep 10, so its display is often asleep. That explains the flaky dealloc checks in tests.
- Animations of a view's
- Checked, no leaks found:
NavigationBarBadgeAnimator(alpha only, no view controller or window captured).BrowserTabViewController.dismissCookiePopupProtectionOptInDialog(alpha only,selfnot captured).AIChatCoordinator.transitionSidebarandTabBarViewController(weak captures, or completions that always run).PromptBarPresenter.dismiss,CircularProgressView,SpinnerView,JSAlertController, and others.
fix-fire-window-video-leak
Branch alex/fix-fire-window-video-leak. Not reproduced; see the update below.
Temporary and source worktrees
spm-browser-tests(alex/spm-browser-tests) is the existing source of the unit-test changes. Not changed.- A detached origin/main baseline in the session scratchpad was used to compare integration tests and has been removed.
Update 2026-10-15: fix-fire-window-video-leak
Status: not reproduced, no fix.
-
Worktree:
fix-fire-window-video-leak, branchalex/fix-fire-window-video-leak, based on origin/maine698211924. -
Changes: only
macOS/IntegrationTests/Fire/FireWindowClosingTests.swift(+153), with four synchronous guard tests:- closing a Fire Window with media playing;
- closing it via the Fire popover;
- closing the last tab in a Fire Window;
- a regular window, for comparison.
The media is a generated 440 Hz WAV served from
https://media.testthroughTestSchemeHandler, so no network is involved. All the tests pass on main (35/35 with the display asleep, 7/7 with it awake), so they are guard tests, not regression tests. -
What was tried:
- Content:
data:audio,httpsvideo, and a real H.264/AAC mp4. - Close paths:
performClose/ Cmd+Shift+W, the Fire popover close action (directly and through the realFireCoordinator), Cmd+W on the last tab, and removing the tab. - Conditions: a background tab, the Lottie fire animation, the display asleep and awake.
In every case the Tab, WebView and window were released within 1–3 s, and media stopped.
- Content:
-
How the check was validated: with a deliberate Tab leak added in
animateBurningIfNeededAndClose, the test failed. -
Findings:
asynctests mask releases: objects live until the test ends. The guard tests are synchronous for this reason.DeallocationTests.testWhenLastTabClosed_windowIsDeallocatedcrashes the test host when the display is asleep (probablyTabPreviewWindowController) and passes when it is awake. This is a separate display-sleep flake.
-
Manual check in the app: not possible, because
osascripthas no Accessibility access. -
Next steps: get the exact user steps (which site, PiP or fullscreen, a popup from the Fire Window, how the window was closed), or reproduce it by hand in a Debug build. The DEBUG deallocation checks will trigger on a leak.