This source code demonstrates:
- using a higher-order component (HOC) to wrap an existing component implementation in order to generate default
testID
andaccessibilityLabel
props for automated testing in staging environments only. - that by using that HOC, there should be little adjustment required in order to make use of it.
ℹ [!NOTE]
This source code uses
react-native
&react-native-web
for demonstration & testing purposes.hoist-non-react-statics
is also required for components which have static methods.Additional tooling to make native testing work:
@testing-library/jest-native
@testing-library/react-native
react-test-renderer
We could implement withStagingTestId(WrappedComponent, options)
such that additional props to generate the default testID
and accessibilityLabel
on staging is abstracted from the actual component, thus reducing prop pollution:
TitleTextFunction.tsx
import React, { forwardRef, useImperativeHandle, useState } from 'react';
import { Text, TextProps } from 'react-native';
import { withStagingTestId } from 'utils/withStagingTestId';
export interface TitleTextFunctionProps extends TextProps {
title?: string;
}
export interface TitleTextFunctionHandle {
doSomething: () => void;
forceUpdate: (callback?: () => void) => void;
}
export const TitleTextFunction = forwardRef<TitleTextFunctionHandle, TitleTextFunctionProps>(function IdTextFunction(props, ref) {
const {
title,
...rest
} = props;
const [ _, update ] = useState(0);
useImperativeHandle(ref, (): TitleTextFunctionHandle => ({
doSomething() {
console.log('(imperative) %c<TitleTextFunction />', 'color: #ff5524', 'Did something.');
},
forceUpdate(callback) {
update(_ + 1);
if (!callback) {
return;
}
callback();
}
}));
return (
<Text {...rest}>
{title}
</Text>
);
});
export const TitleTextFunctionTagged = withStagingTestId(TitleTextFunction, {
testComponentRole: 'span',
testNameAttribute: 'id',
});
App.tsx
import React from 'react';
import TitleTextFunctionTagged from './TitleTextFunctionTagged';
export const App = () => {
// In here, details such as `testComponentRole` and `testNameAttribute` are inaccessible, thus keeping the component props clean.
return (
<TitleTextFunctionTagged title="Hi!" />
);
};
- Writing HOCs in TS: https://react-typescript-cheatsheet.netlify.app/docs/hoc/react_hoc_docs
-
Clone this repo to your local.
# https git clone https://github.com/csantarin/with-staging-testid-poc.git # ssh git clone git@github.com:csantarin/with-staging-testid-poc.git
-
Browse to the local copy.
cd with-staging-testid-poc
-
Install all dependencies.
yarn
-
Run the app itself for a live demo.
yarn start
Expect all
TitleText*
elements to have a "span-<title>"testID
andaccessibilityLabel
. -
Run the tests.
yarn test
Expect 0 errors.