diff --git a/Example/AztecExample.xcodeproj/project.pbxproj b/Example/AztecExample.xcodeproj/project.pbxproj index d812e9bb6..1783149e6 100644 --- a/Example/AztecExample.xcodeproj/project.pbxproj +++ b/Example/AztecExample.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ B570B1C91E82D332008CF41E /* MoreAttachmentRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B570B1C81E82D332008CF41E /* MoreAttachmentRenderer.swift */; }; B570B1CC1E82D343008CF41E /* CommentAttachmentRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B570B1CB1E82D343008CF41E /* CommentAttachmentRenderer.swift */; }; B5AF89341E93ECE60051EFDB /* HTMLAttachmentRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AF89331E93ECE60051EFDB /* HTMLAttachmentRenderer.swift */; }; + CC400F1A1E9EC04200859AB4 /* AztecUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC400F191E9EC04200859AB4 /* AztecUITests.swift */; }; + CC400F251E9EC16900859AB4 /* XCTest+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC400F241E9EC16900859AB4 /* XCTest+Extensions.swift */; }; E63EF92B1D36A60B00B5BA4B /* EditorDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E63EF92A1D36A60B00B5BA4B /* EditorDemoController.swift */; }; FF6691C21E76CF9200C6A703 /* OptionsTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6691C11E76CF9200C6A703 /* OptionsTableView.swift */; }; FF9AF5481DB0E4E200C42ED3 /* AttachmentDetailsViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FF9AF5471DB0E4E200C42ED3 /* AttachmentDetailsViewController.storyboard */; }; @@ -55,6 +57,13 @@ remoteGlobalIDString = 607FACCF1AFB9204008FA782; remoteInfo = "WordPress-Aztec-iOS"; }; + CC400F1C1E9EC04200859AB4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = AztecExample; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -99,6 +108,10 @@ B570B1C81E82D332008CF41E /* MoreAttachmentRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoreAttachmentRenderer.swift; sourceTree = ""; }; B570B1CB1E82D343008CF41E /* CommentAttachmentRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommentAttachmentRenderer.swift; sourceTree = ""; }; B5AF89331E93ECE60051EFDB /* HTMLAttachmentRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLAttachmentRenderer.swift; sourceTree = ""; }; + CC400F171E9EC04200859AB4 /* AztecUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AztecUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + CC400F191E9EC04200859AB4 /* AztecUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AztecUITests.swift; sourceTree = ""; }; + CC400F1B1E9EC04200859AB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CC400F241E9EC16900859AB4 /* XCTest+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "XCTest+Extensions.swift"; sourceTree = ""; }; E63EF92A1D36A60B00B5BA4B /* EditorDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditorDemoController.swift; sourceTree = ""; }; FF6691C11E76CF9200C6A703 /* OptionsTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionsTableView.swift; sourceTree = ""; }; FF9AF5471DB0E4E200C42ED3 /* AttachmentDetailsViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = AttachmentDetailsViewController.storyboard; sourceTree = ""; }; @@ -120,6 +133,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CC400F141E9EC04200859AB4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -162,6 +182,7 @@ children = ( 607FACD21AFB9204008FA782 /* Example for WordPress-Aztec-iOS */, 607FACE81AFB9204008FA782 /* Tests */, + CC400F181E9EC04200859AB4 /* AztecUITests */, 02ECB379638AE0CDEAB24BEC /* Frameworks */, 607FACD11AFB9204008FA782 /* Products */, 599F257B1D8BD058002871D6 /* Dependencies */, @@ -173,6 +194,7 @@ children = ( 607FACD01AFB9204008FA782 /* AztecExample.app */, 607FACE51AFB9204008FA782 /* AztecExample-Tests.xctest */, + CC400F171E9EC04200859AB4 /* AztecUITests.xctest */, ); name = Products; sourceTree = ""; @@ -231,6 +253,16 @@ name = Renders; sourceTree = ""; }; + CC400F181E9EC04200859AB4 /* AztecUITests */ = { + isa = PBXGroup; + children = ( + CC400F191E9EC04200859AB4 /* AztecUITests.swift */, + CC400F1B1E9EC04200859AB4 /* Info.plist */, + CC400F241E9EC16900859AB4 /* XCTest+Extensions.swift */, + ); + path = AztecUITests; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -272,13 +304,31 @@ productReference = 607FACE51AFB9204008FA782 /* AztecExample-Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + CC400F161E9EC04200859AB4 /* AztecUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = CC400F231E9EC04200859AB4 /* Build configuration list for PBXNativeTarget "AztecUITests" */; + buildPhases = ( + CC400F131E9EC04200859AB4 /* Sources */, + CC400F141E9EC04200859AB4 /* Frameworks */, + CC400F151E9EC04200859AB4 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + CC400F1D1E9EC04200859AB4 /* PBXTargetDependency */, + ); + name = AztecUITests; + productName = AztecUITests; + productReference = CC400F171E9EC04200859AB4 /* AztecUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 607FACC81AFB9204008FA782 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0720; + LastSwiftUpdateCheck = 0830; LastUpgradeCheck = 0800; ORGANIZATIONNAME = "Automattic Inc."; TargetAttributes = { @@ -294,6 +344,11 @@ ProvisioningStyle = Manual; TestTargetID = 607FACCF1AFB9204008FA782; }; + CC400F161E9EC04200859AB4 = { + CreatedOnToolsVersion = 8.3.1; + ProvisioningStyle = Automatic; + TestTargetID = 607FACCF1AFB9204008FA782; + }; }; }; buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AztecExample" */; @@ -317,6 +372,7 @@ targets = ( 607FACCF1AFB9204008FA782 /* AztecExample */, 607FACE41AFB9204008FA782 /* AztecExample-Tests */, + CC400F161E9EC04200859AB4 /* AztecUITests */, ); }; /* End PBXProject section */ @@ -359,6 +415,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CC400F151E9EC04200859AB4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -384,6 +447,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CC400F131E9EC04200859AB4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CC400F251E9EC16900859AB4 /* XCTest+Extensions.swift in Sources */, + CC400F1A1E9EC04200859AB4 /* AztecUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -397,6 +469,11 @@ target = 607FACCF1AFB9204008FA782 /* AztecExample */; targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; }; + CC400F1D1E9EC04200859AB4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* AztecExample */; + targetProxy = CC400F1C1E9EC04200859AB4 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -582,6 +659,72 @@ }; name = Release; }; + CC400F1E1E9EC04200859AB4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + INFOPLIST_FILE = AztecUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = WP.AztecUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + TEST_TARGET_NAME = AztecExample; + }; + name = Debug; + }; + CC400F1F1E9EC04200859AB4 /* Release-Alpha */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + INFOPLIST_FILE = AztecUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = WP.AztecUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_TARGET_NAME = AztecExample; + }; + name = "Release-Alpha"; + }; + CC400F201E9EC04200859AB4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + INFOPLIST_FILE = AztecUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = WP.AztecUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_TARGET_NAME = AztecExample; + }; + name = Release; + }; + CC400F211E9EC04200859AB4 /* Profiling */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + INFOPLIST_FILE = AztecUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = WP.AztecUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_TARGET_NAME = AztecExample; + }; + name = Profiling; + }; F111A10D1DA7E77500294FD3 /* Profiling */ = { isa = XCBuildConfiguration; buildSettings = { @@ -782,6 +925,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + CC400F231E9EC04200859AB4 /* Build configuration list for PBXNativeTarget "AztecUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CC400F1E1E9EC04200859AB4 /* Debug */, + CC400F1F1E9EC04200859AB4 /* Release-Alpha */, + CC400F201E9EC04200859AB4 /* Release */, + CC400F211E9EC04200859AB4 /* Profiling */, + ); + defaultConfigurationIsVisible = 0; + }; /* End XCConfigurationList section */ }; rootObject = 607FACC81AFB9204008FA782 /* Project object */; diff --git a/Example/AztecUITests/AztecUITests.swift b/Example/AztecUITests/AztecUITests.swift new file mode 100644 index 000000000..accbd5514 --- /dev/null +++ b/Example/AztecUITests/AztecUITests.swift @@ -0,0 +1,237 @@ +import XCTest + +class AztecSimpleTextFormattingTests: XCTestCase { + + private var app: XCUIApplication! + private var richTextField: XCUIElement! + + override func setUp() { + super.setUp() + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIDevice.shared().orientation = .portrait + app = XCUIApplication() + app.launch() + + let tablesQuery = app.tables + tablesQuery.staticTexts[elementStringIDs.emptyDemo].tap() + + let richTextField = app.textViews[elementStringIDs.richTextField] + richTextField.tap() + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testSimpleBoldText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.boldButton].tap() + + let text = getHTMLContent() + let expected = "1" + XCTAssertEqual(expected, text) + } + + func testSimpleItalicText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.italicButton].tap() + + let text = getHTMLContent() + let expected = "1" + XCTAssertEqual(expected, text) + } + + func testSimpleUnderlineText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.underlineButton].tap() + + let text = getHTMLContent() + let expected = "1" + XCTAssertEqual(expected, text) + } + + func testSimpleStrikethroughText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.strikethroughButton].tap() + + let text = getHTMLContent() + let expected = "1" + XCTAssertEqual(expected, text) + } + + func testSimpleBlockquoteText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.blockquoteButton].tap() + + let text = getHTMLContent() + let expected = "
1
" + XCTAssertEqual(expected, text) + } + + // Enable this test after unordered lists are fully implemented + /* + func testSimpleUnorderedListText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.unorderedlistButton].tap() + + let text = getHTMLContent() + let expected = "
  • 1
