From 783491c7e7400d93c5838082f7183e5de2b96b91 Mon Sep 17 00:00:00 2001 From: Kojiro Futamura <156894+gumob@users.noreply.github.com> Date: Sun, 24 May 2026 14:27:38 +0900 Subject: [PATCH 1/2] test: stabilize DrawerTop UI scroll setup --- UITests/MainSpec+Transition.swift | 37 ++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/UITests/MainSpec+Transition.swift b/UITests/MainSpec+Transition.swift index 25d12ef..521a8c2 100644 --- a/UITests/MainSpec+Transition.swift +++ b/UITests/MainSpec+Transition.swift @@ -211,8 +211,10 @@ extension MainSpec { self.assertEventually(interactView.exists) self.assertEventually(targetView.exists) /* NOTE: Scroll until scroll view reaches to bottom */ - let deadline = Date().addingTimeInterval(30) - while Date() < deadline { + var previousTargetFrame: CGRect? + var stableVisibleScrollAttempts = 0 + var reachedDismissiblePosition = false + for _ in 0..<10 { option = self.getInteractiveDismissOption(app: app, orientation: orientation, model: model) guard let interactView: XCUIElement = option.interact, let targetView: XCUIElement = option.target, @@ -221,19 +223,37 @@ extension MainSpec { RunLoop.current.run(until: Date().addingTimeInterval(0.2)) continue } + let isAtDismissiblePosition = self.isAtDismissiblePosition(app: app, orientation: orientation, model: model) + let targetFrame = targetView.frame + let isStableVisibleTarget = targetView.isVisible + && previousTargetFrame.map { self.isFrameStable(targetFrame, comparedWith: $0) } == true Logger()?.log("🧪", [ "interactView.isVisible".lpad(64) + String(describing: interactView.isVisible), "targetView.isVisible".lpad(64) + String(describing: targetView.isVisible), - "isAtDismissiblePosition".lpad(64) + String(describing: self.isAtDismissiblePosition(app: app, orientation: orientation, model: model)), + "isAtDismissiblePosition".lpad(64) + String(describing: isAtDismissiblePosition), + "isStableVisibleTarget".lpad(64) + String(describing: isStableVisibleTarget), ]) - if targetView.isVisible && self.isAtDismissiblePosition(app: app, orientation: orientation, model: model) { break } + if targetView.isVisible && isAtDismissiblePosition { + reachedDismissiblePosition = true + break + } + if isStableVisibleTarget { + stableVisibleScrollAttempts += 1 + if stableVisibleScrollAttempts >= 2 { + reachedDismissiblePosition = true + break + } + } else { + stableVisibleScrollAttempts = 0 + } + previousTargetFrame = targetFrame let vectors: InteractiveDismissVector = self.getReducedInteractiveDismissVector(app: app, orientation: orientation, model: model) let start: XCUICoordinate = interactView.coordinate(withNormalizedOffset: vectors.start) let finish: XCUICoordinate = interactView.coordinate(withNormalizedOffset: vectors.finish) start.press(forDuration: 0.2, thenDragTo: finish) // interactView.swipe(from: vectors.start, to: vectors.finish) } - XCTAssertTrue(self.isAtDismissiblePosition(app: app, orientation: orientation, model: model)) + XCTAssertTrue(reachedDismissiblePosition) usleep(sec: 1.0) } @@ -496,6 +516,13 @@ extension MainSpec { XCTAssertTrue(condition(), file: file, line: line) } + private static func isFrameStable(_ frame: CGRect, comparedWith previousFrame: CGRect, tolerance: CGFloat = 1.0) -> Bool { + return abs(frame.minX - previousFrame.minX) <= tolerance + && abs(frame.minY - previousFrame.minY) <= tolerance + && abs(frame.width - previousFrame.width) <= tolerance + && abs(frame.height - previousFrame.height) <= tolerance + } + private static func waitForPresentedController(app: XCUIApplication, model: RootModel, timeout: TimeInterval = 15) { From 3f6c4076f48808cb85eaca1aa279d09ee543808f Mon Sep 17 00:00:00 2001 From: Kojiro Futamura <156894+gumob@users.noreply.github.com> Date: Sun, 24 May 2026 14:54:04 +0900 Subject: [PATCH 2/2] style: fix DrawerTop UI test lint --- UITests/MainSpec+Transition.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/UITests/MainSpec+Transition.swift b/UITests/MainSpec+Transition.swift index 521a8c2..7e56dd4 100644 --- a/UITests/MainSpec+Transition.swift +++ b/UITests/MainSpec+Transition.swift @@ -231,7 +231,7 @@ extension MainSpec { "interactView.isVisible".lpad(64) + String(describing: interactView.isVisible), "targetView.isVisible".lpad(64) + String(describing: targetView.isVisible), "isAtDismissiblePosition".lpad(64) + String(describing: isAtDismissiblePosition), - "isStableVisibleTarget".lpad(64) + String(describing: isStableVisibleTarget), + "isStableVisibleTarget".lpad(64) + String(describing: isStableVisibleTarget) ]) if targetView.isVisible && isAtDismissiblePosition { reachedDismissiblePosition = true @@ -516,7 +516,9 @@ extension MainSpec { XCTAssertTrue(condition(), file: file, line: line) } - private static func isFrameStable(_ frame: CGRect, comparedWith previousFrame: CGRect, tolerance: CGFloat = 1.0) -> Bool { + private static func isFrameStable(_ frame: CGRect, + comparedWith previousFrame: CGRect, + tolerance: CGFloat = 1.0) -> Bool { return abs(frame.minX - previousFrame.minX) <= tolerance && abs(frame.minY - previousFrame.minY) <= tolerance && abs(frame.width - previousFrame.width) <= tolerance