Skip to content
This repository has been archived by the owner on Jun 1, 2024. It is now read-only.

Commit

Permalink
fix: Navigation tests on iOS (#1635)
Browse files Browse the repository at this point in the history
* fix: appium navigation controller

* fix test

* impl

* update

* fix typo

Co-authored-by: Lucas Araújo <[email protected]>
  • Loading branch information
igorgiumellizup and lucasaraujo authored Jun 17, 2021
1 parent c5f1257 commit 7617a87
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 190 deletions.
4 changes: 2 additions & 2 deletions tests/appium/app-ios/AppiumApp/AppiumApp/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

let deepLinkController = DeepLinkViewController()
deepLinkController.bffUrl = bffUrl
let screen = UINavigationController(rootViewController: deepLinkController)
let screen = CustomBeagleNavigationController(rootViewController: deepLinkController)
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = screen
window?.makeKeyAndVisible()
Expand All @@ -55,7 +55,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

BeagleConfig.config()

let screen = UINavigationController(rootViewController: MainViewController())
let screen = CustomBeagleNavigationController(rootViewController: MainViewController())
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = screen
window?.makeKeyAndVisible()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ class BeagleConfig {
builder: CustomBeagleNavigationController.init,
forId: "CustomBeagleNavigation"
)
dependencies.navigation.registerNavigationController(
builder: OtherBeagleNavigationController.init,
forId: "otherController"
)

Beagle.dependencies = dependencies
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,114 @@
* limitations under the License.
*/

import UIKit
import Beagle

/// Appium App Navigation Controller.
/// When some server driven request fails it shows an error view with a 'Try again' button.
class CustomBeagleNavigationController: BeagleNavigationController {

let errorView = CustomErrorView()

override func serverDrivenStateDidChange(
to state: ServerDrivenState,
at screenController: BeagleController
) {
super.serverDrivenStateDidChange(to: state, at: screenController)
guard case .error(_, let retry) = state else { return }
errorView.retry = { [weak self] in
guard let self = self else { return }
self.errorView.removeFromSuperview()
retry?()
}
errorView.removeFromSuperview()
view.addSubview(errorView)
errorView.anchorTo(superview: view)
}
}

/// This Navigation changes the 'Try again' button title to 'Retry'.
class OtherBeagleNavigationController: CustomBeagleNavigationController {

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

init() {
super.init(nibName: nil, bundle: nil)
errorView.button.setTitle("Retry", for: .normal)
}

}

class CustomErrorView: UIView {

var retry: (() -> Void)?

lazy var label: UILabel = {
let label = UILabel()
label.text = "Oops! Something went wrong!"
return label
}()

lazy var button: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Try again", for: .normal)
button.addTarget(self, action: #selector(retryAction), for: .touchUpInside)
return button
}()

private lazy var stack: UIStackView = {
label.translatesAutoresizingMaskIntoConstraints = false
button.translatesAutoresizingMaskIntoConstraints = false
let stack = UIStackView(arrangedSubviews: [label, button])
stack.alignment = .center
stack.axis = .vertical
stack.distribution = .equalSpacing
stack.spacing = 20
return stack
}()

private lazy var close: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Close", for: .normal)
button.addTarget(self, action: #selector(closeAction), for: .touchUpInside)
return button
}()

init() {
super.init(frame: .zero)
setupView()
}

required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}

private func setupView() {
if #available(iOS 13.0, *) {
backgroundColor = .systemBackground
} else {
backgroundColor = .white
}
addSubview(stack)
stack.anchorCenterSuperview()

addSubview(close)
let (top, right): (NSLayoutYAxisAnchor, NSLayoutXAxisAnchor)
if #available(iOS 11.0, *) {
(top, right) = (safeAreaLayoutGuide.topAnchor, safeAreaLayoutGuide.rightAnchor)
} else {
(top, right) = (topAnchor, rightAnchor)
}
close.anchor(top: top, right: right, topConstant: 20, rightConstant: 20)
}

@objc private func retryAction() {
retry?()
}

