testing-library / webdriverio-testing-library

🕷️ Simple and complete WebdriverIO DOM testing utilities that encourage good testing practices.
16 stars 14 forks source link

appium / react-native support? #40

Closed wolverineks closed 1 year ago

wolverineks commented 1 year ago

does this work with appium? any interest in getting it to work?

olivierwilkinson commented 1 year ago

Hi there, thanks for making an issue!

I'm not sure at the moment, but I will look into it soon 😄

olivierwilkinson commented 1 year ago

So it is possible to use this library with Appium but only when testing WebViews in a web context. To enter into a web context I found a nice example in the WebdriverIO appium-boilerplate repo:

Roughly it boils down to the following (note that browser could be replaced with driver):

// setup like normal
setupBrowser(browser);

// set appium context to be WebView context
// the first context is the native context and second is the webview
const contexts = await browser.getContexts()
await browser.setContext(contexts[1])

// you can now query elements in the WebView
const element = await browser.getByText('Text in a WebView in a RN app');

If you are looking to get native elements of your React Native app I don't think this library will work however: It relies on @testing-library/dom to fetch the elements which doesn't work outside of a browser environment.

I am not aware of anything that will fetch native elements through appium with DTL queries, but there is @testing-library/react-native for unit testing components in case that is an appropriate alternative.

jgornick commented 1 year ago

Just trying to better understand something...

It seems like this library could work with Appium, but the way this library queries for elements is done by injecting/executing a function in the browser and using that response to eventually return the element.

Is there a reason why this library doesn't query directly using the webdriverio methods? I'm sure I'm misunderstanding something, but it's not making sense to me why it executes a query in the browser to eventaully use webdriverio's $ with the selector.

Any help would be greatly appreciated! Thank you!

cc @olivierwilkinson

olivierwilkinson commented 1 year ago

Hey @jgornick 👋,

The reason this library doesn't work with appium native element testing is because it's built on top of DOM Testing Library (DTL), the library that React Testing Library is also built upon. If we used $ queries directly we would be rebuilding DTL queries from scratch, potentially introducing inconsistencies in how the queries behave and requiring this library to be updated in step with DTL. By injecting DTL to the browser environment the behaviour of the queries is consistent between user's React Testing Library tests and WebdriverIO e2e tests. That is also the reason DTL is a peer dependency rather than a direct dependency, it allows us to inject the version of DTL installed by RTL.

jgornick commented 1 year ago

Thanks for reaching back out @olivierwilkinson!

I'm curious to know if there are any inconsistencies you might be aware of? Our team is looking to standardize our API usages for querying and interacting with elements using the Testing Library Core API contract. At this point, we might look at creating a testing-library/appium type adapter that would use the webdriverio library as the client to Appium.

Any info would be greatly appreciated!

Thanks!

olivierwilkinson commented 1 year ago

Hi @jgornick

Sorry for the slow reply, I was sick the last week so haven't been as productive as I would like haha

I'm curious to know if there are any inconsistencies you might be aware of?

The inconsistencies I was talking about is between the version of DOM Testing Library installed by React Testing Library and the behaviour of this library if we were to reimplement the DTL queries from scratch. The user would have to match the version of DTL installed with the version of this library.

Adding an appium adapter for querying native elements is an interesting idea! In terms of the inconsistencies between DTL queries and Appium queries for native iOS and Android elements: since DTL is DOM specific there will be some differences, although there may be some way to mitigate the differences. I've not used Appium particularly so I'm not sure how easy that would be.

To take an example, the DTL ByRole queries use the element's ARIA role as the role and the element's accessible name for the name option. The closest I could find that matches that in iOS is accessibility traits and it's accessibility label as the name. If the ByRole queries were to fetch elements based on accessibility traits in iOS the options for the role will differ from the DTL version, and may differ between Android and iOS so you may need to have a custom list of roles that maps to the different platform specific roles / traits. However It's unclear to me if you can query for accessibility traits with Appium, it looks like it lets you query for an iOS accessibility-id but as far as I can remember that needs to be manually defined by the developer which would make it closer to a ByTestId query.

Having said all that even if there are differences / roadblocks it may be that you can create a subset or variant of DTL queries that makes sense for Appium, similar to react-native-testing-library queries.

I hope that is helpful!