Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update docs and make them more lean #458

Merged
merged 4 commits into from Mar 30, 2017
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -45,7 +45,8 @@ You can bring more specific issues to our attention by asking them on
You can also start new discussions with us on our [Google group](https://groups.google.com/forum/#!forum/earlgrey-discuss)
or request to join our [slack channel](https://googleoss.slack.com/messages/earlgrey).

* [FAQ](https://github.com/google/EarlGrey/tree/master/docs/faq.md)
* [FAQ - Frequently Asked Questions](https://github.com/google/EarlGrey/tree/master/docs/faq.md)
* [IFAQ - Infrequently Asked Questions](https://github.com/google/EarlGrey/tree/master/docs/ifaq.md)
* [Known Issues](https://github.com/google/EarlGrey/tree/master/docs/known-issues.md)
* [Stack Overflow](http://stackoverflow.com/questions/tagged/earlgrey)
* [Slack](https://googleoss.slack.com/messages/earlgrey)
Expand Down
105 changes: 56 additions & 49 deletions docs/faq.md
@@ -1,6 +1,12 @@
# FAQ

**How does EarlGrey compare to Xcode’s UI Testing?**
#### **I see lots of “XXX is implemented in both YYY and ZZZ. One of the two will be used. Which one is undefined.” in the logs**

This usually means that EarlGrey is being linked to more than once. Ensure that only the **Test Target**
depends on *EarlGrey.framework* and EarlGrey.framework is embedded in the app under test (i.e. *$TEST_HOST*) from the
test target's built products via a Copy File(s) Build Phase.

#### **How does EarlGrey compare to Xcode’s UI Testing?**

EarlGrey is more of a [gray-box testing](https://en.wikipedia.org/wiki/Gray_box_testing) solution
whereas Xcode’s UI Testing is completely [black-box](https://en.wikipedia.org/wiki/Black-box_testing).
Expand All @@ -18,25 +24,15 @@ assertions. The ability to search for elements (using search actions) makes test
UI changes. For example, EarlGrey provides APIs that allow searching for elements in scrollable
containers, regardless of the amount of scrolling required.

**I get a crash with “Could not swizzle …”**
#### **Why do the tests have the application scaled with borders around it? How can I get them to fit in the video frame?**

This means that EarlGrey is trying to swizzle a method that it has swizzled before. It is a result of EarlGrey being linked to more than once. Ensure that only the **Test Target**
depends on *EarlGrey.framework* and EarlGrey.framework is embedded in the app under test (i.e. *$TEST_HOST*) from the
test target's build phase.
For your tests to have the application properly scaled, make sure the app under test has correct launch screen images present for all supported devices (see
[iOS Developer Library, Launch Files](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/LaunchImages.html)).

**I see lots of “XXX is implemented in both YYY and ZZZ. One of the two will be used. Which one is
undefined.” in the logs**

This usually means that EarlGrey is being linked to more than once. Ensure that only the **Test Target**
depends on *EarlGrey.framework* and EarlGrey.framework is embedded in the app under test (i.e. *$TEST_HOST*) from the
test target's build phase.

**Is there a way to return a specific element?**
#### **Is there a way to return a specific element?**

No, but there is a better alternative. Use [GREYActionBlock](../EarlGrey/Action/GREYActionBlock.h)
to create a custom GREYAction and access any fields or invoke any selector on the element. For
example, if you want to invoke a selector on an element, you can use syntax similar to the
following:
to create a custom GREYAction and access any fields or invoke any selector on the element. For example, if you want to invoke a selector on an element, you can use syntax similar to the following:


```objc
Expand Down Expand Up @@ -74,19 +70,26 @@ open class Element {
* GREYAssertTrue(element.text != "", reason: "get text failed")
*/
public func grey_getText(_ elementCopy: Element) -> GREYActionBlock {
return GREYActionBlock.action(withName: "get text",
constraints: grey_respondsToSelector(#selector(getter: UILabel.text))) { element,
return GREYActionBlock.action(withName: "get text",
constraints: grey_respondsToSelector(#selector(getter: UILabel.text))) { element,
errorOrNil -> Bool in
let elementObject = element as? NSObject
let text = elementObject?.perform(#selector(getter: UILabel.text),
let text = elementObject?.perform(#selector(getter: UILabel.text),
with: nil)?.takeRetainedValue() as? String
elementCopy.text = text ?? ""
return true
}
}
```

**How do I check whether an element exists in the UI hierarchy?**
#### **I get a crash with “Could not swizzle …”**

This means that EarlGrey is trying to swizzle a method that it has swizzled before. It is a result
of EarlGrey being linked to more than once. Ensure that only the **Test Target**
depends on *EarlGrey.framework* and EarlGrey.framework is embedded in the app under test (i.e. *$TEST_HOST*) from the
test target's build phase.

#### **How do I check whether an element exists in the UI hierarchy?**

If you are unsure whether the element exists in the UI hierarchy, pass an `NSError` to the
interaction and check if the error domain and code indicate that the element wasn’t found:
Expand All @@ -103,7 +106,7 @@ if ([error.domain isEqual:kGREYInteractionErrorDomain] &&
}
```

**My app shows a splash screen. How can I make my test wait for the main screen?**
#### **My app shows a splash screen. How can I make my test wait for the main screen?**

Use [GREYCondition](../EarlGrey/Synchronization/GREYCondition.h) in your test's setup method to
wait for the main screen’s view controller. Here’s an example:
Expand All @@ -126,35 +129,35 @@ wait for the main screen’s view controller. Here’s an example:
}
```

**Will my test fail if I have other modal dialogs showing on top of my app?**
#### **Will my test fail if I have other modal dialogs showing on top of my app?**

Yes, if these dialogs belong to the app process running the test and are obscuring UI elements with
which tests are interacting.

**Can I use Xcode Test Navigator?**
#### **Can I use Xcode Test Navigator?**

Yes. EarlGrey supports **Test Navigator** out-of-the-box.

**Can I set debug breakpoints in the middle of a test?**
#### **Can I set debug breakpoints in the middle of a test?**

Yes. You can set a breakpoint on any interaction. The breakpoint will be hit before that
interaction is executed, but after all prior interactions have been executed.

**Where do I find the xctest bundle?**
#### **Where do I find the XCTest bundle?**

For the Example project, run the `EarlGreyExampleSwiftTests` target once then find the bundle:

> cd ~/Library/Developer/Xcode/DerivedData/EarlGreyExample-*/Build/Products/Debug-iphonesimulator/EarlGreyExampleSwift.app/PlugIns/EarlGreyExampleSwiftTests.xctest/

For physical device builds, replace `Debug-iphonesimulator` with `Debug-iphoneos`.

**How do I resolve "dyld: could not load inserted library '@executable_path/EarlGrey.framework/EarlGrey' because image not found" error?**
#### **How do I resolve "dyld: could not load inserted library '@executable_path/EarlGrey.framework/EarlGrey' because image not found" error?**

The error means that the dynamic loader is unable to find *EarlGrey.framework* at the specified path: `@executable_path/EarlGrey.framework/EarlGrey`

Verify that *EarlGrey.framework* is embedded in the app under test bundle. Build the **Test Target** and check for EarlGrey.framework in the app under test bundle. For an app named *MyApp*, EarlGrey.framework should be at `MyApp.app/EarlGrey.framework`. If it isn't there, make sure that the **Test Target** has a `Copy to $(TEST_HOST)` script in **Build Phases**. Follow [these instructions](install-and-run.md) on how to configure it. After configuring it, rebuild and check again. If EarlGrey.framework is still not present in the app under test bundle, please [open an issue](https://github.com/google/EarlGrey/issues/new) describing your project setup and the full error in detail.

**How should I handle animations?**
#### **How should I handle animations?**

By default, [EarlGrey truncates CALayer based animations](../EarlGrey/Common/GREYConfiguration.h#L108) that exceed a threshold. The max animation duration setting is configurable:

Expand All @@ -178,34 +181,39 @@ Refer to the [PSPDFKit blog post for more details.](https://pspdfkit.com/blog/20

```swift
// Swift
UIApplication.sharedApplication().keyWindow?.layer.speed = 100
GREYTestHelper.enableFastAnimation()
```

```swift
// Objective-C
[GREYTestHelper enableFastAnimation];
```

If the above doesn't help, you can temporarily disable synchronization to work around an animation
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: place the swift code example before objc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

and then turn it back on after the animation is gone.

```swift
// Swift
GREYConfiguration.sharedInstance().setValue(false, forConfigKey: kGREYConfigKeySynchronizationEnabled)
```

```objc
// Objective-C
[[GREYConfiguration sharedInstance] setValue:@NO
forConfigKey:kGREYConfigKeySynchronizationEnabled];
```

```swift
// Swift
GREYConfiguration.sharedInstance().setValue(false, forConfigKey: kGREYConfigKeySynchronizationEnabled)
```

Alternatively, conditionally disable the animation using `#if EARLGREY_ENV`.

**How do I match an element when it's duplicated in the app?**
#### **How do I match an element when it's duplicated in the app?**

EarlGrey requires all matchers return exactly one element.
This is difficult to do when an element is duplicated (same label/class/location).

We recommend combining the matchers [as suggested here](api.md#earlgrey-matchers) and then adding
`grey_interactable()` or `grey_sufficientlyVisible()`.

**How do I reset application state before each test?**
#### **How do I reset application state before each test?**

In the application target's Build Settings, set **Defines Module** to **Yes**. Create a `resetApplicationForTesting()` method on the AppDelegate. The reset method will be invoked on `setUp` instead of `tearDown` because otherwise there's no guarantee the app will be in a clean state when the first test is run.

Expand Down Expand Up @@ -247,7 +255,7 @@ In the EarlGrey test target, import the application's app delegate header. In `s
}
```

**How do I create a matcher that matches internal UIKit classes?**
#### **How do I create a matcher that matches internal UIKit classes?**

Use `NSClassFromString` to match on internal classes that can't be referenced directly.

Expand All @@ -256,7 +264,7 @@ Use `NSClassFromString` to match on internal classes that can't be referenced di
grey_kindOfClass(NSClassFromString("_UIAlertControllerView"))
```

**Why does the screen appear frozen for 30 seconds?**
#### **Why does the screen appear frozen for 30 seconds?**

If the tests are erroring with a timeout, then a background animation or synchronization bug may be keeping the application busy. EarlGrey will timeout interactions after 30 seconds.

Expand Down Expand Up @@ -295,7 +303,7 @@ then all elements in the entire application will be checked for visibility, and
with a matching id will be selected. It's significantly faster to use the most targeted
matchers first (typically `grey_accessibilityID` or `grey_accessibilityLabel`).

**How do I inspect the EarlGrey view hierarchy?**
#### **How do I inspect the EarlGrey view hierarchy?**

Breakpoint in any test, then paste the following into Xcode's lldb debug window:

Expand All @@ -308,7 +316,7 @@ Breakpoint in any test, then paste the following into Xcode's lldb debug window:
```


**How can I detect if I'm running in an EarlGrey target?**
#### **How can I detect if I'm running in an EarlGrey target?**

Creating a [build configuration](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html#//apple_ref/doc/uid/TP40014216-CH8-ID34) for EarlGrey will allow compilation:

Expand All @@ -328,7 +336,7 @@ Alternatively, perform a runtime check for the EarlGrey class:
public static let envEarlGrey:Bool = NSClassFromString("EarlGreyImpl") != nil
```

**How do I find off screen elements?**
#### **How do I find off screen elements?**

EarlGrey requires elements to be visible (in the UI hierarchy) to perform automation.
Just as a user would, scroll elements into view before interacting with them.
Expand All @@ -354,7 +362,7 @@ EarlGrey.select(elementWithMatcher:matcher)
assertWithMatcher:grey_notNil()];
```

**How do I wait for an element to appear using Swift?**
#### **How do I wait for an element to appear using Swift?**

The best way is to [setup synchronization](features.md#synchronization) so that EarlGrey automatically waits
for elements to appear. As a work around for when that's not possible, `GREYCondition` and `waitWithTimeout`
Expand All @@ -375,7 +383,7 @@ let populated = GREYCondition(name: "Wait for UICollectionView to populate", blo
GREYAssertTrue(populated, reason: "Failed to populate UICollectionView in 20 seconds")
```

**How do I match elements that are denoted with "AX=N" in the view hierarchy?**
#### **How do I match elements that are denoted with "AX=N" in the view hierarchy?**

EarlGrey's view hierarchy identifies non-accessible elements with `AX=N`.
Accessibility IDs can be added to both accessible and non-accessible elements.
Expand All @@ -389,7 +397,7 @@ When searching for AX=N elements, the following accessibility matchers won't wor
If the `AX=N` element can't be matched by `grey_accessibilityID`, then you'll have to use non-accessibility
matchers to locate the element.

**Why does my Swift project throw compiler errors for all the shorthand matchers?**
#### **Why does my Swift project throw compiler errors for all the shorthand matchers?**

A few times, we've noticed Source-Kit issues with Swift projects not finding the EarlGrey C-macros
when the project is built with CocoaPods. This seems to be caused by the naming scheme of the EarlGrey
Expand All @@ -404,7 +412,7 @@ manually changing the filename for the CocoaPods EarlGrey folder from `Pods/Earl
in your Project Navigator and also completely remove any Framework Search Paths in your target's Build
Settings pointing to `EarlGrey-1.0.0`. The project should run fine now.

**How do I create a custom action in Swift?**
#### **How do I create a custom action in Swift?**

You need to create a new object of type `GREYActionBlock` and call pass it to `performAction`. For example,
take a look at [checkHiddenBlock](../Tests/FunctionalTests/Sources/FTRSwiftTests.swift#L65) in our Functional
Expand All @@ -426,7 +434,7 @@ EarlGrey().selectElementWithMatcher(grey_accessibilityLabel("label"))

```

**How do I change the directory location for where the screenshots are stored?**
#### **How do I change the directory location for where the screenshots are stored?**

You need to change kGREYConfigKeyScreenshotDirLocation in GREYConfiguration to change the location.

Expand All @@ -436,7 +444,7 @@ You need to change kGREYConfigKeyScreenshotDirLocation in GREYConfiguration to c
forConfigKey:kGREYConfigKeyScreenshotDirLocation];
```

**How do I run tests against a precompiled app?**
#### **How do I run tests against a precompiled app?**

Xcode 8 adds two new commands for building and running tests:

Expand Down Expand Up @@ -478,13 +486,12 @@ xcodebuild \
test-without-building
```

**I get a compiler error `i"Invalid escaped sequence in literal"` when I add the backspace escape character
in a Swift string `"grey_typeText("foob\bar")"` to type "fooar". How do I use backspace to delete text in Swift?**
#### **I get a compiler error `"Invalid escaped sequence in literal"` when I add the backspace escape character in a Swift string `"grey_typeText("foob\bar")"` to type "fooar". How do I use backspace to delete text in Swift?**

For Swift, the backspace escape character is `\u{8}`. You need to add that in your string to be typed for
Swift. For example, To type "fooar", you should use `grey_typeText("foob\u{8}ar")`

**Does EarlGrey support finding react-native elements?**
#### **Does EarlGrey support finding react-native elements?**

Yes. By default [all touchable elements](https://facebook.github.io/react-native/docs/accessibility.html)
are accessible. A button with the `accessibilityLabel` prop set can be found by `grey_accessibilityLabel`.
Expand Down
13 changes: 13 additions & 0 deletions docs/ifaq.md
@@ -0,0 +1,13 @@
# IFAQ - Infrequently Asked Questions

#### **Why does EarlGrey need to modify the test's scheme and add a Copy Files Build Phase?**

EarlGrey synchronizes by keeping track of the app's internal state. It is essential that EarlGrey
therefore be embedded into the app. Since we do not want users to have EarlGrey directly link to
the app under test or create separate test rigs, we perform the embedding ourselves by adding a
Copy Files Build Phase that copies the *EarlGrey.framework* linked to the test target to the app
under test, as specified by the *$TEST_HOST* variable.

Also, EarlGrey needs to be loaded before the app to ensure that we do not miss any states that
should have been tracked, along with giving EarlGrey fine-grained control of the test's execution.
For this purpose, we add a *DYLD_INSERT_LIBRARIES* environment variable in the test's scheme.