Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,10 @@ the complete runner log, privacy-safe app breadcrumbs, and always-kept visual
and element-state checkpoints for successful as well as failed tests. The
checkpoint PNGs and text files are also extracted into a directly browsable
`checkpoints/` directory.
Menu-bar clicks use a scoped, private XCTest event-confirmation timeout to avoid
its five-second wait for a missing mouse-up acknowledgement. The normal timeout
is restored after each toggle, and app-idle and panel-readiness checks remain
enabled. The helper fails explicitly if an Xcode update removes the required API.
The same suite runs on a GitHub-hosted macOS runner for every pull request and
push to `main`, so it does not use the local mouse or interrupt local work.

Expand Down
37 changes: 35 additions & 2 deletions UITests/DaylineUITests/DaylineUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ final class DaylineUITests: XCTestCase {
if statusMenuIndicator.exists {
let statusItem = app.descendants(matching: .statusItem)["dayline.menuBarItem"].firstMatch
XCTAssertTrue(statusItem.waitForExistenceIfNeeded(timeout: 3))
statusItem.click()
try clickMenuBarItem(statusItem)
waitForRemoval(statusMenuIndicator)
}
app.activate()
Expand Down Expand Up @@ -890,10 +890,43 @@ final class DaylineUITests: XCTestCase {
return
}

statusItem.click()
try clickMenuBarItem(statusItem)
XCTAssertTrue(element("dayline.refresh").waitForExistenceIfNeeded(timeout: 5))
}

private func clickMenuBarItem(_ statusItem: XCUIElement) throws {
// MenuBarExtra clicks don't acknowledge XCTest's mouse-up event, so its default
// confirmation timeout adds five seconds even after the panel is ready. This
// private XCTest setting changes only that timeout; idle/readiness checks remain.
let sessionClass = try XCTUnwrap(
NSClassFromString("XCTRunnerDaemonSession") as? NSObject.Type,
"This Xcode version no longer exposes the UI automation session"
)
let sharedSession = NSSelectorFromString("sharedSession")
guard sessionClass.responds(to: sharedSession) else {
XCTFail("This Xcode version no longer exposes the shared UI automation session")
return
}
let session = try XCTUnwrap(
sessionClass.perform(sharedSession)?.takeUnretainedValue() as? NSObject
)
let key = "implicitEventConfirmationIntervalForCurrentContext"
let overrideKey = "implicitEventConfirmationIntervalForCurrentContextWithoutSideEffects"
guard session.responds(to: NSSelectorFromString(key)),
session.responds(to: NSSelectorFromString("setImplicitEventConfirmationIntervalForCurrentContextWithoutSideEffects:")) else {
XCTFail("This Xcode version no longer supports the scoped menu click confirmation timeout")
return
}
let previousInterval = try XCTUnwrap(session.value(forKey: key) as? NSNumber)
// The ordinary setter restores only at test teardown, not at activity end.
// Restore explicitly so subsequent clicks retain XCTest's normal confirmation.
defer { session.setValue(previousInterval, forKey: overrideKey) }
XCTContext.runActivity(named: "Toggle menu bar panel") { _ in
session.setValue(0.1, forKey: overrideKey)
statusItem.click()
}
}

private func element(_ identifier: String) -> XCUIElement {
app.descendants(matching: .any)[identifier].firstMatch
}
Expand Down
Loading