-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reimplement
waitForElementAndTap...
as a typed XCUIElement
method
"Typed" in that it expects an `enum` instead of a `String` to define the expected element state.
- Loading branch information
Showing
5 changed files
with
99 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import XCTest | ||
|
||
public extension XCUIElement { | ||
|
||
/// Abstraction do describe possible "states" an `XCUIElement` can be in. | ||
/// | ||
/// The goal of this `enum` is to make checking against the possible states a safe operation thanks to the compiler enforcing all and only the states represented by the `enum` `case`s are handled. | ||
enum State { | ||
case exists | ||
case dismissed | ||
case selected | ||
} | ||
|
||
/// Attempt to tap `self` until the given `XCUIElement` is in the given `State` or the `maxRetries` number of retries has been reached. | ||
/// | ||
/// Useful to make tests robusts against UI changes that may have some lag. | ||
func tapUntil( | ||
element: XCUIElement, | ||
matches state: State, | ||
failureMessage: String, | ||
maxRetries: Int = 10, | ||
retryInterval: TimeInterval = 1 | ||
) { | ||
tapUntil( | ||
Condition(element: element, state: state), | ||
retriedCount: 0, | ||
failureMessage: failureMessage, | ||
maxRetries: maxRetries, | ||
retryInterval: retryInterval | ||
) | ||
} | ||
|
||
/// Attempt to tap `self` until its "state" matches `Condition.State` or the `maxRetries` number of retries has been reached. | ||
/// | ||
/// Useful to make tests robusts against UI changes that may have some lag. | ||
func tapUntil( | ||
_ state: State, | ||
failureMessage: String, | ||
maxRetries: Int = 10, | ||
retryInterval: TimeInterval = 1 | ||
) { | ||
tapUntil( | ||
Condition(element: self, state: state), | ||
retriedCount: 0, | ||
failureMessage: failureMessage, | ||
maxRetries: maxRetries, | ||
retryInterval: retryInterval | ||
) | ||
} | ||
|
||
/// Describe the expectation for a given `XCUIElement` to be in a certain `Condition.State`. | ||
/// | ||
/// Example: `Condition(element: myButton, state: .selected)`. | ||
struct Condition { | ||
|
||
let element: XCUIElement | ||
let state: XCUIElement.State | ||
|
||
fileprivate func isMet() -> Bool { | ||
switch state { | ||
case .exists: return element.exists | ||
case .dismissed: return element.isHittable | ||
case .selected: return element.isSelected | ||
} | ||
} | ||
} | ||
|
||
private func tapUntil( | ||
_ condition: Condition, | ||
retriedCount: Int, | ||
failureMessage: String, | ||
maxRetries: Int, | ||
retryInterval: TimeInterval | ||
) { | ||
guard retriedCount < maxRetries else { | ||
return XCTFail("\(failureMessage) after \(retriedCount) tries.") | ||
} | ||
|
||
tap() | ||
|
||
guard condition.isMet() else { | ||
sleep(UInt32(retryInterval)) | ||
return tapUntil(condition, retriedCount: retriedCount + 1, failureMessage: failureMessage, maxRetries: maxRetries, retryInterval: retryInterval) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters