Giter VIP home page Giter VIP logo

callstack / react-native-testing-library Goto Github PK

View Code? Open in Web Editor NEW
3.0K 3.0K 261.0 16.85 MB

πŸ¦‰ Simple and complete React Native testing utilities that encourage good testing practices.

Home Page: https://callstack.github.io/react-native-testing-library/

License: MIT License

JavaScript 3.80% TypeScript 95.62% Dockerfile 0.02% CSS 0.50% Shell 0.05%
hacktoberfest jest react react-native testing

react-native-testing-library's Introduction

React Native Testing Library

owl

Simple and complete React Native testing utilities that encourage good testing practices.

Version codecov Build downloads PRs Welcome Chat Sponsored by Callstack Star on GitHub

The problem

You want to write maintainable tests for your React Native components. As a part of this goal, you want your tests to avoid including implementation details of your components and rather focus on making your tests give you the confidence for which they are intended. As part of this, you want your tests to be maintainable in the long run so refactors of your components (changes to implementation but not functionality) don't break your tests and slow you and your team down.

This solution

The React Native Testing Library (RNTL) is a lightweight solution for testing React Native components. It provides light utility functions on top of react-test-renderer, in a way that encourages better testing practices. Its primary guiding principle is:

The more your tests resemble the way your software is used, the more confidence they can give you.

This project is inspired by React Testing Library. Tested to work with Jest, but it should work with other test runners as well.

Installation

Open a Terminal in your project's folder and run:

Using yarn

yarn add --dev @testing-library/react-native

Using npm

npm install --save-dev @testing-library/react-native

This library has a peerDependencies listing for react-test-renderer. Make sure that your react-test-renderer version matches exactly the react version.

Additional Jest matchers

You can use the built-in Jest matchers by adding the following line to your jest-setup.ts file (configured using setupFilesAfterEnv):

import '@testing-library/react-native/extend-expect';

Custom Jest Preset (React Native before 0.71)

We generally advise using the "react-native" preset when testing with this library.

However, if you use React Native version earlier than 0.71 with modern Jest fake timers (default since Jest 27), you'll need to apply this custom Jest preset or otherwise awaiting promises, like using waitFor or findBy*, queries will fail with a timeout.

This is a known issue. It happens because React Native's Jest preset overrides native Promise. Our preset restores it to defaults, which is not a problem in most apps out there.

Here's how you apply a custom preset in your Jest config:

{
  "preset": "@testing-library/react-native"
}

If this doesn't work for you, please fall back to using "legacy" fake timers.

Flow

Note for Flow users – you'll also need to install typings for react-test-renderer:

flow-typed install react-test-renderer

Example

import { render, screen, fireEvent } from '@testing-library/react-native';
import { QuestionsBoard } from '../QuestionsBoard';

// It is recommended to use userEvent with fake timers
// Some events involve duration so your tests may take a long time to run.
jest.useFakeTimers();

test('form submits two answers', async () => {
  const questions = ['q1', 'q2'];
  const onSubmit = jest.fn();

  const user = userEvent.setup();
  render(<QuestionsBoard questions={questions} onSubmit={onSubmit} />);

  const answerInputs = screen.getAllByLabelText('answer input');

  // simulates the user focusing on TextInput and typing text one char at a time
  await user.type(answerInputs[0], 'a1');
  await user.type(answerInputs[1], 'a2');

  // simulates the user pressing on any pressable element
  await user.press(screen.getByRole('button', { name: 'Submit' }));

  expect(onSubmit).toHaveBeenCalledWith({
    1: { q: 'q1', a: 'a1' },
    2: { q: 'q2', a: 'a2' },
  });
});

You can find the source of QuestionsBoard component and this example here.

API / Usage

The public API of @testing-library/react-native is focused around these essential methods:

  • render – deeply renders the given React element and returns helpers to query the output components.
  • fireEvent - invokes named event handler on the element.
  • waitFor - waits for non-deterministic periods of time until the queried element is added or times out.
  • waitForElementToBeRemoved - waits for non-deterministic periods of time until the queried element is removed or times out.
  • within - creates a queries object scoped for a given element.

Migration Guides

Troubleshooting

Community Resources

Check out our list of Community Resources about RNTL.

Made with ❀️ at Callstack

React Native Testing Library is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. Callstack is a group of React and React Native geeks, contact us at [email protected] if you need any help with these or just want to say hi!

Like the project? βš›οΈ Join the team who does amazing stuff for clients and drives React Native Open Source! πŸ”₯


Supported and used by Rally Health.

react-native-testing-library's People

Contributors

antoinethibi avatar augustinlf avatar batdroid avatar charpeni avatar codingitwrong avatar cross19xx avatar danahartweg avatar dcalhoun avatar dependabot-preview[bot] avatar dependabot[bot] avatar esemesek avatar greenkeeper[bot] avatar hduprat avatar jaworek avatar jsnajdr avatar kyawthura-gg avatar mattagn avatar mdjastrzebski avatar nickmccurdy avatar ozzieorca avatar pierrezimmermannbam avatar pplytas avatar renovate[bot] avatar retyui avatar ryanjwessel avatar siepra avatar stevehanson avatar suezzo avatar thymikee avatar vangalilea avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-testing-library's Issues

An in-range update of react-native is breaking the build 🚨

The devDependency react-native was updated from 0.57.5 to 0.57.6.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

react-native is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ ci/circleci: install-dependencies: Your tests failed on CircleCI (Details).

Commits

The new version differs by 19 commits.

  • d5332fb [0.57.6] Bump version numbers
  • ac5aaec iOS: Support inline view truncation (#21456)
  • 356ac5d Remove useless additionnal blur call (#22156)
  • 87c9d92 CxxReact: Silence 'unused lambda capture' warnings in open-source (#22240)
  • ec1bbfd resizeMode applies to Image.defaultSource (#22216)
  • f41383f Fix React Native AsyncMode and DevTools
  • 90cb45f Workaround a wrong fling direction for inverted ScrollViews on Android P (#21117)
  • 695784a Fixed HTTP connection timeout on Android (#22164)
  • de3711e Fix crash when releasing RN views
  • 5ba44f7 Fix regression in StyleSheet.setStyleAttributePreprocessor (#22262)
  • 6e7576b Android: Close websocket properly when remote server initiates close (#22248)
  • 35c1c27 NetInfo: try to solve crash with releasing _firstTimeReachability
  • e360b0b Fix IllegalArgumentException when dismissing ReactModalHostView
  • 6c85356 Improving Modal visible prop check to handle undefined and null (#22072)
  • d0c8cb1 Add iOS 12 textContentType options (#21079)

There are 19 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Tests fail when using a ListHeaderComponent on a FlatList or VirtualizedList

Hey there,

I'm using a FlatList with a ListHeaderComponent in a component and I'm having issues getting render to work without errors. The error is below:

    Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

      at invariant (node_modules/fbjs/lib/invariant.js:42:15)
      at getFiberTagFromObjectType (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1693:9)
      at createFiberFromElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1653:20)
      at reconcileSingleElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4670:23)
      at reconcileChildFibers (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4727:35)
      at reconcileChildrenAtExpirationTime (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5098:28)
      at reconcileChildren (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5089:3)
      at mountIndeterminateComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5524:5)
      at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5903:14)
      at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7949:12)

More detail:

  console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6309
    The above error occurred in one of your React components:
        in Unknown (at VirtualizedList.js:761)
        in View (created by View)
        in View (at VirtualizedList.js:767)
        in VirtualizedCellWrapper (at VirtualizedList.js:764)
        in View (created by View)
        in View (at ScrollViewMock.js:31)
        in RCTScrollView (created by _class)
        in _class (at ScrollViewMock.js:29)
        in ScrollView (at VirtualizedList.js:1062)
        in VirtualizedList (at FlatList.js:663)

Associated code:

https://github.com/facebook/react-native/blob/master/Libraries/Lists/VirtualizedList.js#L753

Versions:

"react": "16.6.3",
"react-native": "0.57.8",

Repro:

https://github.com/wmcbain/RNTestingTestingRepro

Is there a suggested way to mock this in order to get past the error?

More helpers for testing hooks

Ask your Question

I'd like to know how to test context-api with react-native-testing-library.
It is supported int react-testing-library as in #296. Also, [useContext] could be covered which was addressed in #283.

I searched for api doc and I am not seeing any use-case for this one.

Native Base <Content/> type is not rendered

Hi,
I have this component:

import {
	Container,
	Content,
	Text,
} from 'native-base';


<Container style={styles.container}>			
	<Content padder>
		<Text testID={'emptyCasesList'}>Cases list is empty</Text>
	</Content>
</Container>

But the test can't find the 'emptyCasesList' element. when I run debug.deep, I can't see the <Content/> element nor the <Text>.
BUT - when I remove the <Content/> element (leaving just the <Text/>), test passes and I see the <Text/> element.
If the answer is something like "NativeBase is mocking the <Content/> in tests" - could you please elaborate further?

Thanks.

Setup CI

I think we'll go with CircleCI

getByText fails to get text when using alternate ui lib implementation

I'm using wix's react-native-ui-lib with react-native-testing-library. They have extended some core rn elements (eg Text) so that their elements are used instead. Example: https://github.com/wix/react-native-ui-lib/wiki/USAGE

When I use Text element from react-native-ui-lib, the getByText helper fails to find the text. However, when I switch to the RN Text component, the tests pass as I expect.

Not sure what the right way forward is here so thought I would log an issue to discuss.

(Right now I'm just using toJSON and a string regex to assert that the text was found.)

An in-range update of @types/react is breaking the build 🚨

The devDependency @types/react was updated from 16.7.8 to 16.7.9.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@types/react is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • βœ… ci/circleci: install-dependencies: Your tests passed on CircleCI! (Details).
  • ❌ ci/circleci: typescript: Your tests failed on CircleCI (Details).
  • βœ… ci/circleci: lint-and-flow: Your tests passed on CircleCI! (Details).
  • βœ… ci/circleci: tests: Your tests passed on CircleCI! (Details).

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

fireEvent seems to always trigger event (on disabled TouchableOpacity)

I'm trying to figure out why it seems like the fireEvent.press function always seem to trigger a callback even though it shouldn't be registered. My use case is that I'm trying to write a test that makes sure that onPress isn't called if the component is "disabled".

Trying to mimic the behaviour below...

  const MyComponent = _props => (
    <View>
      <TouchableHighlight testID={'touchable'}>
        <Text>{'Foo'}</Text>
      </TouchableHighlight>
    </View>
  )

  const pressedCallback = jest.fn()
  const { getByTestId } = render(<MyComponent onPress={() => pressedCallback('bar')} />)
  fireEvent.press(getByTestId('touchable'))
  expect(pressedCallback).not.toBeCalled() //Expected mock function not to be called but it was called with: ["bar"]

Press doesn't exist on element

If i have the following component setup and then render(<SignUp />); in a test file. Trying to check if the event fires on press does not register.

export class SignUp extends Component {
  handleSignUp = () => ({})

  render() {
    return (
      <View>
        <TouchableOpacity testID="sign-up-button" onPress={this.handleSignUp}>
          <Text>Sign up</Text>
        </TouchableOpacity>
      </View>
    )
  }
}

test('should invoke specified event', () => {
  const handleSignUp = jest.fn();
  const { getByTestId } = render(<SignUp />);
  fireEvent(getByTestId('sign-up-button'), 'press');
  expect(handleSignUp).toHaveBeenCalled();
});

Expected mock function to have been called, but it was not called.

Update README overview comparison to Enzyme

As discussed in this thread:

https://twitter.com/thymikee/status/1050432901945483265

It would be good to both spell out that Enzyme can be set up with deep rendering with mount(), which I plan to update documentation for here:

enzymejs/enzyme#1375

But it would also be good to highlight the benefits of using react-native-testing-library at the same time. As @thymikee mentioned:

Yup, but I don't want to use jsdom as RN is not web. Also Enzyme makes it too easy to write bad tests that assert on implementation details. [...]

I might be able to help with documentation here soon if no one else wants to pick this up, though I might try out the library myself first when I get a chance so I can better speak to it.

Tests won't compile because library is published as ES6

I am trying to run simple test case in TypeScript project but I am getting

> mocha
/myApp/node_modules/react-native-testing-library/src/index.js:2
import render from './render';
^^^^^^
SyntaxError: Unexpected token import

This means that you guys are publishing the project code in ES6 even though node_modules should be released as ES5.

Could you compile the library code to ES5 and republish that :)

Using the library with Styled Components

Hi, thank you for a great testing library!
Is there any additional setup I need to do to make the snapshot testing work smoothly with [styled-components](https://github.com/styled-components/styled-components)?

The generated snapshots are not useful as they're missing the entire CSS.

Snapshot with react-test-renderer:

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Component SubmitButton renders correctly 1`] = `
<View
  accessible={true}
  isTVSelectable={true}
  onResponderGrant={[Function]}
  onResponderMove={[Function]}
  onResponderRelease={[Function]}
  onResponderTerminate={[Function]}
  onResponderTerminationRequest={[Function]}
  onStartShouldSetResponder={[Function]}
  style={
    Object {
      "alignItems": "center",
      "backgroundColor": "#006a35",
      "borderColor": "rgba(0, 0, 0, 0)",
      "borderRadius": 24,
      "borderWidth": 1.5,
      "height": 48,
      "justifyContent": "center",
      "marginBottom": 40,
      "marginHorizontal": 36,
      "opacity": 1,
    }
  }
>
  <Text
    labelColor="#fff"
    style={
      Array [
        Object {
          "color": "#fff",
          "fontFamily": "UniversLTPro-65Bold",
          "fontSize": 12,
          "letterSpacing": 1,
          "lineHeight": 14,
        },
      ]
    }
  >
   
  </Text>
</View>
`;

Snapshot with react-native-testing-library:

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Component SubmitButton renders correctly 1`] = `
Object {
  "output": <ForwardRef
    disabled={false}
    onPress={[Function]}
  >
    <ForwardRef
      labelColor="#fff"
    >
      
    </ForwardRef>
  </ForwardRef>,
}
`;

As you can see, the snapshot spits out a bunch of ForwardRef components and doesn't list the CSS so the snapshot test only shows props passed to components and is not really useful.

Is there any additional setup I need here or do we need to add support for this in react-native-testing-library or styled-components?

Usage with Flow requires react-test-renderer types to be installed

We should either

  1. make it explicit to install the typings using flow-typed or
  2. add node_modules/react-native-testing-library/flow-typed/ to [libs] in .flowconfig
  3. move the ReactTestInstance/ReactTestRendererJSON to our codebase.

I'm leaning towards options 1 & 2 as both make sense in some scenarios.

cc @Esemesek

An in-range update of release-it is breaking the build 🚨

The devDependency release-it was updated from 10.0.8 to 10.0.9.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

release-it is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ ci/circleci: install-dependencies: Your tests failed on CircleCI (Details).

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

FireEvent: press

Hi guys, thanks for cool library!
Have a question for you:
Is there any way I can test onPressIn and onPressOut?

[TypeScript] Typings for get/queryByType and get/queryAllByType breaks with components that has required props

I'm using React Native Elements and testing my components using react-native-testing-library. However, when I try to use the getByType/getAllByType/queryByType/queryAllByType APIs, TypeScript complains about props that are marked by the component as required. One example of a component with a required attribute is the Icon component from React Native Elements.

Consider this example:

// Icon has a required prop `name`
import { Icon, Input } from 'react-native-elements';

// Current signature used by getByType/getAllByType/queryByType/queryAllByType
// getByType: (type: React.ComponentType) => ReactTestInstance;
// getAllByType: (type: React.ComponentType) => Array<ReactTestInstance>
// queryByType: (type: React.ComponentType) => ReactTestInstance | null;
// queryAllByType: (type: React.ComponentType) => Array<ReactTestInstance> | [];

const inst = render(<Input leftIcon={{ name: 'visibility-off' }} />);
// TypeScript fails!
const icon = inst.getByType(Icon);

Error shown

[ts]
Argument of type 'typeof Icon' is not assignable to parameter of type 'ComponentType<{}>'.
  Type 'typeof Icon' is not assignable to type 'ComponentClass<{}, any>'.
    Types of parameters 'props' and 'props' are incompatible.
      Type '{}' is not assignable to type 'Readonly<IconProps>'.
        Property 'name' is missing in type '{}'. [2345]

Add waitForElementToDiminish to helper functions

I started using the library in our react-native project and I keep facing problems to wait until ApolloClient finish loading. Why don't we implement a waitForElementToDiminish so we can always add the loading label/testID and simplify our waits.

[1.6.1] Cannot read property 'toString' of null

Versions

  • Expo v32.0.0
  • jest-expo v32.0.0
  • React v16.5.0
  • NativeBase v2.12.1
  • react-native-testing-library v1.6.1
  • react-test-renderer v16.8.4
  • OS: multiple

Description

As of v1.6.1, I am receiving the following error when trying to test a NativeBase Picker using getByText (the same tests pass in v1.6.0):

Currently the only supported library to search by text is "react-native".

Cannot read property 'toString' of null

This only seems to happen when there are multiple tests.

Reproducible Demo

https://github.com/wKovacs64/rntl-161-repro

Component not rendering in Mocha

I'm attempting to create a "Hello World" component to try out RNTL with Mocha and I'm getting an error attempting to render the component.

Full reproduction repo: https://github.com/CodingItWrong/RNTLTestMocha

Component:

import React from 'react';
import { View, Text } from 'react-native';

export default function Hello() {
  return <View>
    <Text>asdf</Text>
  </View>;
}

Test:

import { expect } from 'chai';
import React from 'react';
import { render, fireEvent } from 'react-native-testing-library';

import Hello from '../Hello';

describe('Hello', () => {
  it('displays the message', () => {
    const { debug, getByText } = render(<Hello />);

    debug();

    expect(getByText('asdf')).not.to.be.null;
  });
});

Error:

  1) Hello
       displays the message:
     Error: Cannot find module 'View'
      at require (internal/module.js:11:18)
      at Object.get View [as View] (node_modules/react-native/Libraries/react-native/react-native-implementation.js:167:12)
      at Hello (Hello.js:5:11)
      at mountIndeterminateComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6889:13)

I have react-test-renderer installed. Does RNTL work with Mocha? Am I missing another dependency? If it's Jest-only I think it would be good to add a note in the README; I can PR that if so.

Add more examples

There's never too little. As a part of it we could show examples with Redux, Apollo, Relay, React Navigation, etc.

An in-range update of conventional-changelog-cli is breaking the build 🚨

The devDependency conventional-changelog-cli was updated from 2.0.5 to 2.0.7.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

conventional-changelog-cli is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ ci/circleci: install-dependencies: Your tests failed on CircleCI (Details).

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Add TypeScript typings

We use Flow internally, because that's what React Native comes with by default. Would be cool to add TS typings though :)

Problem rendering FlatElements

I love to have react-native-testing testing approach in RN, and I'm starting to use it.

I can render almost any RN element, unless FlatList and SectionList. Somehow they are never renderer when I try to access the elements I render with renderItem, additionally when I check with debug() is like if they are omitted from the rendering.

What should I do to get them working?

Is there a better way to get state from a rendered element?

I wrote a helper function to retrieve state after a changeText or press event. Is there a better way to do this?

My components are all wrapped in styled-component tags as well..

const getState = instance => {
  const [ReactTestInstance] = instance.children;
  const {
    stateNode: { state },
  } = ReactTestInstance['_fiber'].memoizedProps.children['_owner'];
  return state;
};

Unexpected behavior for <Text /> element

In React Native it is okay to pass a number as a child for a <Text /> element. So

<Text>2<Text />

is the same as

<Text>{"2"}<Text />

or

<Text>2.toString()<Text />

But since getByText only accepts a string as it's input, you can't find the element if it's being rendered in the first way.

This took me quite some time to debug and I think it's very counter-intuitive. Maybe there is a good solution so getByText finds everything rendered between <Text /> tags?

An in-range update of eslint is breaking the build 🚨

The devDependency eslint was updated from 5.14.0 to 5.14.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

eslint is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • βœ… ci/circleci: install-dependencies: Your tests passed on CircleCI! (Details).
  • βœ… ci/circleci: typescript: Your tests passed on CircleCI! (Details).
  • βœ… ci/circleci: tests: Your tests passed on CircleCI! (Details).
  • ❌ ci/circleci: lint-and-flow: Your tests failed on CircleCI (Details).

Release Notes for v5.14.1
  • 1d6e639 Fix: sort-keys throws Error at SpreadElement (fixes #11402) (#11403) (Krist Wongsuphasawat)
Commits

The new version differs by 3 commits.

  • b2e94d8 5.14.1
  • ce129ed Build: changelog update for 5.14.1
  • 1d6e639 Fix: sort-keys throws Error at SpreadElement (fixes #11402) (#11403)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

How to test children props as a function?

I get an error

Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

when I test a component that looks something like this

<View>{this.props.children({ status: this.state.status })}</View>

How to handle promises?

import React from 'react';
import { render, fireEvent } from 'react-native-testing-library';
import Providers from '../../../containers/Providers';
import SignIn from '../../../components/views/SignIn';

test('basic form validation and jwt retrieval', () => {
  const element = React.createElement(Providers,null, React.createElement(SignIn));

  const { getByText, getByTestId, getByName } = render(element);
  const component = getByName('StyledNativeComponent');
  const username = getByTestId('username');
  const password = getByTestId('password');
  const signIn = getByText(/sign in/i);

  // submit valid user
  fireEvent.changeText(username, 'USER');
  fireEvent.changeText(password, 'PASS');
  fireEvent.press(signIn);
});

How can I access the result from fireEvent.press(signIn)? The result is a promise (JWT) that has token etc in it.

What's the best approach to handle this kind of a test that has promises in it?

Error when getByTestId used with fireEvent.changeText on a TextInput

I have a TextInput component being rendered by a redux-form Field component.

When I call fireEvent.changeText(input, 'hello') on my component it works if I've fetched the input using getByPlaceholder, but fails if I use getByTestId. The error:

No handler function found for event: changeText

Here's code to reproduce the issue:

import React from 'react'
import { Field, reduxForm } from 'redux-form'
import { TextInput } from 'react-native'

const BaseInput = props => (
  <TextInput onChangeText={() => console.log('text changed')} {...props} />
)

const ReduxFormField = props => <Field component={BaseInput} {...props} />

const Input = () => (
  <ReduxFormField name="test" placeholder="placeholder" testID="testID" />
)

export default reduxForm({ form: 'DemoForm' })(Input)

And the tests:

...
import Input from '..'

describe('<Input>', () => {
  it('should be found by placeholder', () => {
    const { getByPlaceholder, unmount } = render(<Input />)
    const input = getByPlaceholder('placeholder')
    expect(input).toBeDefined()
    fireEvent.changeText(input, 'hello')
    unmount()
  })
  it('should be found by testID', () => {
    const { getByTestId, unmount } = render(<Input />)
    const input = getByTestId('testID')
    expect(input).toBeDefined()
    fireEvent.changeText(input, 'hello')
    unmount()
  })
})

I noticed this when I removed the placeholder from an input and needed to fetch it in a different way. I didn't expect any behaviour to be different when getting the same component with different queries.

TypeError: Cannot read property 'default' of undefined

I am not sure if this is a problem of react-native-testing-library or react-native-vector-icons.

Versions

"react": "^16.8.1",
"react-native": "^0.58.4",
"react-native-testing-library": "^1.5.0",
"react-test-renderer": "^16.8.1"

Description

    TypeError: Cannot read property 'default' of undefined

      at new Icon (node_modules/react-native-vector-icons/lib/create-icon-set.js:30:104)
      at constructClassInstance (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:3422:22)
      at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6592:9)
      at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7549:20)
      at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11218:16)
      at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11250:28)
      at renderRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11333:11)
      at performWorkOnRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12221:11)
      at performWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12133:11)
      at performSyncWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12107:7)

