Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Example/AztecExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
B570B1CC1E82D343008CF41E /* CommentAttachmentRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B570B1CB1E82D343008CF41E /* CommentAttachmentRenderer.swift */; };
B5AF89341E93ECE60051EFDB /* HTMLAttachmentRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AF89331E93ECE60051EFDB /* HTMLAttachmentRenderer.swift */; };
B5DB1C371EC630E10005E623 /* UnknownEditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DB1C361EC630E10005E623 /* UnknownEditorViewController.swift */; };
BE6AF9551FB9EA30003846F9 /* BlogsPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6AF9541FB9EA30003846F9 /* BlogsPage.swift */; };
BE88E4651FB5BA5000F83E61 /* HighPriorityIssuesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE88E4621FB5BA5000F83E61 /* HighPriorityIssuesTests.swift */; };
BE8EAC701FC1DE34005CD7D0 /* BasePage.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE8EAC6F1FC1DE34005CD7D0 /* BasePage.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 */; };
Expand Down Expand Up @@ -117,6 +120,9 @@
B570B1CB1E82D343008CF41E /* CommentAttachmentRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommentAttachmentRenderer.swift; sourceTree = "<group>"; };
B5AF89331E93ECE60051EFDB /* HTMLAttachmentRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLAttachmentRenderer.swift; sourceTree = "<group>"; };
B5DB1C361EC630E10005E623 /* UnknownEditorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnknownEditorViewController.swift; sourceTree = "<group>"; };
BE6AF9541FB9EA30003846F9 /* BlogsPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogsPage.swift; sourceTree = "<group>"; };
BE88E4621FB5BA5000F83E61 /* HighPriorityIssuesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HighPriorityIssuesTests.swift; sourceTree = "<group>"; };
BE8EAC6F1FC1DE34005CD7D0 /* BasePage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasePage.swift; sourceTree = "<group>"; };
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 = "<group>"; };
CC400F1B1E9EC04200859AB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -272,9 +278,20 @@
name = Renders;
sourceTree = "<group>";
};
BE8EAC6A1FC1DCF3005CD7D0 /* Pages */ = {
isa = PBXGroup;
children = (
BE6AF9541FB9EA30003846F9 /* BlogsPage.swift */,
BE8EAC6F1FC1DE34005CD7D0 /* BasePage.swift */,
);
path = Pages;
sourceTree = "<group>";
};
CC400F181E9EC04200859AB4 /* AztecUITests */ = {
isa = PBXGroup;
children = (
BE8EAC6A1FC1DCF3005CD7D0 /* Pages */,
BE88E4621FB5BA5000F83E61 /* HighPriorityIssuesTests.swift */,
CC400F191E9EC04200859AB4 /* AztecUITests.swift */,
CC400F1B1E9EC04200859AB4 /* Info.plist */,
CC400F241E9EC16900859AB4 /* XCTest+Extensions.swift */,
Expand Down Expand Up @@ -491,7 +508,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BE88E4651FB5BA5000F83E61 /* HighPriorityIssuesTests.swift in Sources */,
BE8EAC701FC1DE34005CD7D0 /* BasePage.swift in Sources */,
CC400F251E9EC16900859AB4 /* XCTest+Extensions.swift in Sources */,
BE6AF9551FB9EA30003846F9 /* BlogsPage.swift in Sources */,
CC400F1A1E9EC04200859AB4 /* AztecUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@
ReferencedContainer = "container:AztecExample.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CC400F161E9EC04200859AB4"
BuildableName = "AztecUITests.xctest"
BlueprintName = "AztecUITests"
ReferencedContainer = "container:AztecExample.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
Expand Down
9 changes: 3 additions & 6 deletions Example/AztecUITests/AztecUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@ class AztecSimpleTextFormattingTests: XCTestCase {
app = XCUIApplication()
app.launch()

let tablesQuery = app.tables
tablesQuery.staticTexts[elementStringIDs.emptyDemo].tap()

let richTextField = app.textViews[elementStringIDs.richTextField]
richTextField.tap()
let blogsPage = BlogsPage.init(appInstance: app)
blogsPage.gotoEmptyDemo()
}

override func tearDown() {
Expand Down Expand Up @@ -139,7 +136,7 @@ class AztecSimpleTextFormattingTests: XCTestCase {
}

/*
Commenting these out because they fail. Should not be wrapped in a <p> tag, see #818.
Commenting these out because they fail. Should not be wrapped in a <p> tag, see #818.
func testMoreTag() {
app.scrollViews.otherElements.buttons[elementStringIDs.moreButton].tap()

Expand Down
128 changes: 128 additions & 0 deletions Example/AztecUITests/HighPriorityIssuesTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import XCTest

class HighPriorityIssuesTests: 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 blogsPage = BlogsPage.init(appInstance: app)
blogsPage.gotoEmptyDemo()
}

override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}

// Github issue https://github.com/wordpress-mobile/AztecEditor-iOS/issues/385
func testLongTitle() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is still failing on larger devices (e.g. iPad Pro). If there isn't a way to get it to work for both large and small devices, could we restrict it to only run when testing smaller devices?

Copy link
Contributor Author

@brbrr brbrr Nov 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think its possible to tag which tests to run with current test runner (as it's done in wp-e2e-tests). The only solution I see is to move such tests to separate files and run them only for small screens. And in general, I think it would be better to address this issue once we'll have them running on multiple devices. I've created the ticket for that: #839

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked around and found these hints and tips that include conditional code for testing on iPhone v. iPad. I updated the example shown there and got it to work in this test like this:

if (app.windows.element(boundBy: 0).horizontalSizeClass == .compact || app.windows.element(boundBy: 0).verticalSizeClass == .compact) {
            titleTextView.typeText("very very very very very very long title in a galaxy not so far away")
        } else {
            titleTextView.typeText("very very very very very very long title in a galaxy not so far away very very very very very very long title in a galaxy not so far away")
        }

// Title line height is about 22px, so it might be useing for comparing the height difference should make it precise.
// But may be fragile due to different font sizes etc
let titleLineHeight = 22
let titleTextView = app.textViews[elementStringIDs.titleTextField]
titleTextView.tap()
let oneLineTitleHeight = Int(titleTextView.frame.height)

// TODO: Move it into EditorPage
if (app.windows.element(boundBy: 0).horizontalSizeClass == .compact || app.windows.element(boundBy: 0).verticalSizeClass == .compact) {
titleTextView.typeText("very very very very very very long title in a galaxy not so far away")
} else {
titleTextView.typeText("very very very very very very long title in a galaxy not so far away very very very very very very long title in a galaxy not so far away")
}

let twoLineTitleHeight = Int(titleTextView.frame.height)
XCTAssert(twoLineTitleHeight - oneLineTitleHeight == titleLineHeight ) // XCTAssert(oneLineTitleHeight < twoLineTitleHeight)
}

// Github issue https://github.com/wordpress-mobile/AztecEditor-iOS/issues/675
func testInfiniteLoopOnAssetDownload() {
switchContentView()
enterTextInHTML(text: "<img src=\"https://someinvalid.url/with-an-invalid-resource\">")
switchContentView()
gotoRootPage()

let editorDemoButton = app.tables.staticTexts[elementStringIDs.emptyDemo]
XCTAssert(editorDemoButton.exists, "Editor button not hittable. Are you on the right page?")
}

// Github issue https://github.com/wordpress-mobile/AztecEditor-iOS/issues/465
func testTypeAfterInvalidHTML() {
switchContentView()
enterTextInHTML(text: "<qaz!>")
switchContentView()

let field = app.textViews[elementStringIDs.richTextField]
// Some magic to move caret to end of the text
let vector = CGVector(dx:field.frame.width, dy:field.frame.height - field.frame.minY)
field.coordinate(withNormalizedOffset:CGVector.zero).withOffset(vector).tap()
enterTextInField(text: "Some text after invalid HTML tag")

let text = getHTMLContent()
XCTAssertEqual(text, "<p><qaz></qaz>Some text after invalid HTML tag</p>")
}

// Github issue https://github.com/wordpress-mobile/AztecEditor-iOS/issues/768
func testLooseStylesNoContent() {
let boldButton = app.scrollViews.otherElements.buttons[elementStringIDs.boldButton]
let italicButton = app.scrollViews.otherElements.buttons[elementStringIDs.italicButton]

XCTAssert(!boldButton.isSelected && !italicButton.isSelected)
boldButton.tap()
italicButton.tap()

enterTextInField(text: "q")
let deleteButton = app.keys["delete"]
deleteButton.tap()
deleteButton.tap()
XCTAssert(boldButton.isSelected && italicButton.isSelected)
}

// Github issue https://github.com/wordpress-mobile/AztecEditor-iOS/issues/771
func testCopyPasteCrash() {
// gotoRootPage()
// let blogsPage = BlogsPage.init(appInstance: app)
// blogsPage.gotoDemo()

let text = "<h1>Sample HTML content</h1> <p>this is some text that is spread out across several lines but is rendered on a single line in a browser</p> <h2>Character Styles</h2> <p><strong>Bold text</strong><br><em>Italic text</em><br><u>Underlined text</u><br><del>Strikethrough</del><br><span style=\"color: #ff0000\">Colors</span><br><span style=\"text-decoration: underline\">Alternative underline text</span><br><a href=\"http://www.wordpress.com\">I'm a link!</a><br><!--more-->Text after the more break</p> <h2>Lists</h2> <h3>Unordered List:</h3> <ul> <li>One</li> <li>Two</li> <li>Three</li> </ul> <h3>Ordered List:</h3> <ol> <li>One</li> <li>Two</li> <li>Three</li> </ol> <p> <hr> </p>"

switchContentView()
// selectAllTextInHTMLField()
enterTextInHTML(text: text)

let htmlContentView = app.textViews[elementStringIDs.htmlTextField]
// let text = htmlContentView.value as! String

selectAllTextInHTMLField()
app.menuItems[elementStringIDs.copyButton].tap()
htmlContentView.swipeUp()
htmlContentView.swipeUp()
htmlContentView.swipeUp()

// determinating where to click to put caret to end of text
let frame = htmlContentView.frame
let buttonFrame = app.scrollViews.otherElements.buttons[elementStringIDs.mediaButton].frame.height
let vector = CGVector(dx: frame.width, dy: frame.height - (buttonFrame + 1))

htmlContentView.coordinate(withNormalizedOffset:CGVector.zero).withOffset(vector).tap()
htmlContentView.typeText("\n\n")
htmlContentView.tap()
app.menuItems[elementStringIDs.pasteButton].tap()

sleep(3) // to make sure everything is updated
let newText = htmlContentView.value as! String

XCTAssertEqual(newText, text + "\n\n" + text)
}
}


23 changes: 23 additions & 0 deletions Example/AztecUITests/Pages/BasePage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Foundation
import XCTest

class BasePage {
var app: XCUIApplication!
private var expectedElement: XCUIElement!
var waitTimeout: Double!

init(appInstance: XCUIApplication, element: XCUIElement) {
app = appInstance
expectedElement = element
waitTimeout = 20
waitForPage()
}

func waitForPage() {
expectedElement.waitForExistence(timeout: waitTimeout)
}

func isLoaded() -> Bool {
return expectedElement.exists
}
}
37 changes: 37 additions & 0 deletions Example/AztecUITests/Pages/BlogsPage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Foundation
import XCTest


class BlogsPage: BasePage {

init(appInstance: XCUIApplication) {
let expectedElement = appInstance.tables.staticTexts[elementStringIDs.emptyDemo]
super.init(appInstance: appInstance, element: expectedElement)
}

func gotoEmptyDemo() {
app.staticTexts[elementStringIDs.emptyDemo].tap()

showOptionsStrip()
}

func gotoDemo() {
app.staticTexts[elementStringIDs.demo].tap()

showOptionsStrip()
}

func showOptionsStrip() -> Void {
app.textViews[elementStringIDs.richTextField].tap()
expandOptionsSctrip()
}

func expandOptionsSctrip() -> Void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On larger devices (e.g. iPad Pro) this function is toggling the extended toolbar open/closed rather than always expanding it. We should check the status of the toolbar before tapping — otherwise the expanded toolbar is toggled off in every other test.

If it isn't currently possible to check the status, we should open an issue to address that as it's also an accessibility issue. (VoiceOver users need to be aware of the toolbar status so they can expand it if needed, too.)

Copy link
Contributor Author

@brbrr brbrr Nov 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created the ticket for that: #837

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, how about checking to see if the HTML button exists before toggling the extended toolbar? I'm thinking of something like this:

        let expandButton = app.children(matching: .window).element(boundBy: 1).children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .button).element
        let htmlButton = app.scrollViews.otherElements.buttons[elementStringIDs.sourcecodeButton]
        
        if expandButton.exists && expandButton.isHittable && !htmlButton.exists {
            expandButton.tap()
        }

That way we don't break the existing tests on iPads, and we can improve the check later once that issue is resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's nice solution, thanks!

let expandButton = app.children(matching: .window).element(boundBy: 1).children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .button).element
let htmlButton = app.scrollViews.otherElements.buttons[elementStringIDs.sourcecodeButton]

if expandButton.exists && expandButton.isHittable && !htmlButton.exists {
expandButton.tap()
}
}
}
Loading