Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Espresso UI Testing for React Native?

I'm trying to make some UI Testing with Espresso on my React Native Android application to use Screengrab by Fastlane.

I have followed this tutorial to integrate React Native in an existing app to be able to write a test. But when I started writing my UI Test I was unable to find what to write and how to target a component and perform a click on it for example.

I found this post where someone give an example on how to write Espresso Test for React Native but it doesn't work for me ... None of my component have resource-id set so I don't know how to perform some action on my application.

If someone could help me to write a UI Test with Espresso on a React Native app or give me another solution to take automated screenshot of my Android application that'll be awesome.

If you have any question let me know.

like image 826
G.Sabathier Avatar asked May 11 '16 15:05

G.Sabathier


3 Answers

Espresso

Currently there is no way to set resource-id with react-native, so, to make complex actions you need to write some code (like wait for elements), other things seems work quite good via android studio 'record espresso test' button.

  1. use prop accessibilityLabel as id for elements (eg. "elementId")
  2. use onView(allOf(withContentDescription("elementId"), isDisplayed())) to get element
  3. peform actions on that element (like element.perform(click()))

Here you can find full test https://gist.github.com/cybergrind/0a2ad855352a5cd47cb5fb6a486c5eaa

Appium

If you just want to perform actions and capture screenshots, you can do this with appium:

  1. use prop accessibilityLabel as id for elements
  2. in web driver use waitForElementByAccessibilityId
  3. capture screenshots with saveScreenshot('out.png') -> this will create 'out.png' file in directory where you've run tests

In appium you finally will have something like (js example):

driver.waitForElementByAccessibilityId('searchInputAcc', 5000)
      .type('bold\n')
      .sleep(5000)
      .saveScreenshot('out.png')

iOS vs Android accessibilityLabels

It seems that for Android you're free to use accessibiltyLabel on any element (like Text, View and so on), but iOS won't set accessibility on all elements like Adnroid.

If you set label on Text it won't be equal your label

<Text accessibilityLabel="my_text">content</Text>

will give you label equal content on iOS, so basically you can just set accessible attribute on your text nodes for this platform

<Text accessible>content</Text>

Same thing for View - iOS will ignore your labels.

So far, not much elements on iOS will work with your custom accessibility labels.

Below is a list of elements that you can use to test application for crossplatform react-native tests

You can use:

  • TouchableHighlight - will work same on iOS and Android, you can just set accessibilityLabel
  • Text - accessibilityLabel should be same as inner test + you have to set accessible attribute

Won't work (for both platforms altogether):

  • View

P.S. we haven't tested all possible elements yet, so add your results for other elements or wait for our results

Debugging

You can get source of root element, print and read it as xml for debugging purposes (for webdriver.io: http://webdriver.io/api/property/getSource.html)

like image 187
cybergrind Avatar answered Oct 16 '22 19:10

cybergrind


I have a PR against react-native to add proper support for resource-id. Check it out and up-vote please: https://github.com/facebook/react-native/pull/9942

Once that's merged in testID will add resource-id so long as the Id is defined in res/values/ids.xml.

like image 30
jsdevel Avatar answered Oct 16 '22 17:10

jsdevel


Currently if you set testID in your react layer that will get translated into a tag in android.

Then with Espresso you can use the provided ViewMatcher withTagValue link

Then all you have to do to find a view is

onView(withTagValue(is((Object) tagValue))).perform(click());
like image 30
A. Maly Avatar answered Oct 16 '22 18:10

A. Maly