Swiftpack.co - RedMadRobot/catbird as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by RedMadRobot.
RedMadRobot/catbird 0.9.0
Mock server for UI tests
⭐️ 25
🕓 1 week ago
iOS macOS linux macOS iOS
.package(url: "https://github.com/RedMadRobot/catbird.git", from: "0.9.0")

Catbird

Test GitHub license CocoaPods Compatible Platform SPM compatible

Features

  • Dynamic mock server
  • Static file mock server
  • Proxy server with writing response files

Installation

To use Catbird in UI-tests you must have Catbird server and Catbird API code which allows you to communicate with the server.

Type Server API code
Manual
Homebrew 🚫
SPM 🚫
CocoaPods

Manual

Download catbird.zip archive from the latest release page.

Using Homebrew:

Run the following command:

brew install RedMadRobot/formulae/catbird

Using SPM:

If you have an Xcode project, open it and add Catbird Package using the following URL:

https://github.com/RedMadRobot/catbird.git

Using CocoaPods:

Add Catbird to UI tests target.

target 'App' do
  use_frameworks!

  target 'AppUITests' do
    inherit! :search_paths

    pod 'Catbird'
  end
end

Setup in Xcode project

  • Open Schema/Edit scheme...
  • Select Test action
  • Select Pre-Actions
    • Add New Run Script action
    • Provide build setting from <YOUR_APP_TARGET>
    • ${PODS_ROOT}/Catbird/start.sh
  • Select Post-Actions
    • Add New Run Script action
    • Provide build setting from <YOUR_APP_TARGET>
    • ${PODS_ROOT}/Catbird/stop.sh

Usage

import XCTest
import Catbird

enum LoginMock: CatbirdMockConvertible {
    case success
    case blockedUserError

    var pattern: RequestPattern {
        RequestPattern(method: .POST, url: URL(string: "/login")!)
    }

    var response: ResponseMock {
        switch self {
        case .success:
            let json: [String: Any] = [
                "data": [
                    "access_token": "abc",
                    "refresh_token": "xyz",
                    "expired_in": "123",
                ]
            ]
            return ResponseMock(
                status: 200,
                headers: ["Content-Type": "application/json"],
                body: try! JSONSerialization.data(withJSONObject: json))

        case .blockedUserError:
            let json: [String: Any] = [
                "error": [
                    "code": "user_blocked",
                    "message": "user blocked"
                ]
            ]
            return ResponseMock(
                status: 400,
                headers: ["Content-Type": "application/json"],
                body: try! JSONSerialization.data(withJSONObject: json))
        }
    }
}

final class LoginUITests: XCTestCase {

    private let catbird = Catbird()
    private var app: XCUIApplication!

    override func setUp() {
        super.setUp()
        continueAfterFailure = false
        app = XCUIApplication()

        // Base URL in app `UserDefaults.standard.url(forKey: "url_key")`
        app.launchArguments = ["-url_key", catbird.url.absoluteString]
        app.launch()
    }

    override func tearDown() {
        XCTAssertNoThrow(try catbird.send(.removeAll), "Remove all requests")
        super.tearDown()
    }

    func testLogin() {
        XCTAssertNoThrow(try catbird.send(.add(LoginMock.success)))

        app.textFields["login"].tap()
        app.textFields["login"].typeText("john@example.com")
        app.secureTextFields["password"].tap()
        app.secureTextFields["password"].typeText("qwerty")
        app.buttons["Done"].tap()

        XCTAssert(app.staticTexts["Main Screen"].waitForExistence(timeout: 3))
    }

    func testBlockedUserError() {
        XCTAssertNoThrow(try catbird.send(.add(LoginMock.blockedUserError)))

        app.textFields["login"].tap()
        app.textFields["login"].typeText("peter@example.com")
        app.secureTextFields["password"].tap()
        app.secureTextFields["password"].typeText("burger")
        app.buttons["Done"].tap()

        XCTAssert(app.alerts["Error"].waitForExistence(timeout: 3))
    }
}

Request patterns

You can specify a pattern for catch http requests and make a response with mock data. Pattern matching applied for URL and http headers in the request. See RequestPattern struct.

Three types of patterns can be used:

  • equal - the request value must be exactly the same as the pattern value,
  • wildcard - the request value match with the wildcard pattern (see below),
  • regexp - the request value match with the regular expression pattern.
Note:

If you want to apply a wildcard pattern for the url query parameters, don't forget escape ? symbol after domain or path.

Pattern.wildcard("http://example.com\?query=*")

Wildcard pattern

"Wildcards" are the patterns you type when you do stuff like ls *.js on the command line, or put build/* in a .gitignore file.

In our implementation any wildcard pattern translates to regular expression and applies matching with URL or header string.

The following characters have special magic meaning when used in a pattern:

  • * matches 0 or more characters
  • ? matches 1 character
  • [a-z] matches a range of characters, similar to a RegExp range.
  • {bar,baz} matches one of the substitution listed in braces. For example pattern foo{bar,baz} matches strings foobar or foobaz

You can escape special characters with backslash \.

Negation in groups is not supported.

Example project

$ cd Example/CatbirdX
$ bundle exec pod install
$ xed .

Environment variables

CATBIRD_MOCKS_DIR — Directory where static mocks are located.

CATBIRD_PROXY_URL — If you specify this URL Catbird will run in write mode. In this mode, requests to Catbird will be redirected to the CATBIRD_PROXY_URL. Upon receipt of response from the server it will be written to the CATBIRD_MOCKS_DIR directory.

Logs

Logs can be viewed in the Console.app with subsystem com.redmadrobot.catbird

Don't forget to include the message in the action menu

  • ☑ Include Info Messages
  • ☑ Include Debug Messages

Without this, only error messages will be visible

Web

You can view a list of all intercepted requests on the page http://127.0.0.1:8080/catbird

GitHub

link
Stars: 25
Last commit: 5 days ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Release Notes

0.9.0
1 week ago

What's Changed

Full Changelog: https://github.com/RedMadRobot/catbird/compare/0.8.2...0.9.0

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics