Hi,
I am working on an agent app.
The app has a menubarextra.
var body: some Scene {
MenuBarExtra(
"menubarextra", systemImage: "star")
{
Button("Item 1") {
}
Button("Item 2") {
}
Button("Item 3") {
}
}
}
I am going to write xctest to click on the icon i created and want to click on the menu next.
func testExample() throws {
// UI tests must launch the application that they test.
let app = XCUIApplication()
app.launch()
let menuBarsQuery = XCUIApplication().menuBars
let favouriteStatusItem = menuBarsQuery.statusItems["Favourite"]
favouriteStatusItem.click()
menuBarsQuery.menuItems["Item 1"].click()
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
There is a small problem. When the app is not a agent app, the app will start with with its own menu bar. If i am currently on fullscreen, it will swap to the desktop and the menubar will be showing the app's menu bar. In this case, I can see the menubarextra. The test will pass then.
When it is in agent app, the above behaviour will not happen. Once I run the test with fullscreen mode of xcode, my screen will still stay on xcode and the statusbar will not be showing. Then the test will response
error: -[swiftuitestUITests.MenubarExtraTests testExample] : Element StatusItem, {{1080.0, 6.5}, {34.5, 24.0}}, title: 'Favourite' is not hittable
The only solution I can found at the moment is to leave fullscreen first, then run the test.
In xctest, is there any way to force the statusbar to show first? Thank you!
I can find a solution but it is not very nice. It seems there is no API to trigger the statusbar directly.
The following is suggested by ChatGPT
import XCTest
import CoreGraphics
func moveMouseToTop() {
let screenHeight = NSScreen.main?.frame.height ?? 900
let topPoint = CGPoint(x: 100, y: 2) // Move near the top edge
let move = CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: topPoint, mouseButton: .left)
move?.post(tap: .cghidEventTap)
}
class StatusBarTests: XCTestCase {
func testClickStatusBarIcon() {
let app = XCUIApplication(bundleIdentifier: "your.app.bundle.identifier")
app.launch()
moveMouseToTop() // Ensure status bar is visible
let statusBar = XCUIApplication(bundleIdentifier: "com.apple.systemuiserver")
let statusBarItem = statusBar.menuBars.children(matching: .button).element(boundBy: 0) // Adjust index for your icon
XCTAssertTrue(statusBarItem.exists)
statusBarItem.click()
}
}