Reproducible Demo

The test where the error happens:

MenuItems/test.tsx

describe("Prop: onPress", () => {
    const onPressMock = jest.fn();

    it("calls the passed callback when the menuItems(TouchableOpacity) was pressed", () => {
      const { getByTestId } = render(
        <MenuItems
          {...testProps}
          setModalVisible={onPressMock}
          setView={onPressMock}
        />
      );

      fireEvent.press(getByTestId("123"));
      expect(onPressMock).toHaveBeenCalledTimes(1);
    });
  });

MenuItems/index.tsx

export default class MenuItems extends Component<IProps> {
  public render() {
    return (
      <View style={styles.containerWrapper}>
        {this.props.icons.map(item => (
          <TouchableOpacity
            onPress={() => {
              this.props.setModalVisible();
              this.props.setView(item.id);
            }}
            key={item.id}
            style={styles.container}
          >
            <Icon name={item.icon} size={30} style={styles.icon} />
            <Text style={styles.text}>{item.name}</Text>
          </TouchableOpacity>
        ))}
      </View>
    );
  }
}

getByText doesn't find texts inside ScrollView (possibly others?)

Took this code straight from your examples, but instead of looking for testId, I tried to look for the text:

  const {  getByText } = render(
    <ScrollView testID="scroll-view">
      <Text>XD</Text>
    </ScrollView>
  );

  getByText("XD");