@objc private func closeAction() {
removeFromSuperview()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,22 @@ class GenericSteps : AbstractStep() {

@When("^I click on button (.*)$")
fun clickOnButton(string1: String) {
waitForElementWithTextToBeClickable(string1, false, true).click()
waitForElementWithTextToBeClickable(string1, likeSearch = false, ignoreCase = true).click()
}

@Then("^The Text should show (.*)$")
fun textShouldShow(string1: String) {
waitForElementWithTextToBeClickable(string1, false, true)
waitForElementWithTextToBeClickable(string1, likeSearch = false, ignoreCase = true)
}

@When("^I click on text (.*)$")
fun clickOnText(string1: String) {
waitForElementWithTextToBeClickable(string1, false, true).click()
waitForElementWithTextToBeClickable(string1, likeSearch = false, ignoreCase = true).click()
}

@When("^I click on input with hint (.*)$")
fun clickOnInputWithHint(hint: String) {
waitForElementWithTextToBeClickable(hint, false, true)
waitForElementWithTextToBeClickable(hint, likeSearch = false, ignoreCase = true)
}

@When("hide keyboard")
Expand All @@ -52,7 +52,7 @@ class GenericSteps : AbstractStep() {

@Then("^a dialog should appear on the screen with text (.*)$")
fun checkDialog(string: String) {
waitForElementWithTextToBeClickable(string, true, true)
waitForElementWithTextToBeClickable(string, likeSearch = true, ignoreCase = true)
}

@Then("^the screen should show an element with the place holder (.*)$")
Expand All @@ -62,6 +62,11 @@ class GenericSteps : AbstractStep() {

@Then("^the screen should show an element with the title (.*)$")
fun checkElementByTitle(titleText: String) {
waitForElementWithTextToBeClickable(titleText, likeSearch = false, ignoreCase = false)
waitForElementWithTextToBeClickable(titleText, likeSearch = false, ignoreCase = true)
}

@Then("^the screen should not show an element with the title (.*)$")
fun checkElementNotVisibleByTitle(titleText: String) {
waitForElementWithTextToBeInvisible(titleText, likeSearch = false, ignoreCase = false)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@

package br.com.zup.beagle.cucumber.steps

import br.com.zup.beagle.setup.SuiteSetup
import io.cucumber.java.Before
import io.cucumber.java.en.And
import io.cucumber.java.en.Given
import io.cucumber.java.en.Then
import io.cucumber.java.en.When


class NavigateScreenSteps : AbstractStep() {
Expand All @@ -37,43 +36,11 @@ class NavigateScreenSteps : AbstractStep() {
waitForElementWithTextToBeClickable("Navigation Screen", false, false)
}

@When("^I press a navigation button (.*)$")
fun clickOnButton(string: String) {
waitForElementWithTextToBeClickable(string, false, false).click()
}

@When("^I press a navigation failure button (.*)$")
fun clickOnButtonFailure(string: String) {
waitForElementWithTextToBeClickable(string, false, false).click()
}

@And("^I click on (.*) button$")
fun clickOnPoPButton(string: String) {
waitForElementWithTextToBeClickable(string, false, false).click()
}

@Then("^the screen should navigate to another screen with the text label (.*)$")
fun checkGlobalTextScreen(string2: String) {
waitForElementWithTextToBeClickable(string2, false, false)
}

@Then("^the screen should not navigate to another screen with the text label (.*)$")
fun checkGlobalTextScreenIsNotOnView(string2: String) {
waitForElementWithTextToBeInvisible(string2, false, false)
}

@Then("^the app should dismiss the view that contains (.*)$")
fun checkTextIsNotOnAnyView(string1: String) {
waitForElementWithTextToBeInvisible(string1,false, false)
}

@Then("^the view that contains the (.*) must still exist$")
fun checkTextExistsInAView(string2: String) {
waitForElementWithTextToBeClickable(string2, false, false)
}

@Then("^There must be a retry button with text (.*)$")
fun checkButtonExistsInAView(string2: String) {
waitForElementWithTextToBeClickable(string2, false, false)
@Then("^There must be a retry button with text (.*) on Android and (.*) on iOS$")
fun checkButtonExistsInAView(androidText: String, iosText: String) {
if (SuiteSetup.isIos())
waitForElementWithTextToBeClickable(iosText, false, true)
else
waitForElementWithTextToBeClickable(androidText, false, true)
}
}
Loading

0 comments on commit 7617a87

Please sign in to comment.