Start Compose screen tests

This commit is contained in:
Shadowfacts 2020-09-13 13:19:56 -04:00
parent acd01a81cc
commit 1c6e464a4c
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
5 changed files with 124 additions and 2 deletions

View File

@ -253,6 +253,7 @@
D6D3FDE024F41B8400FF50A5 /* ComposeContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D3FDDF24F41B8400FF50A5 /* ComposeContainerView.swift */; }; D6D3FDE024F41B8400FF50A5 /* ComposeContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D3FDDF24F41B8400FF50A5 /* ComposeContainerView.swift */; };
D6D3FDE224F46A8D00FF50A5 /* ComposeUIState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D3FDE124F46A8D00FF50A5 /* ComposeUIState.swift */; }; D6D3FDE224F46A8D00FF50A5 /* ComposeUIState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D3FDE124F46A8D00FF50A5 /* ComposeUIState.swift */; };
D6D4CC91250D2C3100FCCF8D /* UIAccessibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4CC90250D2C3100FCCF8D /* UIAccessibility.swift */; }; D6D4CC91250D2C3100FCCF8D /* UIAccessibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4CC90250D2C3100FCCF8D /* UIAccessibility.swift */; };
D6D4CC94250DB86A00FCCF8D /* ComposeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4CC93250DB86A00FCCF8D /* ComposeTests.swift */; };
D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */; }; D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */; };
D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD6212518A200E1C4BB /* Assets.xcassets */; }; D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD6212518A200E1C4BB /* Assets.xcassets */; };
D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD8212518A200E1C4BB /* LaunchScreen.storyboard */; }; D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD8212518A200E1C4BB /* LaunchScreen.storyboard */; };
@ -575,6 +576,7 @@
D6D3FDDF24F41B8400FF50A5 /* ComposeContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeContainerView.swift; sourceTree = "<group>"; }; D6D3FDDF24F41B8400FF50A5 /* ComposeContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeContainerView.swift; sourceTree = "<group>"; };
D6D3FDE124F46A8D00FF50A5 /* ComposeUIState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeUIState.swift; sourceTree = "<group>"; }; D6D3FDE124F46A8D00FF50A5 /* ComposeUIState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeUIState.swift; sourceTree = "<group>"; };
D6D4CC90250D2C3100FCCF8D /* UIAccessibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAccessibility.swift; sourceTree = "<group>"; }; D6D4CC90250D2C3100FCCF8D /* UIAccessibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAccessibility.swift; sourceTree = "<group>"; };
D6D4CC93250DB86A00FCCF8D /* ComposeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeTests.swift; sourceTree = "<group>"; };
D6D4DDCC212518A000E1C4BB /* Tusker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Tusker.app; sourceTree = BUILT_PRODUCTS_DIR; }; D6D4DDCC212518A000E1C4BB /* Tusker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Tusker.app; sourceTree = BUILT_PRODUCTS_DIR; };
D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
D6D4DDD6212518A200E1C4BB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; D6D4DDD6212518A200E1C4BB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@ -1387,6 +1389,7 @@
D6D4DDEF212518A200E1C4BB /* TuskerUITests.swift */, D6D4DDEF212518A200E1C4BB /* TuskerUITests.swift */,
D65F613323AEAB6600F3CFD3 /* OnboardingTests.swift */, D65F613323AEAB6600F3CFD3 /* OnboardingTests.swift */,
D6A5BB2C23BBA9C4003BF21D /* MyProfileTests.swift */, D6A5BB2C23BBA9C4003BF21D /* MyProfileTests.swift */,
D6D4CC93250DB86A00FCCF8D /* ComposeTests.swift */,
D6A5BB2623BAC88E003BF21D /* Preferences */, D6A5BB2623BAC88E003BF21D /* Preferences */,
D6D4DDF1212518A200E1C4BB /* Info.plist */, D6D4DDF1212518A200E1C4BB /* Info.plist */,
); );
@ -1950,6 +1953,7 @@
D6A5BB2F23BBAC97003BF21D /* DelegatingResponse.swift in Sources */, D6A5BB2F23BBAC97003BF21D /* DelegatingResponse.swift in Sources */,
D6A5BB2D23BBA9C4003BF21D /* MyProfileTests.swift in Sources */, D6A5BB2D23BBA9C4003BF21D /* MyProfileTests.swift in Sources */,
D6A5BB2B23BAEF61003BF21D /* APIMocks.swift in Sources */, D6A5BB2B23BAEF61003BF21D /* APIMocks.swift in Sources */,
D6D4CC94250DB86A00FCCF8D /* ComposeTests.swift in Sources */,
D6D4DDF0212518A200E1C4BB /* TuskerUITests.swift in Sources */, D6D4DDF0212518A200E1C4BB /* TuskerUITests.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View File

@ -19,6 +19,8 @@ struct ComposeCurrentAccount: View {
var body: some View { var body: some View {
HStack(alignment: .top) { HStack(alignment: .top) {
ComposeAvatarImageView(url: account.avatar) ComposeAvatarImageView(url: account.avatar)
.accessibility(label: Text("\(account.displayName) avatar"))
VStack(alignment: .leading) { VStack(alignment: .leading) {
AccountDisplayNameLabel(account: mastodonController.persistentContainer.account(for: account.id)!, fontSize: 20) AccountDisplayNameLabel(account: mastodonController.persistentContainer.account(for: account.id)!, fontSize: 20)
.lineLimit(1) .lineLimit(1)

View File

@ -85,8 +85,22 @@ class ComposeHostingController: UIHostingController<ComposeContainerView> {
super.viewWillAppear(animated) super.viewWillAppear(animated)
// can't do this in viewDidLoad because viewDidLoad isn't called for UIHostingController // can't do this in viewDidLoad because viewDidLoad isn't called for UIHostingController
if mainToolbar.superview == nil { // if mainToolbar.superview == nil {
view.addSubview(mainToolbar) // view.addSubview(mainToolbar)
// NSLayoutConstraint.activate([
// mainToolbar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
// mainToolbar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
// // use the top anchor of the toolbar so our additionalSafeAreaInsets (which has the bottom as the toolbar height) don't affect it
// mainToolbar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
// ])
// }
}
override func didMove(toParent parent: UIViewController?) {
super.didMove(toParent: parent)
if let parent = parent {
parent.view.addSubview(mainToolbar)
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
mainToolbar.leadingAnchor.constraint(equalTo: view.leadingAnchor), mainToolbar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mainToolbar.trailingAnchor.constraint(equalTo: view.trailingAnchor), mainToolbar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
@ -108,6 +122,7 @@ class ComposeHostingController: UIHostingController<ComposeContainerView> {
private func createToolbar() -> UIToolbar { private func createToolbar() -> UIToolbar {
let toolbar = UIToolbar() let toolbar = UIToolbar()
toolbar.translatesAutoresizingMaskIntoConstraints = false toolbar.translatesAutoresizingMaskIntoConstraints = false
toolbar.isAccessibilityElement = true
let visibilityAction: Selector? let visibilityAction: Selector?
if #available(iOS 14.0, *) { if #available(iOS 14.0, *) {
@ -204,6 +219,7 @@ class ComposeHostingController: UIHostingController<ComposeContainerView> {
private func visibilityChanged(_ newVisibility: Status.Visibility) { private func visibilityChanged(_ newVisibility: Status.Visibility) {
for item in visibilityBarButtonItems { for item in visibilityBarButtonItems {
item.image = UIImage(systemName: newVisibility.imageName) item.image = UIImage(systemName: newVisibility.imageName)
item.image!.accessibilityLabel = String(format: NSLocalizedString("Visibility: %@", comment: "compose visiblity accessibility label"), draft.visibility.displayName)
item.accessibilityLabel = String(format: NSLocalizedString("Visibility: %@", comment: "compose visiblity accessibility label"), draft.visibility.displayName) item.accessibilityLabel = String(format: NSLocalizedString("Visibility: %@", comment: "compose visiblity accessibility label"), draft.visibility.displayName)
if #available(iOS 14.0, *) { if #available(iOS 14.0, *) {
let elements = Status.Visibility.allCases.map { (visibility) -> UIMenuElement in let elements = Status.Visibility.allCases.map { (visibility) -> UIMenuElement in

View File

@ -117,6 +117,7 @@ struct ComposeView: View {
Text(verbatim: charactersRemaining.description) Text(verbatim: charactersRemaining.description)
.foregroundColor(charactersRemaining < 0 ? .red : .secondary) .foregroundColor(charactersRemaining < 0 ? .red : .secondary)
.font(Font.body.monospacedDigit()) .font(Font.body.monospacedDigit())
.accessibility(label: Text(charactersRemaining < 0 ? "\(-charactersRemaining) characters too many" : "\(charactersRemaining) characters remaining"))
}.frame(height: 50) }.frame(height: 50)
} }

View File

@ -0,0 +1,99 @@
//
// ComposeTests.swift
// TuskerUITests
//
// Created by Shadowfacts on 9/12/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import XCTest
import Pachyderm
class ComposeTests: TuskerUITests {
override func setUp() {
super.setUp()
router.allRoutes()
app.launchEnvironment["UI_TESTING_LOGIN"] = "true"
app.launch()
app.tabBars.buttons["Compose"].tap()
}
func testCurrentAccount() {
XCTAssertTrue(app.images["Admin Account avatar"].exists, "avatar image exists")
XCTAssertTrue(app.staticTexts["Admin Account"].exists, "display name label exists")
XCTAssertTrue(app.staticTexts["@admin"].exists, "acct label exists")
}
func testBodyPlaceholder() {
XCTAssertTrue(app.staticTexts["What's on your mind?"].exists, "placeholder exists")
app.textViews.firstMatch.typeText("Blah")
XCTAssertFalse(app.staticTexts["What's on your mind?"].exists, "placeholder does not exist")
}
func testCharacterCounter() {
XCTAssertTrue(app.staticTexts["500 characters remaining"].exists, "initial character count is 500")
let textView = app.textViews.firstMatch
let fragments = [
"Hello",
"World",
"@admin",
"@admin@example.com",
"https://foo.example.com/?bar=baz#qux",
]
var remaining = 500
for s in fragments {
let length = CharacterCounter.count(text: s)
// add 1 for newline
remaining -= length + 1
textView.typeText(s + "\n")
XCTAssertTrue(app.staticTexts["\(remaining) characters remaining"].exists, "subsequent character count is \(remaining)")
}
}
// func testToolbarSwitching() {
// // text view is automatically focused, so unfocus
// app.swipeDown()
//
// XCTAssertEqual(app.toolbars.count, 1)
// XCTAssertEqual(app.toolbars.buttons.count, 3)
// XCTAssertTrue(app.toolbars.buttons["CW"].exists)
// XCTAssertTrue(app.toolbars.buttons["Visibility: Public"].exists)
// XCTAssertTrue(app.toolbars.buttons["Drafts"].exists)
//
// }
func testContentWarning() {
let toolbar = app.toolbars.firstMatch
XCTAssertTrue(toolbar.waitForExistence(timeout: 0.1))
XCTAssertEqual(app.toolbars.count, 1, "there is only 1 toolbar")
let cwButton = toolbar.buttons["CW"]
XCTAssertTrue(cwButton.exists, "the CW button exists")
cwButton.tap()
let cwField = app.textFields.firstMatch
XCTAssertEqual(cwField.placeholderValue, "Write your warning here")
XCTAssertTrue(app.staticTexts["500 characters remaining"].exists)
cwField.tap()
let str: String
// on iOS 14, the first type text is typed into a SwiftUI TextField, the 2nd character is inexplicably dropped >.<
if #available(iOS 14.0, *) {
str = "fooo"
} else {
str = "foo"
}
cwField.typeText(str)
XCTAssertTrue(app.staticTexts["497 characters remaining"].exists)
// CharacterCounter is not used => '@' is counted
cwField.typeText(" @bar")
XCTAssertTrue(app.staticTexts["492 characters remaining"].exists)
}
}