Changing ScrollView to View makes it pass.

Am I doing something wrong?

Implement fireEvent API

See https://github.com/kentcdodds/react-testing-library#fireeventeventnamenode-htmlelement-eventproperties-object.

In RN world we could use it like

fireEvent.press(button);
fireEvent.doublePress(button);
fireEvent.changeText(textInput);
fireEvent.scroll(scrollView);

I'd like this to only have events that can be triggered by the user on core components.
Since any "basic" component like Picker, Checkbox, RadioButton can (and usually is) be implemented in user-land, I don't think there's room for so many events as in DOM world.

Accessing props directly would still be possible, because we probably shouldn't care about underlying native implementation (e.g. for gesture handlers)

An in-range update of react-native is breaking the build 🚨

The devDependency react-native was updated from 0.57.7 to 0.57.8.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

react-native is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • βœ… ci/circleci: install-dependencies: Your tests passed on CircleCI! (Details).
  • βœ… ci/circleci: typescript: Your tests passed on CircleCI! (Details).
  • βœ… ci/circleci: lint-and-flow: Your tests passed on CircleCI! (Details).
  • ❌ ci/circleci: tests: Your tests failed on CircleCI (Details).

Commits

The new version differs by 20 commits.

  • af79164 [0.57.8] Bump version numbers
  • 0301a2e Use relative path for SCRIPTDIR (#22598)
  • 274f5b8 default hitSlop values to 0 (#22281)
  • f7e3def Remove trailing slash from origin header if no port is specified (#22290)
  • ba50151 Extend reason message for RCTFatalException (#22532)
  • 8ba5d4c Use main.jsbundle in iOS template for production build (#22531)
  • 3576819 Fix dispatch of OnLayout event for first render
  • 79011d7 Fixed for supporting mediaPlaybackRequiresUserAction under iOS 10. (#22208)
  • 692fc2e Fix bug in comparison logic of object property (#22348)
  • 30c2fb8 Fix ListEmptyComponent is rendered upside down when using inverted flag. (#21496)
  • 472e978 Duration cannot be less then 10ms (#21858)
  • 26775d5 Avoid using -[UITextView setAttributedString:] while user is typing (#19809)
  • d350f37 Bump ws package to 1.1.5 due to vulnerability issues (#21769)
  • 8d1d47a React sync for revisions 3ff2c7c...6bf5e85
  • 95ef882 Fixes animated gifs incorrectly looping/not stopping on last frame (#21999)

There are 20 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

RFC: Investigate shallow equivalents of render getBy APIs

Currently we use shallow rendering as a way to generate small snapshots, e.g. for snapshot-diff lib.
As much as I'm a fan of deep rendering I think in some cases, e.g. if one wants to test components as units, or speed up some tests that don't require deep rendering, it may make sense to assert on shallow output.
However, due to shallow renderer limitations, one couldn't rely on all lifecycle methods (which may be less relevant once Hooks take over the scene, still an implementation detail though).

In terms of API, shallow would just mimic render, so it should be easy to swap in certain conditions.

Testing eventListener in `componentDidMount`

Testing eventListener in componentDidMount

Hey folks,

I have a react-native component that is listening to Linking url event. How would I fire that Event with react-native-testing-library?

Example:

import React, { PureComponent } from 'react';
import { View, Text, Linking, ActivityIndicator } from 'react-native';
import SafariView from 'react-native-safari-view';

class WebAuthView extends Component<Props, State> {
  componentDidMount() {
        Linking.addEventListener('url', this.handleAuthUrl);
        SafariView.addEventListener('onDismiss', this.handleDismiss);
   }

   componentWillUnmount() {
       Linking.removeEventListener('url', this.handleAuthUrl);
       SafariView.removeEventListener('onDismiss', this.handleDismiss);
   }

   handleAuthUrl = ({url}) => {
     // Implementation goes here
   }

   render() {
     // ....
   }
}

An in-range update of react-native is breaking the build 🚨

The devDependency react-native was updated from 0.57.4 to 0.57.5.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

react-native is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • βœ… ci/circleci: install-dependencies: Your tests passed on CircleCI! (Details).
  • ❌ ci/circleci: lint-and-flow: CircleCI is running your tests (Details).
  • βœ… ci/circleci: typescript: Your tests passed on CircleCI! (Details).
  • ❌ ci/circleci: tests: Your tests failed on CircleCI (Details).

Commits

The new version differs by 31 commits.

  • 44bfffb [0.57.5] Bump version numbers
  • b089087 [LOCAL COMMIT] mute some flow error coming from Metro (could be reversed)
  • 754594b [LOCAL COMMIT] re-enable metro
  • 550cf7d Bump fbjs-scripts to ^1.0.0 (#21880)
  • 277c19c Fix Xcode 10 errors relating to third-party (0.57-stable)
  • 08b14f4 Revert "Fix ReactRootView mount/unmount race condition"
  • 53672ef Enforce lockfile is kept up to date (#21739)
  • 44a3e2f Fix checkout_code: Remove Metro cache check (#21998)
  • 76c99f2 React sync for revisions 4773fdf...3ff2c7c
  • 19c8164 React sync for revisions d836010...4773fdf
  • 68dee8a Increase cache and file size limits
  • ce09d6e Performance improvement for loading cached images on iOS (#20356)
  • 3e8a016 bump buck to 2018.10.29.01. fixes Android CI (#22049)
  • 6d436a4 Remove undefined value on init cli command (#22045)
  • 6524591 Fix ReactRootView mount/unmount race condition

There are 31 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Jest: expect(getByText('content')).not.toBeDefined(); throw exception

I would expect that something like this will be possible.
In my test scenario at first I add text content to the TextInput, then I test if text content exists, then I click on the delete button and I would like to test if input will be clear.

expect(getByText('content')).not.toBeDefined();

but I throw the exception with this No instances found

[Expo] waitForElement: Promise constructor's argument is not a function

Created a fresh Expo app and tried to use waitForElement, but it throws. Works fine in vanilla RN app.

Test:

it('renders', async () => {
  const { getByText } = render(<App />);

  await waitForElement(() => getByText(/working/));
});

Result:

TypeError: Promise constructor's argument is not a function

     7 |     const { getByText } = render(<App />);
     8 | 
  >  9 |     await waitForElement(() => getByText(/working/));
    10 |   });
    11 | });
    12 | 
    
    at new Promise (node_modules/promise/lib/core.js:59:11)
    at resolve (node_modules/react-native-testing-library/src/waitForElement.js:8:26)
    at Object.getByText (App.test.js:9:32)
    at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
    at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
    at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
    at invoke (node_modules/regenerator-runtime/runtime.js:152:20)
    at node_modules/regenerator-runtime/runtime.js:195:11
    at tryCallTwo (node_modules/promise/lib/core.js:45:5)

I'm assuming it has something to do with Expo's jest-expo preset, but I haven't narrowed it down yet.

Reproduction repo if anyone wants to mess with it: https://github.com/wKovacs64/rntl-expo-test

Do you not need afterEach(cleanup)

I noticed that this library doesn't expose a cleanup function like react-testing-library does. Is this intentional? Could you clear this issue up in the readme?

jest-dom extend-expect

Hi,
love this library!
just wondering if your planning to get the jest-dom/extend-expect functions converted to Native?
I have a bunch of tests where I introspect text results ...
I can do a getByText but in some cases I need to get all text for a parent Text component that contains a bunch of child Text components.
Thanks for your help,
/Stephen.

Use `@babel/preset-env` for ES6 transpilation

Currently we use Metro preset to transpile our files, which does a lot of transforms, that are not really necessary for running in Node 6+ (lowest actively supported version) environment.

It should be totally fine if we transformed our sources with @babel/preset-env with Node 6 target.

Setup test infra

Currently the project is tested internally on a project I'm involved.

Technically we could test the library with pure React, without setting up React Native (by mocking some core components), which would massively simplify git checkout and maintenance, so I'm currently drawn into this direction. We can also think about using Expo as a testing example.

Looking forward for simplest, yet comprehensive way of doing this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.