Helpers.swift 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //
  2. // SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
  3. // SPDX-License-Identifier: GPL-3.0-or-later
  4. //
  5. import Foundation
  6. import XCTest
  7. extension XCTestCase {
  8. func waitForEnabled(object: Any?) {
  9. let enabledPredicate = NSPredicate(format: "enabled == true")
  10. expectation(for: enabledPredicate, evaluatedWith: object, handler: nil)
  11. waitForExpectations(timeout: TestConstants.timeoutLong, handler: nil)
  12. }
  13. func waitForHittable(object: Any?) {
  14. let enabledPredicate = NSPredicate(format: "hittable == true")
  15. expectation(for: enabledPredicate, evaluatedWith: object, handler: nil)
  16. waitForExpectations(timeout: TestConstants.timeoutLong, handler: nil)
  17. }
  18. // Based on https://stackoverflow.com/a/47947315
  19. @discardableResult
  20. func waitForEitherElementToExist(_ elementA: XCUIElement, _ elementB: XCUIElement, _ timeout: TimeInterval) -> XCUIElement? {
  21. let startTime = NSDate.timeIntervalSinceReferenceDate
  22. while !elementA.exists && !elementB.exists { // while neither element exists
  23. if NSDate.timeIntervalSinceReferenceDate - startTime > timeout {
  24. XCTFail("Timed out waiting for either element to exist.")
  25. break
  26. }
  27. sleep(1)
  28. }
  29. if elementA.exists { return elementA }
  30. if elementB.exists { return elementB }
  31. return nil
  32. }
  33. func launchAndLogin() -> XCUIApplication {
  34. let app = XCUIApplication()
  35. app.launchArguments += ["-AppleLanguages", "(en-US)"]
  36. app.launchArguments += ["-AppleLocale", "\"en-US\""]
  37. app.launchArguments += ["-TestEnvironment"]
  38. app.launch()
  39. let accountSwitcherButton = app.buttons["LoadedProfileButton"]
  40. let serverAddressHttpsTextField = app.textFields["Server address https://…"]
  41. // Wait shortly until the app is fully started
  42. let foundElement = waitForEitherElementToExist(accountSwitcherButton, serverAddressHttpsTextField, TestConstants.timeoutLong)
  43. XCTAssertNotNil(foundElement)
  44. // When the account switcher button exists, we have atleast one account configured
  45. if foundElement == accountSwitcherButton {
  46. return app
  47. }
  48. serverAddressHttpsTextField.tap()
  49. serverAddressHttpsTextField.typeText(TestConstants.server)
  50. let loginButton = app.buttons["Log in"]
  51. XCTAssert(loginButton.waitForExistence(timeout: TestConstants.timeoutLong))
  52. loginButton.tap()
  53. let webViewsQuery = app.webViews.webViews.webViews
  54. let main = webViewsQuery.otherElements["main"]
  55. // Wait for the webview to be available
  56. XCTAssert(main.waitForExistence(timeout: TestConstants.timeoutLong))
  57. // Wait for the login button to be available and to get enabled/hittable
  58. let loginButtonWeb = webViewsQuery.buttons["Log in"]
  59. XCTAssert(loginButtonWeb.waitForExistence(timeout: TestConstants.timeoutLong))
  60. waitForEnabled(object: loginButtonWeb)
  61. waitForHittable(object: loginButtonWeb)
  62. loginButtonWeb.tap()
  63. XCTAssert(main.waitForExistence(timeout: TestConstants.timeoutLong))
  64. let usernameTextField = main.descendants(matching: .textField).firstMatch
  65. let passwordTextField = main.descendants(matching: .secureTextField).firstMatch
  66. XCTAssert(usernameTextField.waitForExistence(timeout: TestConstants.timeoutLong))
  67. XCTAssert(passwordTextField.waitForExistence(timeout: TestConstants.timeoutLong))
  68. usernameTextField.tap()
  69. usernameTextField.typeText(TestConstants.username + "\n")
  70. passwordTextField.tap()
  71. passwordTextField.typeText(TestConstants.password + "\n")
  72. let accountAccess = webViewsQuery.staticTexts["Account access"]
  73. XCTAssert(accountAccess.waitForExistence(timeout: TestConstants.timeoutLong))
  74. let grantAccessButton = webViewsQuery.buttons["Grant access"]
  75. XCTAssert(grantAccessButton.waitForExistence(timeout: TestConstants.timeoutLong))
  76. waitForEnabled(object: grantAccessButton)
  77. waitForHittable(object: grantAccessButton)
  78. // TODO: Find a better way to reliable detect if the grant access button is tappable
  79. sleep(5)
  80. grantAccessButton.tap()
  81. // When the account switcher gets enabled, we have atleast 1 account in the app and are online
  82. XCTAssert(accountSwitcherButton.waitForExistence(timeout: TestConstants.timeoutLong))
  83. waitForEnabled(object: accountSwitcherButton)
  84. return app
  85. }
  86. func createConversation(for app: XCUIApplication, with newConversationName: String) {
  87. app.navigationBars["Nextcloud Talk"].buttons["Create or join a conversation"].tap()
  88. let createNewConversationCell = app.tables.cells.staticTexts["Create a new conversation"]
  89. XCTAssert(createNewConversationCell.waitForExistence(timeout: TestConstants.timeoutShort))
  90. createNewConversationCell.tap()
  91. let newConversationNavBar = app.navigationBars["New conversation"]
  92. XCTAssert(newConversationNavBar.waitForExistence(timeout: TestConstants.timeoutShort))
  93. app.typeText(newConversationName)
  94. newConversationNavBar.buttons["Create"].tap()
  95. }
  96. }