" + XCTAssertEqual(expected, text) + } + */ + + // Enable this test after ordered lists are fully implemented + /* + func testSimpleOrderedListText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.orderedlistButton].tap() + + let text = getHTMLContent() + let expected = "
  1. 1
" + XCTAssertEqual(expected, text) + } + */ + + func testSimpleLinkedText() { + enterTextInField(text: "1") + selectAllTextInField() + + // Copy link to be auto-filled in URL field + UIPasteboard.general.string = "https://wordpress.com/" + app.scrollViews.otherElements.buttons[elementStringIDs.linkButton].tap() + app.alerts.buttons[elementStringIDs.insertLinkConfirmButton].tap() + + let text = getHTMLContent() + let expected = "1" + XCTAssertEqual(expected, text) + } + + func testHorizontalRuler() { + app.scrollViews.otherElements.buttons[elementStringIDs.horizontalrulerButton].tap() + + let text = getHTMLContent() + let expected = "
" + XCTAssertEqual(expected, text) + } + + func testHorizontalRulerWithText() { + enterTextInField(text: "1\n") + app.scrollViews.otherElements.buttons[elementStringIDs.horizontalrulerButton].tap() + enterTextInField(text: "\n2") + + let text = getHTMLContent() + let expected = "1


2" + XCTAssertEqual(expected, text) + } + + func testMoreTag() { + app.scrollViews.otherElements.buttons[elementStringIDs.moreButton].tap() + + let text = getHTMLContent() + let expected = "" + XCTAssertEqual(expected, text) + } + + func testMoreTagWithText() { + enterTextInField(text: "1\n") + app.scrollViews.otherElements.buttons[elementStringIDs.moreButton].tap() + enterTextInField(text: "\n2") + + let text = getHTMLContent() + let expected = "1

