Having issues selecting the back button when setting a testID in setDefaultOptions.
Have also tried setting the testID in the component itself and the element still isn't being found.
Noticed there was meant to be a fix in 6.9.0
Give backButton a testID like this:
Navigation.setDefaultOptions({
layout: {
orientation: ['portrait'],
backgroundColor: Colors.background,
componentBackgroundColor: Colors.background
},
modalPresentationStyle: 'pageSheet',
bottomTabs: {
titleDisplayMode: 'alwaysShow',
backgroundColor: '#1C2432',
hideShadow: false,
elevation: 15
},
bottomTab: {
textColor: '#4b747c',
selectedTextColor: Colors.accentBright,
fontSize: 8,
fontFamily: 'Nunito-Regular'
},
topBar: {
title: {
fontFamily: 'Nunito-Bold',
fontSize: 18,
color: '#fff'
},
backButton: {
icon: require('../assets/images/arrowBack.png'),
color: '#fff',
showTitle: false,
testID: 'navigation-back'
},
buttonColor: {
color: '#fff'
},
background: {
color: Colors.background
}
},
statusBar: {
backgroundColor: Colors.background2,
style: 'light'
}
})
Then trying to select the testID: 'navigation-back' in my test like:
Using Appium 1.18.2 with webdriverio 6.5.2
it('should be able to navigate back', async () => {
const back = await $('~navigation-back')
await back.waitForDisplayed({ timeout: 5000 })
await back.click()
const screen = await $('intro-choice-screen')
const visible = await screen.waitForDisplayed({ timeout: 5000 })
expect(visible).toEqual(true)
})
Results in ~navigation-back not being found.
Applying a testID to bottomTab works as expected, so it doesn't seem to be an issue with Appium.
Hi @calumgould can you see if not using a custom icon successfully registers the back button test id?
Hi @calumgould can you see if not using a custom icon successfully registers the back button test id?
Hi @jinshin1013, have just tried this and unfortunately it still has the same outcome.
Hi @calumgould, I've just tried your config and it seems like it works with the default button: https://www.dropbox.com/s/1rbzxo4w1dwzezs/Screenshot%202020-10-25%20at%2022.57.53.png?dl=0. Accessibility identifier is there.
Also, this is a custom back button which works: https://www.dropbox.com/s/tg9s7z0o8qwdhet/Screenshot%202020-10-25%20at%2023.07.21.png?dl=0
I've also ran a test with detox with your test case and everything works fine. Can you upgrade to 7.1.0 or even 7.2.0 ?
Hi @mateioprea, I appreciate you taking the time to look into this further. I have upgraded to 7.2.0 and booted up the Appium inspector to get a better look at what is going on.
I've now identified a consistent behaviour for how testIDs are being assigned to the back button. The testID passed to setDefaultOptions above has no effect, and the testID that is being read by Appium can be one of two things:
Options passed to previous screen with topBar title 'Wallet':
{
topBar: {
title: {
text: 'Wallet'
},
visible: false,
height: 0
},
bottomTab: {
text: 'WALLET',
icon: require('../../../assets/images/walletsUnactive.png'),
selectedIcon: require('../../../assets/images/wallets.png'),
selectedIconColor: (Platform.OS === 'android') ? Colors.accent : undefined,
testID: 'navigation-wallet'
}
}
Now pressing on an item in this screen, brings up the backButton in the next component. This is what the Appium inspector shows for this: (notice the correct assignment of the bottom navigation)

Options passed to previous screen without a title prop:
{
topBar: {
visible: false,
noBorder: true,
elevation: 0
},
bottomTab: {
text: 'SETTINGS',
icon: require('../../../assets/images/settingsUnactive.png'),
selectedIcon: require('../../../assets/images/settings.png'),
selectedIconColor: (Platform.OS === 'android') ? Colors.accent : undefined,
testID: 'navigation-settings'
}
}
Following the same steps as above, the Appium inspector now shows:

