Skip to content

Commit

Permalink
Adding snapshot test with localisation testing (#12)
Browse files Browse the repository at this point in the history
* Initial commit for adding snapshot test

* Add Snapshots for happy and sad paths

* Clean test file and make it readable

* updating project.yml

* adding test plan

* edited test plan

* new test plan added

* testplan updated

* updating command for test plan

* new screenshots

* adding old commit details

* PR comments

* PR comments

* Update README.md

---------

Co-authored-by: George Nyakundi <[email protected]>
Co-authored-by: tibor-is-back <[email protected]>
  • Loading branch information
3 people authored Apr 25, 2024
1 parent 7c9c938 commit b3acab1
Show file tree
Hide file tree
Showing 22 changed files with 863 additions and 9 deletions.
3 changes: 3 additions & 0 deletions Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ abstract_target 'Tests' do
pod 'Backbase', $backbaseVersion
pod 'Resolver', $resolverVersion

target 'SnapshotTests' do
inherit! :search_paths
end

target 'AccountsJourneyUnitTests' do
end
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,13 @@ pod repo-art add backbase-pods-design "https://repo.backbase.com/artifactory/api
## Usage and login

The Golden Sample App is configured to use the API Sandbox environment out of the box. To be able to connect to this environment you need a Sandbox API key which can be obtained from the API Sandbox team and needs to be added to config.json. To login to the app the API Sandbox [test accounts](https://backbase.io/developers/documentation/api-sandbox/retail-banking-usa/retail-user-credentials/) can be used.

## Test plan
The testplan is part of the project, but Xcodegen cannot add it. In order to do so:

```bash
1. Go to the Snapshot scheme
2. Click on the Edit the scheme
3. Click on the respective test plan
4. Modify the details
```
43 changes: 43 additions & 0 deletions TestPlans/newTestPlan.xctestplan
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"configurations" : [
{
"id" : "A4DFB22F-BBF3-44AB-80FC-C8EB3CF1C6E8",
"name" : "English",
"options" : {
"environmentVariableEntries" : [
{
"key" : "TestPlanLanguage",
"value" : "en"
}
],
"language" : "en"
}
},
{
"id" : "5386E73E-FD0E-4777-8EA3-18AD2E3B1E4E",
"name" : "Arabic",
"options" : {
"environmentVariableEntries" : [
{
"key" : "TestPlanLanguage",
"value" : "ar"
}
],
"language" : "IDELaunchSchemeLanguageRightToLeftLayoutDirection"
}
}
],
"defaultOptions" : {
"testTimeoutsEnabled" : true
},
"testTargets" : [
{
"target" : {
"containerPath" : "container:ios-golden-sample-app.xcodeproj",
"identifier" : "6BD16231F79DDFCBA9FB4B98",
"name" : "SnapshotTests"
}
}
],
"version" : 1
}
55 changes: 55 additions & 0 deletions Tests/SnapshotTests/AccountDetailsScreen.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import XCTest
import SnapshotTesting
import Resolver
@testable import GoldenAccountsUseCase
@testable import AccountsJourney
import AccessControlClient3Gen2
import ArrangementsClient2Gen2
import Backbase

class AccountDetailsScreenSnapshotTests: XCTestCase {

private var simulatorsForTestConfiguration: [Simulator] {
guard let language = ProcessInfo.processInfo.environment["TestPlanLanguage"] else { fatalError("Missing environment variable from test plan")}
print("language from config: \(language)")
if language == "en" {
return Simulator.leftToRightWithDarkMode
} else {
return Simulator.rightToLeftLightMode
}
}

func testSuggestionsHappyPath() {

Resolver.register { AccountsJourney.Configuration() }

let viewModel = AccountDetailsViewModel()
// Register the Mock
Resolver.register { MockAccountDetailsUseCase() as AccountDetailsUseCase }

let viewController = AccountDetailsViewController(viewModel: viewModel, arrangementId: "")

// fire the event that fetches account details
viewController.viewModel.onEvent(.getAccountDetails(""))

let result = verifyViewSnapshot(with: viewController.view, testCases: simulatorsForTestConfiguration)
XCTAssertTrue(result.isEmpty, "Failed in \(#function) snapshot test")
}

func testSuggestionsSadPath() {

Resolver.register { AccountsJourney.Configuration() }

let viewModel = AccountDetailsViewModel()
// Register the Mock
Resolver.register { MockAccountDetailsUseCase(shouldReturnError: true) as AccountDetailsUseCase }

let viewController = AccountDetailsViewController(viewModel: viewModel, arrangementId: "")

// fire the event that fetches account details
viewController.viewModel.onEvent(.getAccountDetails(""))

let result = verifyViewSnapshot(with: viewController.view, testCases: simulatorsForTestConfiguration)
XCTAssertTrue(result.isEmpty, "Failed in \(#function) snapshot test")
}
}
31 changes: 31 additions & 0 deletions Tests/SnapshotTests/Extensions/Bundle+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Copyright © 2020 Backbase R&D B.V. All rights reserved.
//

import UIKit

extension Bundle {
static var snapshot: Bundle? {
return Bundle(for: BundleToken.self)
}
}

private final class BundleToken {}

extension Bundle {
/// Helper function to return contents of a file in data format
/// - Parameter path: path of the file
/// - Returns: data format of the contents
static func data(from path: String) -> Data {
guard let filePath = Bundle(for: AccountDetailsScreenSnapshotTests.self).path(forResource: path, ofType: nil) else {
fatalError("Failed to find file \(path)")
}
let fileUrl = URL(fileURLWithPath: filePath)
do {
let data = try Data(contentsOf: fileUrl, options: .uncached)
return data
} catch {
fatalError("Failed to find file \(path)")
}
}
}
73 changes: 73 additions & 0 deletions Tests/SnapshotTests/Extensions/SnapshotTesting+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// Created by Backbase on 7.12.2022.
//

import SnapshotTesting
import UIKit

extension UITraitCollection {

static func getTraitCollection(_ orientation: ViewImageConfig.Orientation,
_ layoutDirection: UITraitEnvironmentLayoutDirection,
_ userInterfaceStyle: UIUserInterfaceStyle) -> UITraitCollection {
let base: [UITraitCollection] = [
.init(forceTouchCapability: .available),
.init(layoutDirection: layoutDirection),
.init(preferredContentSizeCategory: .medium),
.init(userInterfaceIdiom: .phone),
.init(userInterfaceStyle: userInterfaceStyle)
]

switch orientation {
case .landscape:
return .init(
traitsFrom: base + [
.init(horizontalSizeClass: .compact),
.init(verticalSizeClass: .compact)
]
)
case .portrait:
return .init(
traitsFrom: base + [
.init(horizontalSizeClass: .compact),
.init(verticalSizeClass: .regular)
]
)
}
}
}


extension ViewImageConfig.Orientation: CustomStringConvertible {
/// Description used for assembling the file name of a reference snapshot
public var description: String {
switch self {
case .landscape: return "landscape"
case .portrait: return "portrait"
}
}
}

extension UIUserInterfaceStyle: CustomStringConvertible {
/// Description used for assembling the file name of a reference snapshot
public var description: String {
switch self {
case .light: return "light"
case .dark: return "dark"
case .unspecified: return "unspecifiedInterfaceStyle"
@unknown default: return "unknownInterfaceStyle"
}
}
}

extension UITraitEnvironmentLayoutDirection: CustomStringConvertible {
/// Description used for assembling the file name of a reference snapshot
public var description: String {
switch self {
case .leftToRight: return "LTR"
case .rightToLeft: return "RTL"
case .unspecified: return "unspecifiedLayoutDirection"
@unknown default: return "unknownLayoutDirection"
}
}
}
17 changes: 17 additions & 0 deletions Tests/SnapshotTests/Extensions/UIColor+DesignSystem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// UIColor+DesignSystem.swift
// BackbaseDesignSystemSnapshotTests
//
// Created by Backbase R&D B.V. on 09/02/2023.
// Copyright © 2023 Backbase R&D B.V. All rights reserved.
//

import UIKit
import BackbaseDesignSystem

extension UIColor {

static var designSystemColors: DesignSystem.Colors {
DesignSystem.shared.colors
}
}
52 changes: 52 additions & 0 deletions Tests/SnapshotTests/Extensions/UIView+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// Created by Backbase on 8.12.2022.
//

import UIKit
import BackbaseDesignSystem

extension UIView {

func setSizeConstraints(size: CGSize) -> UIView {
translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
widthAnchor.constraint(equalToConstant: size.width),
heightAnchor.constraint(equalToConstant: size.height)
])
return self
}

func containerCenterAligned(size: CGSize = CGSize(width: 200, height: 100),
backgroundColor: UIColor = DesignSystem.shared.colors.surfaceSecondary.default) -> UIView {
translatesAutoresizingMaskIntoConstraints = false
let view = containerView(size: size, backgroundColor: backgroundColor)
NSLayoutConstraint.activate([
centerXAnchor.constraint(equalTo: view.centerXAnchor),
centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
return view
}

func containerCornerAttached(size: CGSize = CGSize(width: 200, height: 100),
backgroundColor: UIColor = DesignSystem.shared.colors.surfaceSecondary.default) -> UIView {
translatesAutoresizingMaskIntoConstraints = false
let view = containerView(size: size, backgroundColor: backgroundColor)
NSLayoutConstraint.activate([
topAnchor.constraint(equalTo: view.topAnchor, constant: 16),
bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -16),
leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16)
])
return view
}

private func containerView(size: CGSize, backgroundColor: UIColor) -> UIView {
let containerView = UIView(frame: .init(origin: .zero, size: size))
containerView.backgroundColor = backgroundColor
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.layer.cornerRadius = 8.0
containerView.addSubview(self)
return containerView
}
}
Loading

0 comments on commit b3acab1

Please sign in to comment.