I am running detox on my React-Native project and can only test the splash screen. The splash screen goes to a Login Screen but the detox code will not allow me to test this element.
Test Code:
describe('Splash', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should have splash screen', async () => {
await expect(element(by.id('splash'))).toBeVisible();
await expect(element(by.id('login'))).toBeVisible();
});
});
Error given:
● Splash › should have splash screen
Failed: [Error: Error: Cannot find UI Element.
Exception with Assertion: {
"Assertion Criteria": "assertWithMatcher:matcherForSufficientlyVisible(>=0.750000)",
"Element Matcher": "((!(kindOfClass('RCTScrollView')) && (respondsToSelector(accessibilityIdentifier) && accessibilityID('login'))) || (((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && parentThatMatches(kindOfClass('RCTScrollView'))) && ((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && parentThatMatches((respondsToSelector(accessibilityIdentifier) && accessibilityID('login'))))))",
"Recovery Suggestion": "Check if the element exists in the UI hierarchy printed below. If it exists, adjust the matcher so that it accurately matches element."
}
Error Trace: [
{
"Description": "Interaction cannot continue because the desired element was not found.",
"Error Domain": "com.google.earlgrey.ElementInteractionErrorDomain",
"Error Code": "0",
"File Name": "GREYElementInteraction.m",
"Function Name": "-[GREYElementInteraction matchedElementsWithTimeout:error:]",
"Line": "124"
}
]
The first test passes when it runs not testing the login component
It takes time items to render on the screen. You can use the waitFor
property that detox provides.
In most cases, tests should be automatically synchronized with the app. When synchronization doesn't work, you have a fail-safe by using waitFor.
You can read more about using waitFor
in the documentation.
NOTE: Every waitFor call must set a timeout using withTimeout(). Calling waitFor without setting a timeout will do nothing.
NOTE: waitFor will not throw when reaching timeout, instead it will just continue to the next line. To make sure your tests work as you expect them to add expect() at the following line.
So based on the example in the documentation you should update your test to be
it('should show login screen', async () => {
await expect(element(by.id('splash'))).toBeVisible()
await waitFor(element(by.id('login'))).toBeVisible().withTimeout(2000);
await expect(element(by.id('login'))).toBeVisible()
});