As you can see here, the testID provided to backButton isn't being applied at any stage, even passing a testID directly to backButton options in the component has no effect.
The testIDs for the bottom nav are applied correctly and recognised by the inspector.
Running the previous test, replacing the id selector with whatever testID was automatically assigned results in passing tests:
it('should be able to navigate back', async () => {
const back = await $('~Wallet')
await back.waitForDisplayed({ timeout: 5000 })
await back.click()
const screen = await $('wallet-screen')
const visible = await screen.waitForDisplayed({ timeout: 5000 })
expect(visible).toEqual(true)
})
However, this obviously isn't an ideal solution and one would expect the testID to be consistent across all screens.
@calumgould can you fork this repo and provide a failing playground e2e test? Either with Detox or Appium. This way we can investigate further and fix the actual issue, if any.
@mateioprea forked the repo and here you can see from the Appium inspector, the exact same issue to what I am having.
https://github.com/calumgould/react-native-navigation
Didn't have time to go through the whole Appium setup, but all that's needed to view what accessibility ids are being provided is to use the appium desktop inspector, make a build and provide config like this:
{
"platformName": "iOS",
"deviceName": "iPhone 12 Pro",
"orientation": "PORTRAIT",
"automationName": "XCUITest",
"app": "PATH_TO_APP",
"autoAcceptAlerts": true
}
The only code added to the playground was the backButton options passed to your existing Navigation.setDefaultOptions in Options.ts. I also added the custom back button image from my app.
const setDefaultOptions = () =>
Navigation.setDefaultOptions({
window: {
backgroundColor: Colors.primary,
},
layout: {
componentBackgroundColor: Colors.background,
orientation: ['portrait'],
},
topBar: {
backButton: {
icon: require('../../img/arrowBack.png'),
color: 'black',
showTitle: false,
testID: 'navigation-back'
}
},
bottomTabs: {
titleDisplayMode: 'alwaysShow',
},
bottomTab: {
selectedIconColor: Colors.primary,
selectedTextColor: Colors.primary,
},
animations: {
...(useSlideAnimation ? slideAnimations : useCustomAnimations ? customAnimations : {}),
},
modalPresentationStyle: OptionsModalPresentationStyle.fullScreen,
});
The accessibility id is not set by Navigation.setDefaultOptions and is instead just whatever the topBar -> title prop was of the previous screen.
(Previous screen title was Stack -> press button labelled push -> accessibility id of backButton is Stack)

Another screenshot to show the issue repeating
(Now on screen with title Pushed Screen -> press button labelled push -> again accessibility id is title of previous screen instead of the testID assigned earlier)

Hope this helps you investigate further.
An e2e test in the playground app would have been preferable.
@guyca Here's some tests showing the issue https://github.com/calumgould/react-native-navigation
Make a build with yarn appium-build
Test with yarn appium-test
I used the Stack Position: X in the footer to verify these tests
describe('failing back button', () => {
beforeAll(async () => {
await browser.pause(2000);
});
it('try to navigate back', async () => {
const stackButton = await $('~STACK_BUTTON');
await stackButton.click();
const pushButton = await $('~PUSH_BUTTON');
// Press push button twice
await pushButton.click();
await browser.pause(1000);
// Now on 'Pushed Screen'
await pushButton.click();
await browser.pause(1000);
// Now on 'Pushed 2'
// Stack position is 2
const backButton = await $('~navigation-back');
await backButton.click();
// Should now be back on 'Pushed Screen'
const pushFooter = await $('~footer');
await pushFooter.waitForDisplayed({ timeout: 5000 });
// Stack position should be 1
const footerText = await pushFooter.getText();
expect(footerText).toEqual('Stack Position: 1');
});
});

Now by changing the backButton selector to the topBar -> title of the previous screen, in this case Pushed Screen the test passes.
describe('passing back button', () => {
beforeAll(async () => {
await browser.pause(2000);
});
it('try to navigate back', async () => {
const stackButton = await $('~STACK_BUTTON');
await stackButton.click();
const pushButton = await $('~PUSH_BUTTON');
// Press push button twice
await pushButton.click();
await browser.pause(1000);
// Now on 'Pushed Screen'
await pushButton.click();
await browser.pause(1000);
// Now on 'Pushed 2'
// Stack position is 2
const backButton = await $('~Pushed Screen');
await backButton.click();
// Should now be back on 'Pushed Screen'
const pushFooter = await $('~footer');
await pushFooter.waitForDisplayed({ timeout: 5000 });
// Stack position should be 1
const footerText = await pushFooter.getText();
expect(footerText).toEqual('Stack Position: 1');
});
});

@calumgould We don't officially support Appium. If you believe this is a bug with RNN, please submit a failing Detox e2e test.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.
The issue has been closed for inactivity.