forked from shadowfacts/Tusker
Start Compose screen tests
This commit is contained in:
parent
acd01a81cc
commit
1c6e464a4c
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue