0

I am trying to write the tests for the NavBar component (using react-native-testing-library) that has several buttons that are basically just icons (using ui-kitten for react native). So I can't get these buttons by text (as there is none) but other methods didn't work for me either (like adding accesibilityLabel or testID and then getting by the label text / getting by test ID). Any ideas what I am doing wrong?

// NavBar.tsx
import React from 'react';
import {View, StyleSheet} from 'react-native';
import {HomeBtn, SaveBtn} from '../components/buttons';
import UserSignOut from './UserSignOut';

const NavBar = ({
  navigation,
  pressHandlers,
}) => {
  return (
    <View style={styles.navBar}>
      <View>
        <HomeBtn navigation={navigation} />
        <SaveBtn pressHandler={pressHandlers?.saveBtn ?? undefined} />
      </View>
      <UserSignOut />
    </View>
  );
};
export default NavBar;

// HomeBtn.tsx
import React from 'react';
import {Button} from '@ui-kitten/components';
import {HomeIcon} from '../shared/icons';
import styles from './Btn.style';

export const HomeBtn = ({navigation}: any) => {
  return (
    <Button
      accesibilityLabel="home button"
      style={styles.button}
      accessoryLeft={props => HomeIcon(props, styles.icon)}
      onPress={() => navigation.navigate('Home')}
    />
  );
};

// NavBar.test.tsx
import React from 'react';
import {render, screen} from '@testing-library/react-native';
import * as eva from '@eva-design/eva';
import {RootSiblingParent} from 'react-native-root-siblings';
import {EvaIconsPack} from '@ui-kitten/eva-icons';
import {ApplicationProvider, IconRegistry} from '@ui-kitten/components';
import NavBar from '../../containers/NavBar';

describe('NavBar', () => {
  const navBarContainer = (
    <RootSiblingParent>
      <IconRegistry icons={EvaIconsPack} />
      <ApplicationProvider {...eva} theme={eva.light}>
        <NavBar />
      </ApplicationProvider>
    </RootSiblingParent>
  );
  it('should render the buttons', async () => {
    render(navBarContainer);
    // this test fails (nothing is found with this accesibility label)
    await screen.findByLabelText('home button');
  });
});
dnd1993
  • 101
  • 2
  • 11
  • screen.getByRole('button') finds no elements either =/ – dnd1993 Oct 28 '22 at 20:18
  • I never use react but can't you just select the button by attribute? – FUZIION Oct 31 '22 at 13:31
  • Don't know how I'd do it in React Native – dnd1993 Oct 31 '22 at 13:36
  • I see the home button requires a propery named 'navigation' which is not provided in the test suite. In this way the button probably not rendered successfully. So the possible truth is that the button was not rendered and the test suite did work as expected(said that button wasn't render). – Pengson Nov 07 '22 at 09:45

2 Answers2

0

Does await screen.findByA11yLabel('home button') work? It should match the accessibilityLabel prop.

Dan
  • 8,041
  • 8
  • 41
  • 72
0

Query predicate

The recommended solution would be to use:

getByRole('button', { name: "home button" })

As it will require both the button role, as well as check accessibilityLabel with name option.

Alternative, but slightly less expressive way would be to use:

getByLabelText('home button')

This query will only check accessibilityLabel prop, which also should work fine.

Why is query not matching

Since you're asking why the query is not working, that depends on your test setup. It seems that you should be able to use sync getBy* query and do not need to await findBy* query, as the HomeBtn should be rendered without waiting for any async action.

What might prevent that test from working could be incorrect mocking of any of the wrapping components: RootSiblingParent, ApplicationProvider, they might be "consuming" children prop without rendering it. In order to diagnose the issue you can use debug() function from RNTL to inspect the current state of rendered components. You can also run your tests on render(<NavBar />) to verify that.

Maciej Jastrzebski
  • 3,674
  • 3
  • 22
  • 28