← All repositories

listless

A simple list app for Apple platforms

git clone https://code.inqk.net/listless.git


Tests/UI/ListlessiOSScreenshots.swift (3663B)

1import XCTest
2
3final class ListlessiOSScreenshots: XCTestCase {
4    var app: XCUIApplication!
5
6    static let screenshotDir = "/tmp/listless-screenshots"
7
8    override class func setUp() {
9        super.setUp()
10        try? FileManager.default.createDirectory(
11            atPath: screenshotDir,
12            withIntermediateDirectories: true
13        )
14    }
15
16    override func tearDownWithError() throws {
17        app.terminate()
18    }
19
20    // MARK: - Helpers
21
22    private func launchApp(_ additionalArgs: [String] = []) {
23        app = XCUIApplication()
24        app.launchArguments = ["UI_TESTING"] + additionalArgs
25        app.launch()
26    }
27
28    var draftTextField: XCUIElement {
29        app.textViews.matching(identifier: "draft-row-append").firstMatch
30    }
31
32    var itemListScrollView: XCUIElement {
33        app.scrollViews["item-list-scrollview"]
34    }
35
36    func createItem(_ title: String) {
37        let textView = draftTextField
38        if !textView.exists {
39            itemListScrollView.tap()
40            _ = textView.waitForExistence(timeout: 2)
41        }
42        textView.tap()
43        textView.typeText(title + "\n")
44    }
45
46    func itemCheckbox(at index: Int) -> XCUIElement {
47        app.buttons.matching(identifier: "item-checkbox").element(boundBy: index)
48    }
49
50    func exitEditingMode() {
51        let draft = draftTextField
52        if draft.exists {
53            draft.typeText("\n")
54        }
55    }
56
57    func saveScreenshot(name: String) {
58        let screenshot = XCUIScreen.main.screenshot()
59        let attachment = XCTAttachment(screenshot: screenshot)
60        attachment.name = name
61        attachment.lifetime = .keepAlways
62        add(attachment)
63
64        let data = screenshot.pngRepresentation
65        let path = "\(Self.screenshotDir)/\(name).png"
66        try? data.write(to: URL(fileURLWithPath: path))
67    }
68
69    // MARK: - Screenshots
70
71    /// Five items with keyboard up: three active, one empty draft row focused,
72    /// one completed at the bottom.
73    func testScreenshot01_ItemsWithKeyboard() throws {
74        launchApp()
75
76        createItem("Add items on your iPhone")
77        createItem("Edit items on your iPad")
78        createItem("Reorder items on your Mac")
79        createItem("Complete items on your Watch")
80        exitEditingMode()
81
82        usleep(500_000)
83
84        // Complete the last item
85        let checkbox = itemCheckbox(at: 3)
86        XCTAssertTrue(checkbox.waitForExistence(timeout: 2))
87        checkbox.tap()
88
89        usleep(500_000)
90
91        // Tap below items to create an empty focused draft row
92        let bottomArea = itemListScrollView.coordinate(
93            withNormalizedOffset: CGVector(dx: 0.5, dy: 0.9)
94        )
95        bottomArea.tap()
96        XCTAssertTrue(draftTextField.waitForExistence(timeout: 2))
97        usleep(300_000)
98
99        saveScreenshot(name: "01-items")
100    }
101
102    /// Empty list showing the "Pull down to create" hint.
103    func testScreenshot02_EmptyState() throws {
104        launchApp()
105
106        usleep(500_000)
107
108        saveScreenshot(name: "02-empty-state")
109    }
110
111    /// Two items with the first row swiped right past the complete threshold.
112    /// Collaroy colour theme.
113    func testScreenshot03_SwipeComplete() throws {
114        launchApp(["THEME_COLLAROY", "SCREENSHOT_SWIPE"])
115
116        createItem("Slide left to complete")
117        createItem("Slide right to delete")
118        exitEditingMode()
119
120        usleep(500_000)
121
122        saveScreenshot(name: "03-swipe")
123    }
124
125    /// Settings sheet.
126    func testScreenshot04_Settings() throws {
127        launchApp(["SCREENSHOT_SHOW_SETTINGS"])
128
129        usleep(500_000)
130
131        saveScreenshot(name: "04-settings")
132    }
133}