2" + XCTAssertEqual(expected, text) + } + + func testHeadingOneText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.headerButton].tap() + app.tables.staticTexts[elementStringIDs.header1Button].tap() + + let text = getHTMLContent() + let expected = "

1

" + XCTAssertEqual(expected, text) + } + + func testHeadingTwoText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.headerButton].tap() + app.tables.staticTexts[elementStringIDs.header2Button].tap() + + let text = getHTMLContent() + let expected = "

1

" + XCTAssertEqual(expected, text) + } + + func testHeadingThreeText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.headerButton].tap() + app.tables.staticTexts[elementStringIDs.header3Button].tap() + + let text = getHTMLContent() + let expected = "

1

" + XCTAssertEqual(expected, text) + } + + func testHeadingFourText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.headerButton].tap() + app.tables.element(boundBy: 0).swipeUp() + app.tables.staticTexts[elementStringIDs.header4Button].tap() + + let text = getHTMLContent() + let expected = "

1

" + XCTAssertEqual(expected, text) + } + + func testHeadingFiveText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.headerButton].tap() + app.tables.element(boundBy: 0).swipeUp() + app.tables.staticTexts[elementStringIDs.header5Button].tap() + + let text = getHTMLContent() + let expected = "
1
" + XCTAssertEqual(expected, text) + } + + func testHeadingSixText() { + enterTextInField(text: "1") + selectAllTextInField() + + app.scrollViews.otherElements.buttons[elementStringIDs.headerButton].tap() + app.tables.element(boundBy: 0).swipeUp() + app.tables.staticTexts[elementStringIDs.header6Button].tap() + + let text = getHTMLContent() + let expected = "
1
" + XCTAssertEqual(expected, text) + } +} diff --git a/Example/AztecUITests/Info.plist b/Example/AztecUITests/Info.plist new file mode 100644 index 000000000..6c6c23c43 --- /dev/null +++ b/Example/AztecUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Example/AztecUITests/XCTest+Extensions.swift b/Example/AztecUITests/XCTest+Extensions.swift new file mode 100644 index 000000000..29ea34515 --- /dev/null +++ b/Example/AztecUITests/XCTest+Extensions.swift @@ -0,0 +1,70 @@ +import XCTest + +public struct elementStringIDs { + // Demo Menu + static var emptyDemo = "Empty Editor Demo" + + // Text Fields + static var richTextField = "richContentView" + static var htmlTextField = "HTMLContentView" + + // Alerts + static var insertLinkConfirmButton = "Insert Link" + + // Toolbar + static var mediaButton = "formatToolbarInsertMedia" + static var headerButton = "formatToolbarSelectParagraphStyle" + static var boldButton = "formatToolbarToggleBold" + static var italicButton = "formatToolbarToggleItalic" + static var underlineButton = "formatToolbarToggleUnderline" + static var strikethroughButton = "formatToolbarToggleStrikethrough" + static var blockquoteButton = "formatToolbarToggleBlockquote" + static var orderedlistButton = "formatToolbarToggleListOrdered" + static var unorderedlistButton = "formatToolbarToggleListUnordered" + static var linkButton = "formatToolbarInsertLink" + static var horizontalrulerButton = "formatToolbarInsertHorizontalRuler" + static var sourcecodeButton = "formatToolbarToggleHtmlView" + static var moreButton = "formatToolbarInsertMore" + static var header1Button = "Heading 1" + static var header2Button = "Heading 2" + static var header3Button = "Heading 3" + static var header4Button = "Heading 4" + static var header5Button = "Heading 5" + static var header6Button = "Heading 6" +} + +extension XCTest { + /** + Enters text in the rich text field with auto-correction disabled + - Parameter text: the test to enter into the field + */ + func enterTextInField(text: String) -> Void { + let app = XCUIApplication() + let richTextField = app.textViews[elementStringIDs.richTextField] + + richTextField.typeText(text) + } + + /** + Selects all entered text in the rich text field + */ + func selectAllTextInField() -> Void { + let app = XCUIApplication() + let richTextField = app.textViews[elementStringIDs.richTextField] + + richTextField.press(forDuration: 1.2) + app.menuItems.element(boundBy: 1).tap() + } + + /** + Gets the contents of the HTML text view + */ + func getHTMLContent() -> String { + let app = XCUIApplication() + + app.buttons[elementStringIDs.sourcecodeButton].tap() + let htmlContentTextView = app.textViews[elementStringIDs.htmlTextField] + let text = htmlContentTextView.value as! String + return text + } +} diff --git a/Example/Example/EditorDemoController.swift b/Example/Example/EditorDemoController.swift index 6e5e78489..299438bce 100644 --- a/Example/Example/EditorDemoController.swift +++ b/Example/Example/EditorDemoController.swift @@ -20,6 +20,7 @@ class EditorDemoController: UIViewController { textView.delegate = self textView.formattingDelegate = self textView.mediaDelegate = self + textView.accessibilityIdentifier = "richContentView" return textView }() @@ -34,6 +35,7 @@ class EditorDemoController: UIViewController { textView.isHidden = true textView.delegate = self + textView.accessibilityIdentifier = "HTMLContentView" return textView }() @@ -681,6 +683,13 @@ extension EditorDemoController : Aztec.FormatBarDelegate { // MARK: - + func makeToolbarButton(identifier: FormattingIdentifier) -> FormatBarItem { + let button = FormatBarItem(image: identifier.iconImage, identifier: identifier) + button.accessibilityLabel = identifier.accessibilityLabel + button.accessibilityIdentifier = identifier.accessibilityIdentifier + return button + } + func createToolbar(htmlMode: Bool) -> Aztec.FormatBar { let scrollableItems = scrollableItemsForToolbar @@ -712,24 +721,24 @@ extension EditorDemoController : Aztec.FormatBarDelegate { var scrollableItemsForToolbar: [FormatBarItem] { return [ - FormatBarItem(image: Gridicon.iconOfType(.addImage), identifier: .media), - FormatBarItem(image: Gridicon.iconOfType(.heading), identifier: .header), - FormatBarItem(image: Gridicon.iconOfType(.bold), identifier: .bold), - FormatBarItem(image: Gridicon.iconOfType(.italic), identifier: .italic), - FormatBarItem(image: Gridicon.iconOfType(.underline), identifier: .underline), - FormatBarItem(image: Gridicon.iconOfType(.strikethrough), identifier: .strikethrough), - FormatBarItem(image: Gridicon.iconOfType(.quote), identifier: .blockquote), - FormatBarItem(image: Gridicon.iconOfType(.listUnordered), identifier: .unorderedlist), - FormatBarItem(image: Gridicon.iconOfType(.listOrdered), identifier: .orderedlist), - FormatBarItem(image: Gridicon.iconOfType(.link), identifier: .link), - FormatBarItem(image: Gridicon.iconOfType(.minusSmall), identifier: .horizontalruler), - FormatBarItem(image: Gridicon.iconOfType(.readMore), identifier: .more) + makeToolbarButton(identifier: .media), + makeToolbarButton(identifier: .header), + makeToolbarButton(identifier: .bold), + makeToolbarButton(identifier: .italic), + makeToolbarButton(identifier: .underline), + makeToolbarButton(identifier: .strikethrough), + makeToolbarButton(identifier: .blockquote), + makeToolbarButton(identifier: .unorderedlist), + makeToolbarButton(identifier: .orderedlist), + makeToolbarButton(identifier: .link), + makeToolbarButton(identifier: .horizontalruler), + makeToolbarButton(identifier: .more) ] } var fixedItemsForToolbar: [FormatBarItem] { return [ - FormatBarItem(image: Gridicon.iconOfType(.code), identifier: .sourcecode) + makeToolbarButton(identifier: .sourcecode) ] } @@ -958,3 +967,136 @@ extension EditorDemoController { static let moreAttachmentText = "more" } } + +extension FormattingIdentifier { + + var iconImage: UIImage { + + switch(self) { + case .media: + return Gridicon.iconOfType(.addImage) + case .header: + return Gridicon.iconOfType(.heading) + case .bold: + return Gridicon.iconOfType(.bold) + case .italic: + return Gridicon.iconOfType(.italic) + case .underline: + return Gridicon.iconOfType(.underline) + case .strikethrough: + return Gridicon.iconOfType(.strikethrough) + case .blockquote: + return Gridicon.iconOfType(.quote) + case .orderedlist: + return Gridicon.iconOfType(.listOrdered) + case .unorderedlist: + return Gridicon.iconOfType(.listUnordered) + case .link: + return Gridicon.iconOfType(.link) + case .horizontalruler: + return Gridicon.iconOfType(.minusSmall) + case .sourcecode: + return Gridicon.iconOfType(.code) + case .more: + return Gridicon.iconOfType(.readMore) + case .header1: + return Gridicon.iconOfType(.heading) + case .header2: + return Gridicon.iconOfType(.heading) + case .header3: + return Gridicon.iconOfType(.heading) + case .header4: + return Gridicon.iconOfType(.heading) + case .header5: + return Gridicon.iconOfType(.heading) + case .header6: + return Gridicon.iconOfType(.heading) + } + } + + var accessibilityIdentifier: String { + switch(self) { + case .media: + return "formatToolbarInsertMedia" + case .header: + return "formatToolbarSelectParagraphStyle" + case .bold: + return "formatToolbarToggleBold" + case .italic: + return "formatToolbarToggleItalic" + case .underline: + return "formatToolbarToggleUnderline" + case .strikethrough: + return "formatToolbarToggleStrikethrough" + case .blockquote: + return "formatToolbarToggleBlockquote" + case .orderedlist: + return "formatToolbarToggleListOrdered" + case .unorderedlist: + return "formatToolbarToggleListUnordered" + case .link: + return "formatToolbarInsertLink" + case .horizontalruler: + return "formatToolbarInsertHorizontalRuler" + case .sourcecode: + return "formatToolbarToggleHtmlView" + case .more: + return "formatToolbarInsertMore" + case .header1: + return "formatToolbarToggleH1" + case .header2: + return "formatToolbarToggleH2" + case .header3: + return "formatToolbarToggleH3" + case .header4: + return "formatToolbarToggleH4" + case .header5: + return "formatToolbarToggleH5" + case .header6: + return "formatToolbarToggleH6" + } + } + + var accessibilityLabel: String { + switch(self) { + case .media: + return NSLocalizedString("Insert media", comment: "Accessibility label for insert media button on formatting toolbar.") + case .header: + return NSLocalizedString("Select paragraph style", comment: "Accessibility label for selecting paragraph style button on formatting toolbar.") + case .bold: + return NSLocalizedString("Bold", comment: "Accessibility label for bold button on formatting toolbar.") + case .italic: + return NSLocalizedString("Italic", comment: "Accessibility label for italic button on formatting toolbar.") + case .underline: + return NSLocalizedString("Underline", comment: "Accessibility label for underline button on formatting toolbar.") + case .strikethrough: + return NSLocalizedString("Strike Through", comment: "Accessibility label for strikethrough button on formatting toolbar.") + case .blockquote: + return NSLocalizedString("Block Quote", comment: "Accessibility label for block quote button on formatting toolbar.") + case .orderedlist: + return NSLocalizedString("Ordered List", comment: "Accessibility label for Ordered list button on formatting toolbar.") + case .unorderedlist: + return NSLocalizedString("Unordered List", comment: "Accessibility label for unordered list button on formatting toolbar.") + case .link: + return NSLocalizedString("Insert Link", comment: "Accessibility label for insert link button on formatting toolbar.") + case .horizontalruler: + return NSLocalizedString("Insert Horizontal Ruler", comment: "Accessibility label for insert horizontal ruler button on formatting toolbar.") + case .sourcecode: + return NSLocalizedString("HTML", comment:"Accessibility label for HTML button on formatting toolbar.") + case .more: + return NSLocalizedString("More", comment:"Accessibility label for the More button on formatting toolbar.") + case .header1: + return NSLocalizedString("Header 1", comment: "Accessibility label for selecting h1 paragraph style button on the formatting toolbar.") + case .header2: + return NSLocalizedString("Header 2", comment: "Accessibility label for selecting h2 paragraph style button on the formatting toolbar.") + case .header3: + return NSLocalizedString("Header 3", comment: "Accessibility label for selecting h3 paragraph style button on the formatting toolbar.") + case .header4: + return NSLocalizedString("Header 4", comment: "Accessibility label for selecting h4 paragraph style button on the formatting toolbar.") + case .header5: + return NSLocalizedString("Header 5", comment: "Accessibility label for selecting h5 paragraph style button on the formatting toolbar.") + case .header6: + return NSLocalizedString("Header 6", comment: "Accessibility label for selecting h6 paragraph style button on the formatting toolbar.") + } + } +}