mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-08 22:33:26 +01:00
UITests: fixes for iOS 26 compatibility
This commit is contained in:
@@ -3527,7 +3527,7 @@
|
|||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.6;
|
||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER)";
|
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER)";
|
||||||
|
|||||||
@@ -19,7 +19,41 @@ final class UITests: XCTestCase {
|
|||||||
|
|
||||||
private static let APP_NAME = "SideStore"
|
private static let APP_NAME = "SideStore"
|
||||||
|
|
||||||
|
func printAllMethods(of className: String) {
|
||||||
|
guard let cls: AnyClass = objc_getClass(className) as? AnyClass else {
|
||||||
|
print("Class \(className) not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var methodCount: UInt32 = 0
|
||||||
|
if let methodList = class_copyMethodList(cls, &methodCount) {
|
||||||
|
for i in 0..<Int(methodCount) {
|
||||||
|
let method = methodList[i]
|
||||||
|
let sel = method_getName(method)
|
||||||
|
print(String(describing: sel))
|
||||||
|
}
|
||||||
|
free(methodList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
// ensure the swizzle only happens once
|
||||||
|
if !Self.mockIdlingPrivateApiToNoOp {
|
||||||
|
let original = class_getInstanceMethod(
|
||||||
|
objc_getClass("XCUIApplicationProcess") as? AnyClass,
|
||||||
|
// this is the new method signature obtained via reflection
|
||||||
|
Selector(("waitForQuiescenceIncludingAnimationsIdle:isPreEvent:"))
|
||||||
|
)
|
||||||
|
let replaced = class_getInstanceMethod(type(of: self), #selector(Self.replace))
|
||||||
|
if let original, let replaced{
|
||||||
|
method_exchangeImplementations(original, replaced)
|
||||||
|
}
|
||||||
|
Self.mockIdlingPrivateApiToNoOp = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UNCOMMENT below to enable the printing of private members of XCUIApplicationProcess */
|
||||||
|
// printAllMethods(of: "XCUIApplicationProcess")
|
||||||
|
|
||||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
// Self.dismissSpotlight()
|
// Self.dismissSpotlight()
|
||||||
// Self.deleteMyApp()
|
// Self.deleteMyApp()
|
||||||
@@ -55,6 +89,7 @@ final class UITests: XCTestCase {
|
|||||||
|
|
||||||
func testBulkAddInputSources() throws {
|
func testBulkAddInputSources() throws {
|
||||||
|
|
||||||
|
// let app = XCUIApplication()
|
||||||
let app = XCUIApplication()
|
let app = XCUIApplication()
|
||||||
app.launch()
|
app.launch()
|
||||||
|
|
||||||
@@ -157,6 +192,13 @@ private extension UITests {
|
|||||||
springboard_app.tap()
|
springboard_app.tap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func replace() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
static var mockIdlingPrivateApiToNoOp = false
|
||||||
|
|
||||||
|
|
||||||
class func deleteMyApp2() {
|
class func deleteMyApp2() {
|
||||||
XCUIApplication().terminate()
|
XCUIApplication().terminate()
|
||||||
dismissSpringboardAlerts()
|
dismissSpringboardAlerts()
|
||||||
@@ -171,16 +213,19 @@ private extension UITests {
|
|||||||
let button = springboard_app.buttons["Remove App"]
|
let button = springboard_app.buttons["Remove App"]
|
||||||
_ = button.exists || button.waitForExistence(timeout: 5)
|
_ = button.exists || button.waitForExistence(timeout: 5)
|
||||||
button.tap()
|
button.tap()
|
||||||
|
_ = springboard_app.waitForExistence(timeout: 0.3)
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
let button = springboard_app.buttons["Delete App"]
|
let button = springboard_app.buttons["Delete App"]
|
||||||
_ = button.waitForExistence(timeout: 0.3)
|
_ = button.waitForExistence(timeout: 0.3)
|
||||||
button.tap()
|
button.tap()
|
||||||
|
_ = springboard_app.waitForExistence(timeout: 0.3)
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
let button = springboard_app.buttons["Delete"]
|
let button = springboard_app.buttons["Delete"]
|
||||||
_ = button.waitForExistence(timeout: 0.3)
|
_ = button.waitForExistence(timeout: 0.3)
|
||||||
button.tap()
|
button.tap()
|
||||||
|
_ = springboard_app.waitForExistence(timeout: 0.3)
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Press home once to make the icons stop wiggling
|
// // Press home once to make the icons stop wiggling
|
||||||
@@ -263,13 +308,16 @@ private extension UITests {
|
|||||||
let app = XCUIApplication()
|
let app = XCUIApplication()
|
||||||
app.tabBars["Tab Bar"].buttons["Sources"].tap()
|
app.tabBars["Tab Bar"].buttons["Sources"].tap()
|
||||||
app.navigationBars["Sources"].buttons["Add"].tap()
|
app.navigationBars["Sources"].buttons["Add"].tap()
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
|
|
||||||
let collectionViewsQuery = app.collectionViews
|
let collectionViewsQuery = app.collectionViews
|
||||||
let appsSidestoreIoTextField = collectionViewsQuery.textFields["apps.sidestore.io"]
|
let appsSidestoreIoTextField = collectionViewsQuery.textFields["apps.sidestore.io"]
|
||||||
_ = appsSidestoreIoTextField.exists || appsSidestoreIoTextField.waitForExistence(timeout: 5)
|
_ = appsSidestoreIoTextField.exists || appsSidestoreIoTextField.waitForExistence(timeout: 5)
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
appsSidestoreIoTextField.tap()
|
appsSidestoreIoTextField.tap()
|
||||||
appsSidestoreIoTextField.tap()
|
appsSidestoreIoTextField.tap()
|
||||||
collectionViewsQuery.staticTexts["Paste"].tap()
|
collectionViewsQuery.staticTexts["Paste"].tap()
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
|
|
||||||
// if app.keyboards.buttons["Return"].exists {
|
// if app.keyboards.buttons["Return"].exists {
|
||||||
// app.keyboards.buttons["Return"].tap()
|
// app.keyboards.buttons["Return"].tap()
|
||||||
@@ -282,6 +330,7 @@ private extension UITests {
|
|||||||
|
|
||||||
if app.keyboards.count > 0 {
|
if app.keyboards.count > 0 {
|
||||||
appsSidestoreIoTextField.typeText("\n") // Fallback to newline so that soft kb is dismissed
|
appsSidestoreIoTextField.typeText("\n") // Fallback to newline so that soft kb is dismissed
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
let cellsQuery = collectionViewsQuery.cells
|
let cellsQuery = collectionViewsQuery.cells
|
||||||
@@ -318,17 +367,22 @@ private extension UITests {
|
|||||||
let app = XCUIApplication()
|
let app = XCUIApplication()
|
||||||
app.tabBars["Tab Bar"].buttons["Sources"].tap()
|
app.tabBars["Tab Bar"].buttons["Sources"].tap()
|
||||||
app.navigationBars["Sources"].buttons["Add"].tap()
|
app.navigationBars["Sources"].buttons["Add"].tap()
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
|
|
||||||
let collectionViewsQuery = app.collectionViews
|
let collectionViewsQuery = app.collectionViews
|
||||||
let appsSidestoreIoTextField = collectionViewsQuery.textFields["apps.sidestore.io"]
|
let appsSidestoreIoTextField = collectionViewsQuery.textFields["apps.sidestore.io"]
|
||||||
_ = appsSidestoreIoTextField.exists || appsSidestoreIoTextField.waitForExistence(timeout: 5)
|
_ = appsSidestoreIoTextField.exists || appsSidestoreIoTextField.waitForExistence(timeout: 5)
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
appsSidestoreIoTextField.tap()
|
appsSidestoreIoTextField.tap()
|
||||||
appsSidestoreIoTextField.tap()
|
appsSidestoreIoTextField.tap()
|
||||||
_ = appsSidestoreIoTextField.exists || appsSidestoreIoTextField.waitForExistence(timeout: 5)
|
_ = appsSidestoreIoTextField.exists || appsSidestoreIoTextField.waitForExistence(timeout: 5)
|
||||||
collectionViewsQuery.staticTexts["Paste"].tap()
|
collectionViewsQuery.staticTexts["Paste"].tap()
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
|
|
||||||
|
|
||||||
if app.keyboards.count > 0 {
|
if app.keyboards.count > 0 {
|
||||||
appsSidestoreIoTextField.typeText("\n") // Fallback to newline so that soft kb is dismissed
|
appsSidestoreIoTextField.typeText("\n") // Fallback to newline so that soft kb is dismissed
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
let cellsQuery = collectionViewsQuery.cells
|
let cellsQuery = collectionViewsQuery.cells
|
||||||
@@ -380,14 +434,24 @@ private extension UITests {
|
|||||||
.containing(.button, identifier: source.identifier)
|
.containing(.button, identifier: source.identifier)
|
||||||
.children(matching: .button)[source.identifier]
|
.children(matching: .button)[source.identifier]
|
||||||
XCTAssert(sourceButton.exists || sourceButton.waitForExistence(timeout: 10), "Source preview for id: '\(source.alertTitle)' not found in the view")
|
XCTAssert(sourceButton.exists || sourceButton.waitForExistence(timeout: 10), "Source preview for id: '\(source.alertTitle)' not found in the view")
|
||||||
|
|
||||||
|
_ = sourceButton.waitForExistence(timeout: 0.5)
|
||||||
|
|
||||||
// let addButton = sourceButton.children(matching: .button).firstMatch
|
// let addButton = sourceButton.children(matching: .button).firstMatch
|
||||||
|
// let addButton = sourceButton.descendants(matching: .button)["add"]
|
||||||
|
// XCTAssert(addButton.exists || addButton.waitForExistence(timeout: 0.3), " `+` button for id: '\(source.alertTitle)' not found in the preview container")
|
||||||
|
// addButton.tap()
|
||||||
|
|
||||||
let addButton = sourceButton.children(matching: .button)["add"]
|
let addButton = sourceButton.children(matching: .button)["add"]
|
||||||
XCTAssert(addButton.exists || addButton.waitForExistence(timeout: 0.3), " `+` button for id: '\(source.alertTitle)' not found in the preview container")
|
XCTAssert(addButton.waitForExistence(timeout: 1)) //TODO: fine tune down the value to make tests faster (but validate tests still works)
|
||||||
addButton.tap()
|
// addButton.tap()
|
||||||
|
|
||||||
|
let coord = addButton.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5))
|
||||||
|
coord.tap()
|
||||||
|
|
||||||
if source.requiresSwipe {
|
if source.requiresSwipe {
|
||||||
sourceButton.swipeUp(velocity: .slow) // Swipe up if needed.
|
sourceButton.swipeUp(velocity: .slow) // Swipe up if needed.
|
||||||
|
_ = sourceButton.waitForExistence(timeout: 0.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,7 +460,8 @@ private extension UITests {
|
|||||||
// Navigate to the Sources screen and open the Add Source view.
|
// Navigate to the Sources screen and open the Add Source view.
|
||||||
app.tabBars["Tab Bar"].buttons["Sources"].tap()
|
app.tabBars["Tab Bar"].buttons["Sources"].tap()
|
||||||
app.navigationBars["Sources"].buttons["Add"].tap()
|
app.navigationBars["Sources"].buttons["Add"].tap()
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
|
|
||||||
let cellsQuery = app.collectionViews.cells
|
let cellsQuery = app.collectionViews.cells
|
||||||
|
|
||||||
// Data model for recommended sources. NOTE: This list order is required to be the same as that of "Add Source" Screen
|
// Data model for recommended sources. NOTE: This list order is required to be the same as that of "Add Source" Screen
|
||||||
@@ -421,7 +486,8 @@ private extension UITests {
|
|||||||
// Navigate to the Sources screen and open the Add Source view.
|
// Navigate to the Sources screen and open the Add Source view.
|
||||||
app.tabBars["Tab Bar"].buttons["Sources"].tap()
|
app.tabBars["Tab Bar"].buttons["Sources"].tap()
|
||||||
app.navigationBars["Sources"].buttons["Add"].tap()
|
app.navigationBars["Sources"].buttons["Add"].tap()
|
||||||
|
_ = app.waitForExistence(timeout: 0.5)
|
||||||
|
|
||||||
let cellsQuery = app.collectionViews.cells
|
let cellsQuery = app.collectionViews.cells
|
||||||
|
|
||||||
// Data model for recommended sources. NOTE: This list order is required to be the same as that of "Add Source" Screen
|
// Data model for recommended sources. NOTE: This list order is required to be the same as that of "Add Source" Screen
|
||||||
|
|||||||
Reference in New Issue
Block a user