Giter Site home page Giter Site logo

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

View Code? Open in Web Editor NEW
516.0 516.0 44.0 493 KB

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

Home Page: https://native-testing-library.com

License: MIT License

JavaScript 100.00%
javascript jest react-native reactjs testing

native-testing-library's Introduction

@testing-library/angular

Octopus with the Angular logo

Simple and complete Angular testing utilities that encourage good testing practices.


Read The Docs | Edit the docs



Build Status version downloads MIT License

All Contributors PRs Welcome Code of Conduct Discord

Watch on GitHub Star on GitHub Tweet

Open in GitHub Codespaces

Table of Contents

The problem

You want to write maintainable tests for your Angular 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 testbase 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 @testing-library/angular is a very lightweight solution for testing Angular components. It provides light utility functions on top of Angular and @testing-library/dom, 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.

Example

counter.component.ts

@Component({
  selector: 'app-counter',
  template: `
    <button (click)="decrement()">-</button>
    <span>Current Count: {{ counter }}</span>
    <button (click)="increment()">+</button>
  `,
})
export class CounterComponent {
  @Input() counter = 0;

  increment() {
    this.counter += 1;
  }

  decrement() {
    this.counter -= 1;
  }
}

counter.component.spec.ts

import { render, screen, fireEvent } from '@testing-library/angular';
import { CounterComponent } from './counter.component';

describe('Counter', () => {
  test('should render counter', async () => {
    await render(CounterComponent, { componentProperties: { counter: 5 } });

    expect(screen.getByText('Current Count: 5'));
  });

  test('should increment the counter on click', async () => {
    await render(CounterComponent, { componentProperties: { counter: 5 } });

    const incrementButton = screen.getByRole('button', { name: '+' });
    fireEvent.click(incrementButton);

    expect(screen.getByText('Current Count: 6'));
  });
});

See more examples

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's devDependencies. Starting from ATL version 17, you also need to install @testing-library/dom:

npm install --save-dev @testing-library/angular @testing-library/dom

Or, you can use the ng add command. This sets up your project to use Angular Testing Library, which also includes the installation of @testing-library/dom.

ng add @testing-library/angular

You may also be interested in installing jest-dom so you can use the custom jest matchers.

Docs

Version compatibility

Angular Angular Testing Library
18.x 17.x, 16.x, 15.x, 14.x, 13.x
17.x 17.x, 16.x, 15.x, 14.x, 13.x
16.x 14.x, 13.x
>= 15.1 14.x, 13.x
< 15.1 12.x, 11.x
14.x 12.x, 11.x

Guiding Principles

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

We try to only expose methods and utilities that encourage you to write tests that closely resemble how your Angular components are used.

Utilities are included in this project based on the following guiding principles:

  1. If it relates to rendering components, it deals with DOM nodes rather than component instances, nor should it encourage dealing with component instances.
  2. It should be generally useful for testing individual Angular components or full Angular applications.
  3. Utility implementations and APIs should be simple and flexible.

At the end of the day, what we want is for this library to be pretty light-weight, simple, and understandable.

Contributors

Thanks goes to these people (emoji key):

Tim Deschryver
Tim Deschryver

πŸ’» πŸ“– πŸš‡ ⚠️
MichaΓ«l De Boey
MichaΓ«l De Boey

πŸ“–
Ignacio Le Fluk
Ignacio Le Fluk

πŸ’» ⚠️
TamΓ‘s SzabΓ³
TamΓ‘s SzabΓ³

πŸ’»
Gregor Woiwode
Gregor Woiwode

πŸ’»
Toni Villena
Toni Villena

πŸ› πŸ’» πŸ“– ⚠️
ShPelles
ShPelles

πŸ“–
Miluoshi
Miluoshi

πŸ’» ⚠️
Nick McCurdy
Nick McCurdy

πŸ“–
Srinivasan Sekar
Srinivasan Sekar

πŸ“–
Bitcollage
Bitcollage

πŸ“–
Emil Sundin
Emil Sundin

πŸ’»
Ombrax
Ombrax

πŸ’»
Rafael Santana
Rafael Santana

πŸ’» ⚠️ πŸ›
Benjamin Blackwood
Benjamin Blackwood

πŸ“– ⚠️
Gustavo Porto
Gustavo Porto

πŸ“–
Bo Vandersteene
Bo Vandersteene

πŸ’»
Janek
Janek

πŸ’» ⚠️
Gleb Irovich
Gleb Irovich

πŸ’» ⚠️
Arjen
Arjen

πŸ’» 🚧
Suguru Inatomi
Suguru Inatomi

πŸ’» πŸ€”
Amit Miran
Amit Miran

πŸš‡
Jan-Willem Willebrands
Jan-Willem Willebrands

πŸ’»
Sandro
Sandro

πŸ’» πŸ›
Michael Westphal
Michael Westphal

πŸ’» ⚠️
Lukas
Lukas

πŸ’»
Matan Borenkraout
Matan Borenkraout

🚧
mleimer
mleimer

πŸ“– ⚠️
MeIr
MeIr

πŸ› ⚠️
John Dengis
John Dengis

πŸ’» ⚠️
Rokas BrazdΕΎionis
Rokas BrazdΕΎionis

πŸ’»
Mateus Duraes
Mateus Duraes

πŸ’»
Josh Joseph
Josh Joseph

πŸ’» ⚠️
Torsten Knauf
Torsten Knauf

🚧
antischematic
antischematic

πŸ› πŸ€”
Florian Pabst
Florian Pabst

πŸ’»
Mark Goho
Mark Goho

🚧 πŸ“–
Jan-Willem Baart
Jan-Willem Baart

πŸ’» ⚠️

This project follows the all-contributors specification. Contributions of any kind welcome!

Docs

Read The Docs | Edit the docs

FAQ

I am using Reactive Forms and the jest-dom matcher toHaveFormValues always returns an empty object or there are missing fields. Why?

Only form elements with a name attribute will have their values passed to toHaveFormsValues.

Issues

Looking to contribute? Look for the Good First Issue label.

πŸ› Bugs

Please file an issue for bugs, missing documentation, or unexpected behavior.

See Bugs

πŸ’‘ Feature Requests

Please file an issue to suggest new features. Vote on feature requests by adding a πŸ‘. This helps maintainers prioritize what to work on.

See Feature Requests

❓ Questions

For questions related to using the library, please visit a support community instead of filing an issue on GitHub.

Getting started with GitHub Codespaces

To get started, create a codespace for this repository by clicking this πŸ‘‡

Open in GitHub Codespaces

A codespace will open in a web-based version of Visual Studio Code. The dev container is fully configured with software needed for this project.

Note: Dev containers is an open spec which is supported by GitHub Codespaces and other tools.

LICENSE

MIT

native-testing-library's People

Contributors

aegan avatar aiham avatar ajsmth avatar allcontributors[bot] avatar bcarroll22 avatar daveols avatar elyalvarado avatar imgbot[bot] avatar jeffreyffs avatar lewie9021 avatar maadhattah avatar manakuro avatar mateusz1913 avatar mcgloneleviroot avatar nickmccurdy avatar sibelius avatar smakosh avatar sophieau avatar sz-piotr avatar thymikee avatar wolverineks 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

native-testing-library's Issues

What about react-native-testing-library?

Hi!

I did some research and found this library made by Callstack.

They really have a similar API and solves the same problem, right? There're plans to have a single testing-library for react native in the future?

And I'm sorry if this isn't the right place for this kind of question, I just wanna hear some opinions about this scenario :)

Provided mocking implementation of ScrollView is incomplete

  • react-native or expo: react-native
  • native-testing-library version: 4.0.2
  • jest-preset: @testing-library/react-native
  • react-native version: 0.59.8
  • node version: 8.16.0

Relevant code or config:

// Oversimplifying a bit for this sample
const LongScrollView = () => {
  const scrollViewRef = React.createRef();
  const scrollToEnd = () => scrollViewRef.current.scrollToEnd()
  return (
    <ScrollView ref={scrollViewRef}>
       <Button onPress={scrollToEnd}><Text>Go to End</Text></Button>
       <Text>Very large piece of content</Text>
       <Text>EndOfScroll</Text>
    </ScrollView>
  )
}

test('goes to end on pressing the button', () => {
    const { getByText } = render(<LongScrollView />)
    const button = getByText('Go to End')
    fireEvent.press(button)
    expect(getByText('EndOfScroll')).not.toThrowError()
})

What you did:

Try to test user behavior where a ScrollView goes to the end after certain interactions

What happened:

While trying to test a component using the provided jest-preset I'm getting the following error. If I use the react-native preset (or if I remove ScrollView from the coreComponents config for native-testing-library) the error doesn't happen.

TypeError: Cannot read property 'Commands' of undefined

    at Component.scrollResponderScrollToEnd (/home/dev/X/node_modules/react-native/Libraries/Components/ScrollResponder.js:465:7)
    at Object.scrollResponderScrollToEnd [as scrollToEnd] (/home/dev/X/node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js:274:30)
    at Object.scrollToEnd [as onDateChange] (/home/dev/X/App/containers/Profile.tsx:209:26)

Problem description:

The provided ScrollView mock is using the same mockComponent behaviour that all other native components, however the ScrollView is a little different in that the mock provided by react-native itself in their jest-preset refers to its own mock implementation: '../Libraries/Components/ScrollView/mocks/ScrollViewMock',

Suggested solution:

I don't have a suggested solution, except a temporary work-around: comment out ScrollView from the coreComponents configuration until a definitive solution is found.

Warning: An update to Example inside a test was not wrapped in act(...).

  • react-native or expo: react-native
  • native-testing-library version: 3.1.1
  • jest-preset: native-testing-library
  • react-native version: 0.59.2
  • node version: 10.13.0

Relevant code or config:

import * as React from "react";
import { Button, Text, TextInput, View } from "react-native";
import { fireEvent, render, wait } from "native-testing-library";

function Example() {
  const [name, setUser] = React.useState("");
  const [show, setShow] = React.useState(false);

  return (
    <View>
      <TextInput value={name} onChangeText={setUser} testID="input" />
      <Button
        title="Print Username"
        onPress={() => {
          // let"s pretend this is making a server request, so it"s async
          // (you"d want to mock this imaginary request in your unit tests)...
          setTimeout(() => {
            setShow(!show);
          }, Math.floor(Math.random() * 200));
        }}
      />
      {show && <Text testID="printed-username">{name}</Text>}
    </View>
  );
}

test("examples of some things", async () => {
  const { getByTestId, getByText, queryByTestId } = render(<Example />);
  const famousWomanInHistory = "Ada Lovelace";

  const input = getByTestId("input");
  fireEvent.changeText(input, famousWomanInHistory);

  const button = getByText("Print Username");
  fireEvent.press(button);

  await wait(() => expect(queryByTestId("printed-username")).toBeTruthy());

  expect(getByTestId("printed-username").props.children).toBe(famousWomanInHistory);
  expect(baseElement).toMatchSnapshot();
});

What you did:

Ran the example found within the documentation that demonstrates an async state update: https://www.native-testing-library.com/docs/example.

What happened:

I get a console.error message suggesting there is a problem with the tests:

console.error node_modules/react-native/Libraries/YellowBox/YellowBox.js:132
    Warning: An update to Example inside a test was not wrapped in act(...).

    When testing, code that causes React state updates should be wrapped into act(...):

    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */

    This ensures that you're testing the behavior the user would see in the browser. Learn more at https://fb.me/react-wrap-tests-with-act
        in Example
        in View (created by View)
        in View (at AppContainer.js:98)
        in View (created by View)
        in View (at AppContainer.js:115)
        in AppContainer (at src/index.js:24)

Reproduction:

See code snippet above.

Problem description:

Whenever I run the tests, I'm flooded with these console.error messages whenever I test components that make state changes after async logic such as network requests.

Suggested solution:

I feel this is a known issue, but I've not yet seen a ticket open for it on this project. I figured it would be helpful for others to reference and track the progress.

I've attempted to Google around to see if I can find a solution, but appears to be something fundamentally wrong with the underlying library that the *-testing-library family uses, react-test-renderer. This was highlighted in a react-testing-library issue and appears to have a fix on the way in React 16.9 once at least this umbrella issue is closed.

Below is my current workaround:

In my Jest config file, I have a reference to a custom setup script:

module.exports = {
  // ...
  preset: 'native-testing-library',
  setupFiles: [
    ...jestPreset.setupFiles,
    "<rootDir>/setupJest.js"
  ],
  // ...
};

In the custom setup script (setupJest.js), I have the following:

// Auto-mock YellowBox component.
jest.mock("YellowBox");

const mockConsoleMethod = (realConsoleMethod) => {
  const ignoredMessages = [
    "test was not wrapped in act(...)"
  ];

  return (message, ...args) => {
    const containsIgnoredMessage = ignoredMessages.some((ignoredMessage) => message.includes(ignoredMessage));

    if (!containsIgnoredMessage) {
      realConsoleMethod(message, ...args);
    }
  };
};

// Suppress console errors and warnings to avoid polluting output in tests.
console.warn = jest.fn(mockConsoleMethod(console.warn));
console.error = jest.fn(mockConsoleMethod(console.error));

Note: mockConsoleMethod is used to only suppress logs that contain "test was not wrapped in act(...)".

RN 0.61.0-rc.0 Cannot find module 'ReactNative' from 'mock-modules.js'

  • react-native or expo: react-native
  • native-testing-library version: 4.0.8
  • jest-preset: react-native
  • react-native version: 0.61.0-rc.0
  • node version: 10.15.3

Relevant code or config:

react-native info

System:
    OS: macOS 10.14.6
    CPU: (4) x64 Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz
    Memory: 22.55 MB / 16.00 GB
    Shell: 5.7.1 - /usr/local/bin/zsh
  Binaries:
    Node: 10.15.3 - /var/folders/fc/dg0hjk2n5lg7g8brjxyfhx6h0000gn/T/yarn--1567055701100-0.41617634669325376/node
    Yarn: 1.17.3 - /var/folders/fc/dg0hjk2n5lg7g8brjxyfhx6h0000gn/T/yarn--1567055701100-0.41617634669325376/yarn
    npm: 6.4.1 - ~/.asdf/installs/nodejs/10.15.3/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 12.4, macOS 10.14, tvOS 12.4, watchOS 5.3
    Android SDK:
      API Levels: 23, 24, 27, 28
      Build Tools: 27.0.3, 28.0.3
      System Images: android-23 | Google APIs Intel x86 Atom, android-24 | Google APIs Intel x86 Atom
  IDEs:
    Android Studio: 3.4 AI-183.6156.11.34.5692245
    Xcode: 10.3/10G8 - /usr/bin/xcodebuild
  npmPackages:
    @react-native-community/cli: ^2.9.0 => 2.9.0
    react: 16.9.0 => 16.9.0
    react-native: 0.61.0-rc.0 => 0.61.0-rc.0

What you did:

Upgraded from RN 0.60.5 to RN 0.61.0-rc.0

What happened:

Error when running jest

  ● Test suite failed to run

    Cannot find module 'ReactNative' from 'mock-modules.js'

    However, Jest was able to find:
    	'./mock-modules.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['ts', 'tsx', 'js', 'jsx', 'json'].

Reproduction:

N/A

Problem description:

Tests were all passing in RN 0.60.5 (with the pre React 16.9.0 console errors)

Haste module system was changed

Suggested solution:

Can you help us fix this issue by submitting a pull request?

Picker component does not get value updated

I'm having trouble changing the value of a native Picker component to test a component I've built on my own that uses the react-native Picker.
Observing that calling fireEvent.valueChange did trigger the onValueChange callback, I was intrigued why wasn't my hook useState wasn't been updated if it worked in the ios and android simulator.

I decided to test the example given in the React Native docs, but it also did not work.

source of the example: https://facebook.github.io/react-native/docs/picker

My component code:

export class PickerComponent extends React.Component {
  state = {
    language: '',
  };
  render() {
    return (
      <Picker
        accessibilityLabel="picker-ios"
        selectedValue={this.state.language}
        style={{ height: 50, width: 100 }}
        onValueChange={(itemValue, itemIndex) =>
          this.setState({ language: itemValue })
        }>
        <Picker.Item label="Java" value="java" />
        <Picker.Item label="JavaScript" value="js" />
      </Picker>
    );
  }
}

Jest example

it('should  render and change the selectedItem' , () => {
    const { getByLabelText } = render(<PickerComponent />);
    const Picker = getByLabelText('picker-ios');
    fireEvent.valueChange(Picker, items[0]);
    console.log(Picker);    

Testing it I observed that somehow the onValueChange callback is triggered but no update is done after calling it.

TypeError: Cannot read property 'includes' of undefined for getBy*, queryBy*

  • This bug is directly from the example given in the doc. none of the getBy*, queryBy* are working.
  • react-native: 0.59.4
  • native-testing-library version: 3.1.2
  • jest-preset:
  • react-native version: 0.59.4
  • node version: 8.11.4

Relevant code or config:

import React from 'react';
import { Button, Text, TextInput, View } from 'react-native';
import { act, fireEvent, render, wait } from 'native-testing-library';

function Example() {
  const [name, setUser] = React.useState('');
  const [show, setShow] = React.useState(false);

  return (
    <View>
      <TextInput value={name} onChangeText={setUser} testID="input" />
      <Button
        title="Print Username"
        onPress={() => {
          // let's pretend this is making a server request, so it's async
          // (you'd want to mock this imaginary request in your unit tests)...
          setTimeout(() => {
            setShow(!show);
          }, Math.floor(Math.random() * 200));
        }}
      />
      {show && <Text testID="printed-username">{name}</Text>}
    </View>
  );
}

test('examples of some things', async () => {
  const { getByTestId, getByText, queryByTestId } = render(<Example />);
  const famousWomanInHistory = 'Ada Lovelace';

  const input = getByTestId('input');
  fireEvent.changeText(input, famousWomanInHistory);

  const button = getByText('Print Username');
  fireEvent.press(button);

  await wait(() => expect(queryByTestId('printed-username')).toBeTruthy());

  expect(getByTestId('printed-username')).toHaveTextContent(famousWomanInHistory);
  expect(rootInstance).toMatchSnapshot();
});

What you did:

Ran the sample test app

What happened:

● examples of some things

    TypeError: Cannot read property 'includes' of undefined

      32 |   fireEvent.changeText(input, famousWomanInHistory);
      33 | 
    > 34 |   const button = getByText('Print Username');
         |                    ^
      35 |   fireEvent.press(button);
      36 | 
      37 |   await wait(() => expect(queryByTestId('printed-username')).toBeTruthy());

      at validComponentFilter (node_modules/native-testing-library/dist/lib/query-helpers.js:37:55)
      at node_modules/native-testing-library/dist/lib/queries/text.js:32:60
      at overrideCb (node_modules/native-testing-library/dist/lib/query-helpers.js:75:22)
      at _findAll (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13002:11)
      at Proxy.findAll (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12931:16)
      at Proxy.<anonymous> (node_modules/native-testing-library/dist/lib/query-helpers.js:78:24)
      at queryAllByText (node_modules/native-testing-library/dist/lib/queries/text.js:31:31)
      at node_modules/native-testing-library/dist/lib/query-helpers.js:172:24
      at node_modules/native-testing-library/dist/lib/query-helpers.js:156:24
      at _callee$ (__tests__/index.ios.js:34:20)
      at tryCatch (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:40)
      at Generator.invoke [as _invoke] (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:271:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:97:21)
      at tryCatch (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:40)
      at invoke (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:135:20)
      at node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:170:11
      at tryCallTwo (node_modules/promise/lib/core.js:45:5)
      at doResolve (node_modules/promise/lib/core.js:200:13)
      at new Promise (node_modules/promise/lib/core.js:66:3)
      at callInvokeWithMethodAndArg (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:169:16)
      at AsyncIterator.enqueue (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:192:7)
      at AsyncIterator.prototype.(anonymous function) [as next] (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:97:21)
      at Object.<anonymous>.exports.async (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:216:10)
      at Object._callee (__tests__/index.ios.js:27:169)

Reproduction:

Run the sample example provided in the doc

Queries passed as options to render not being returned

The documentation mentions that queries can be passed as an option to render to specify which queries to bind, or add custom bound queries

  • react-native or expo: react-native
  • native-testing-library version: 2.0.1
  • react-native version: 0.59.5
  • node version: 8.15.1
  • npm (or yarn) version: yarn 1.15.2

Relevant code or config:

The following test should pass

test('returns the queries passed as options bound to the container', () => {
  const _getQueryPassedAsOption = { bind: jest.fn(() => _getQueryPassedAsOption) }
  const queries = { getQueryPassedAsOption: _getQueryPassedAsOption };

  const { container, getQueryPassedAsOption } = render(<View />, { queries });

  expect(queries.getQueryPassedAsOption.bind).toHaveBeenCalledWith(null,container);
  expect(getQueryPassedAsOption).toEqual(_getQueryPassedAsOption);
});

Reproduction:

Add the test to any project with native-testing-library and it'll fail.

Problem description:

It should work as documented.

Suggested solution:

I'll submit a PR with the fix. Just give me a few minutes

*ByDisplayValue doesn't work for Switch

  • react-native or expo: 'react-native'
  • native-testing-library version: 4.0.9
  • jest-preset: @testing-library/react-native
  • react-native version: 60.5
  • node version: 10.15.1

Relevant code or config:

const Switch = ({ value, onValueChange }: {value: string; onValueChange(): void) => {
 return (<Switch value={value} onValueChange={onValueChange} />);
}

it('should work as expected', () => {
  const callback = jest.fn();
  const { getByDisplayValue } = render(<Switch value={false} onValueChanged={callback} />)

 expect(getByDisplayValue('false')).toBeTruthy()
})

What you did:

Tried to write a test for a component with a Switch in it.

What happened:

getByDisplayValue is expecting a Matcher(string | RegExp), so you can't pass in false, 'false' as a string also doesn't seem to work.

I also tried to ignore the Typescript error and pass false (and 'off') to getByDisplayValue with no luck.

Component output from debug

<Text
  style={
    Object {
      "paddingBottom": 4,
      "paddingEnd": 12,
      "paddingTop": 4,
      }
    }
>
  testLabel
</Text>
<Switch
  testID="id"
  value={false}
/>

Problem description:

The documentation indicates that ByDisplayValue is what we should be using for switches.

Am I missing something?

Can you help us fix this issue by submitting a pull request?

Possibly, if I can get some direction as to what the intended behaviour is supposed to be!

Not compatible with react-native-svg which use data-testid

  • react-native or expo: react-native
  • native-testing-library version: 4.1.0
  • jest-preset: '@testing-library/react-native'
  • react-native version: 0.61.1
  • node version: 10.15.2

Relevant code or config:

  <Svg
    testID={"ChatIcon"} >

    expect(getByTestId('ChatIcon')).toBeTruthy()

see full test case below:

What you did:

Trying to test the SVG present in my react native application.

What happened:

*ByTestId cannot find the component in question. I determined the cause to be that react-native-svg output data-testid instead of testID. (See debug output below)

Reproduction:

Minimal test case:

import { cleanup, render } from '@testing-library/react-native'
import React from 'react'
import { View } from 'react-native'
import Svg, { G } from 'react-native-svg'

export const ChatIcon: React.FunctionComponent = ({
}) => (
  <Svg
    testID={"ChatIcon"}
    width={'24'}
    height={ '24'}
    viewBox="0 0 24 24"
    >
    <G id="Icon-/-chat" fill="none" fillRule="evenodd" />
  </Svg>
)


const TestComponent: React.FunctionComponent = () => (
  <View testID="testView">
    <ChatIcon/>
  </View>
)

describe('<TestComponent />', () => {

  afterEach(cleanup)
  it('find icon by test id', () => {
    const { getByTestId } = render(<TestComponent/>)

    expect(getByTestId('ChatIcon')).toBeTruthy()
  })
}
Error: Unable to find an element with the testID of: ChatIcon

<View
  pointerEvents="box-none"
  style={
    Object {
      "flex": 1,
    }
  }
>
  <View
    collapsable={true}
    pointerEvents="box-none"
    style={
      Object {
        "flex": 1,
      }
    }
  >
    <View
      testID="testView"
    >
      <svg
        data-testid="ChatIcon"
        height="24"
        viewBox="0 0 24 24"
        width="24"
      />
    </View>
  </View>
</View>

Problem description:

It doesn't allow testing the presence of the component.

Suggested solution:

For now I have bypassed the problem by setting my own Queries. eg :

export const queryByOldTestId = queryHelpers.queryByProp.bind(null, 'data-testid')
describe('<TestComponent />', () => {
  afterEach(cleanup)
  it('find icon by test id passing, () => {
    const r = render(<TestComponent/>, { queries: { 'queryByOldTestId': queryByOldTestId } })
    expect(r.queryByOldTestId('ChatIcon')).toBeTruthy()
  })
})

But it's not really practical or easy to find. I suggest either having react-native-svg output the correct component and/or allowing ByTestId to search for both properties (which would be nice to have in any case while waiting for react-native-svg to have the correct behaviour)

Can you help us fix this issue by submitting a pull request?

Maybe?

Impossible to get FlatList element

Even though from some other parts of the code (events) it looks like is possible to get and interact with a FlatList component, it is not possible to select it with any of the queries as it is rendered as a RCTScrollView and is not whitelisted in the defaultFilter

  • react-native or expo: react-native
  • native-testing-library version: 2.0.0
  • react-native version: 0.59.5
  • node version:8.15.1
  • npm (or yarn) version: yarn 1.15.2

Relevant code or config:

  const MessageList = () => <FlatList testID='testFlatList' />
  test('can get FlatList', () => {
    const { queryByTestId } = render(<MessageList />)
    expect(queryByTestId('testFlatList')).not.toBeEmpty();
  })

What you did:

Tried to get a FlatList in some tests

What happened:

Got the following error:


Error: Unable to find an element with the testID of: internalFlatList

<RCTScrollView
  ListEmptyComponent={null}
  ListFooterComponent={null}
  contentContainerStyle={
    Object {
      "flexGrow": 1,
      "paddingHorizontal": 10,
    }
  }
  data={
    Array [
      Object {
        "callID": "1",
        "content": "This is the first message",
        "onAction": [Function],
        "subtitle": "From x to y",
        "title": "Giver1",
      },
      Object {
        "callID": "2",
        "content": "This is the second message",
        "onAction": [Function],
        "subtitle": "From x to y",
        "title": "Giver2",
      },
    ]
  }
  disableVirtualization={false}
  getItem={[Function]}
  getItemCount={[Function]}
  horizontal={false}
  initialNumToRender={10}
  keyExtractor={[Function]}
  maxToRenderPerBatch={10}
  numColumns={1}
  onContentSizeChange={[Function]}
  onEndReached={[Function]}
  onEndReachedThreshold={0.1}
  onLayout={[Function]}
  onMomentumScrollEnd={[Function]}
  onRefresh={[Function]}
  onScroll={[Function]}
  onScrollBeginDrag={[Function]}
  onScrollEndDrag={[Function]}
  refreshControl={
    <RefreshControlMock
      onRefresh={[Function]}
      refreshing={false}
    />
  }
  refreshing={false}
  removeClippedSubviews={false}
  renderItem={[Function]}
  scrollEventThrottle={50}
  stickyHeaderIndices={Array []}
  testID="internalFlatList"
  updateCellsBatchingPeriod={50}
  viewabilityConfigCallbackPairs={Array []}
  windowSize={21}
/>

    at getElementError (/Users/elyalvarado/Workspace/Happy/HappyRN/node_modules/native-testing-library/dist/query-helpers.js:1:947)
    at /Users/elyalvarado/Workspace/Happy/HappyRN/node_modules/native-testing-library/dist/query-helpers.js:1:3902
    at /Users/elyalvarado/Workspace/Happy/HappyRN/node_modules/native-testing-library/dist/query-helpers.js:1:3437
    at Object.getByTestId (/Users/elyalvarado/Workspace/Happy/HappyRN/App/components/__tests__/MessageList.test.tsx:135:22)
    at Object.asyncJestTest (/Users/elyalvarado/Workspace/Happy/HappyRN/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:102:37)
    at resolve (/Users/elyalvarado/Workspace/Happy/HappyRN/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
    at new Promise (<anonymous>)
    at mapper (/Users/elyalvarado/Workspace/Happy/HappyRN/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
    at promise.then (/Users/elyalvarado/Workspace/Happy/HappyRN/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
    at <anonymous>

Problem description:

This is a native component, and the user can interact with it by scrolling to the end or pulling to refresh

Suggested solution:

I really don't know if this is within the guiding principles, but I think that the user can interact with the FlatList directly because it has specific behaviour that makes it different to other scrollviews in react-native, specifically the onEndReached and onRefresh events.

Support DatePickerIOS

  • react-native or expo: react-native
  • native-testing-library version: ^4.0.7
  • jest-preset: @testing-library/react-native
  • react-native version: v0.60.4
  • node version: v12.7.0

What you did:

I tried to write a test against a <DatePickerIOS />.

What happened:

An unexpected error occurred:

this._picker.setNativeProps is not a function

Reproduction:

import React from "react";
import { DatePickerIOS } from "react-native";
import { render, fireEvent, NativeTestEvent } from "@testing-library/react-native";

const Scenario = () => {
  const [date, onDateChange] = React.useState(new Date());

  return (
    <DatePickerIOS
      testID="date"
      date={date}
      onDateChange={onDateChange}
    />
  );
}

it('should not error', () => {
  const { getByTestId } = render(<Scenario />);

  const datePicker = getByTestId("date");
  const event = new NativeTestEvent("dateChange", new Date());

  expect(() => fireEvent(datePicker, event)).not.toThrowError();
});

it('should not error when providing `createNodeMock`', () => {
  const createNodeMock = jest.fn(element => ({
    setNativeProps: jest.fn()
  }));

  const { getByTestId } = render(<Scenario />, {
    options: { createNodeMock }
  });

  expect(createNodeMock).toHaveBeenCalled();
});

Problem description:

DatePickerIOS calls setNativeProps here:
https://github.com/facebook/react-native/blob/9bc77fadb6b4d51690c93744c02afe40eb6e63fc/Libraries/Components/DatePicker/DatePickerIOS.ios.js#L126

I tried to pass createNodeMock in through the options. I was hoping that by providing a mock forsetNativeProps, that it would work.

createNodeMock was never actually used by the react-test-renderer, though, so my idea didn't work 😦.

Suggested solution:

Maybe add a new mock for DatePickerIOS? πŸ€·β€β™‚

Can you help us fix this issue by submitting a pull request?

Probably!

Cannot find module 'ReactNative' from 'mock-modules.js' with jest-expo

Relevant code or config:

// jest.config.js
const expoPreset = require('jest-expo/jest-preset');
const jestPreset = require('@testing-library/react-native/jest-preset');

module.exports = Object.assign(expoPreset, jestPreset, {
  preset: '@testing-library/react-native',
  transform: {
    '^.+\\.js$': 'babel-jest',
    '^.+\\.tsx?$': 'ts-jest',
  },
  testMatch: [
    '**/__tests__/**/*.ts?(x)',
    '**/?(*.)+(spec|test).ts?(x)',
  ],
  moduleFileExtensions: [
    'js',
    'ts',
    'tsx',
  ],
  globals: {
    'ts-jest': {
      tsConfig: {
        jsx: 'react',
      },
      diagnostics: false,
    },
  },
  modulePathIgnorePatterns: [
    '<rootDir>/build/',
    '<rootDir>/node_modules/',
    '<rootDir>/.history/',
  ],
  setupFiles: [...expoPreset.setupFiles, ...jestPreset.setupFiles, '<rootDir>/test/jestSetup.ts'], // jestSetup.ts is an empty script.
});

What you did:

I followed the installation guide and figured out that the v^33.0.2 jest-expo doesn't contain jest-preset.json as the guide indicates, but instead jest-preset.js. Anyway I imported it as const expoPreset = require('jest-expo/jest-preset'); as in the above snippet.

What happened:

then I tried to test a script, I get this:

$ node node_modules/jest/bin/jest.js src/components/screen/__tests__/Setting.test.tsx
 FAIL  src/components/screen/__tests__/Setting.test.tsx
  ● Test suite failed to run

    Cannot find module 'ReactNative' from 'mock-modules.js'

    However, Jest was able to find:
        './mock-modules.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'ts', 'tsx'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:230:17)
      at Object.<anonymous> (node_modules/@testing-library/react-native/dist/preset/mock-modules.js:18:6)

Reproduction:

https://github.com/marsinearth/native-testing-library-issue-repro

Problem description:

I think something between jest-expo and native-testing-library has been compromised by changed structure of jest-expo package.

Suggested solution:

the error log is very limited, nor I know how to access more log. perdΓ³name.

Can you help us fix this issue by submitting a pull request?

I wish...

Can't query for or fire events on mocked components

Relevant code or config:

Component:

export const ComponentUnderTest = () => (
  <View>
    <ButtonWrapper testID="my-button" onPress={buttonHandler}>
      <Text testID="main-content">Main Content</Text>
    </ButtonWrapper>
  </View>
);

Test:

jest.mock('./ButtonWrapper', () => ({ ButtonWrapper: 'ButtonWrapper' }));

it('should press button', () => {
  const { getByTestId } = render(<ComponentUnderTest />);
  // Throws error: Unable to find an element with the testID of: my-button
  fireEvent.press(getByTestId('my-button'));
  expect(buttonHandler).toHaveBeenCalled();
});

What you did:

Tried to use getByTestId to find the mocked component.

What happened:

Test output:
Screen Shot 2019-05-15 at 3 07 46 PM

Reproduction:

https://github.com/OzzieOrca/repro-native-testing-library-mock-wrapper

Problem description:

Our repo is filled with wrappers around native components and complicated child components. Being able to mock these makes the snapshot output much cleaner and prevents us from having to mock everything needed to render a child component. react-native-testing-library works fine for finding and firing events on these mocked components. native-testing-library doesn't seem to be able to query for these components.

Suggested solution:

  1. Fix the rendered output in the error message. In blue, it says the rendered output is <View /> (hopefully that's what it's meant to be) which doesn't match the snapshot or the output of debug(). I spent a while trying to figure out why my component wasn't rendering anything more than just the root element before realizing it actually was. This error is misleading. If you have a typo in the test id, it won't show you the rendered output with the correct ID and could lead you down a wild goose chase before finding the real issue.
  2. Support querying on mocked components. I believe this would also address #12. Feel free to suggest other testing patterns but we've got a large repo of enzyme shallow tests that I'm trying to migrate to something that supports context and hooks and just looking for an easy path forward.

Thanks for your help with this! Just trying to figure out the best way to test modern React Native components and your library seems promising :)

fireEvent.press() does not work for TouchableNativeFeedback

  • react-native
  • native-testing-library: version 4.0.7
  • jest-preset: @testing-library/react-native
  • react-native version: 0.60.4
  • node version: v10.16.0

I have two buttons. The only difference between them is which Touchable Feedback I use. The one with TouchableNativeFeedback is not testable, the one with TouchableHighlight is. I'm pretty sure this is an issue with native-testing-library.

Relevant code or config:

Here is the exact code I ran:

export const TestableButton = ({ handlePress }) => (
  <TouchableHighlight onPress={handlePress}>
    <Text>FIND ME</Text>
  </TouchableHighlight>
);

export const UntestableButton = ({ handlePress }) => (
  <TouchableNativeFeedback onPress={handlePress}>
    <Text>FIND ME</Text>
  </TouchableNativeFeedback>
);

My test looks like this. It passes for TestableButton, fails for UntestableButton

test('calls handlePress', async () => {
  const mockHandlePress = jest.fn();
  const { getByText } = render(
    <TestableButton handlePress={mockHandlePress} />
  );
  const button = getByText('FIND ME');
  fireEvent.press(button);
  expect(onPress).toHaveBeenCalled();
});

This is currently preventing me from adopting this library because we use TouchableNativeFeedback everywhere, and it makes testing my components impossible if I can't simulate presses. Happy to open a PR if you can point me in the right direction!

Thanks!

improve debug omitProps option

Describe the feature you'd like:

related to this one #70

but I'd like to go deep

We are using Relay in our app, and each fragment has a __fragmentOwner data that could be very large

we want to remove this __fragmentOwner and even more inside props when pretty printing with debug() calls

examples:

sections={
                        Array [
                          Object {
                            "data": Array [
                              Object {
                                "node": Object {
                                  "__fragmentOwner": Object {
                                    "identifier": "query MyestQuery(
....

this is very big (more than 100 lines in terminal)

}>

Suggested implementation:

We can have something like this a sanitizeObject/value that run on value of props - similar to this one https://github.com/entria/entria-fullstack/blob/master/packages/server/test/helper.js#L131

it is a recursive solution

Describe alternatives you've considered:

another solution would be to omit the whole prop all together

Teachability, Documentation, Adoption, Migration Strategy:

validRole and validTraits restricted

I'm wondering why there are only a few options that can be selected via queryByRole as defined in role.js:

const validRoles = [
  'adjustable',
  'button',
  'header',
  'image',
  'imagebutton',
  'keyboardKey',
  'link',
  'none',
  'search',
  'summary',
  'text',
];

const validTraits = [
  'adjustable',
  'allowsDirectInteraction',
  'button',
  'disabled',
  'frequentUpdates',
  'header',
  'image',
  'key',
  'link',
  'none',
  'pageTurn',
  'plays',
  'search',
  'selected',
  'startsMedia',
  'summary',
  'text',
];

Looks like there's a whole bunch of other roles that are defined by React Native: https://facebook.github.io/react-native/docs/accessibility#accessibilityrole-ios-android

I'm wondering if this was a design decision, and if so how we could override / configure this

"getByText" doesn't work

  • react-native or expo: react-native
  • native-testing-library version: 4.0.12
  • jest-preset: 'react-native'
  • react-native version: 0.60.5
  • node version: 8.15.1

Relevant code or config:

it('not work', () => {
    const { getByText } = render(<Text>About β„Ή</Text>)
    getByText(/about/i)
})

What you did:

I just use example from docs

What happened:

  ● ErrorMessage β€Ί not work

    TypeError: Cannot read property 'includes' of undefined

      24 |   it('not work', () => {
      25 |     const { getByText } = render(<Text>About β„Ή</Text>)
    > 26 |     getByText(/about/i)
         |     ^
      27 |   })
      28 | })
      29 | 

      at validComponentFilter (node_modules/@testing-library/react-native/dist/lib/query-helpers.js:37:43)
      at node_modules/@testing-library/react-native/dist/lib/queries/text.js:32:47
      at overrideCb (node_modules/@testing-library/react-native/dist/lib/query-helpers.js:75:22)
      at _findAll (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13002:7)
      at Proxy.findAll (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12931:12)
      at Proxy.<anonymous> (node_modules/@testing-library/react-native/dist/lib/query-helpers.js:78:24)
      at queryAllByText (node_modules/@testing-library/react-native/dist/lib/queries/text.js:31:31)
      at node_modules/@testing-library/react-native/dist/lib/query-helpers.js:172:24
      at node_modules/@testing-library/react-native/dist/lib/query-helpers.js:156:24
      at Object.it (app/auth/__tests__/ErrorMessage.test.tsx:26:5)

Reproduction:

Just use example from docs

Problem description:

When I tried use example from docs I had got this error.

TS error after update TS to version 3.7

  • native-testing-library version: 5.0.0
  • typescript version: 3.7.2

What you did:

Upgrade ts to version 3.7.2

What happened:

I faced with error:

node_modules/@testing-library/react-native/typings/query-helpers.d.ts:1:10 - error TS2440: Import declaration conflicts with local declaration of 'ReactTestInstance'.

1 import { ReactTestInstance } from 'react-test-renderer';
           ~~~~~~~~~~~~~~~~~


Found 1 error.

It is related to change in TS 3.7:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#local-and-imported-type-declarations-now-conflict

Problem description:

In ts 3.7 local and imported declarations now conflict, so we need to extend and rename types with the same name.

Suggested solution:

I suggest to rename and extend interfaces in file query-helpers.d.ts
Actually, I found this PR: #79
could you merge it?

Can you help us fix this issue by submitting a pull request?

Yes, but PR is exist #79.

Calling `render` in `act` produces "Can't access .root on unmounted test renderer" error

  • react-native or expo: react-native
  • native-testing-library version: ^5.0.2
  • jest-preset: @testing-library/react-native
  • react-native version: 0.59.5
  • node version: v10.16.1

Relevant code or config:

import React from "react";

import {
  NativeTestInstance,

  act,
  render
} from "@testing-library/react-native";

test(
  "rendering in act works",
  async () : Promise<void> =>
  {
    let baseElement : NativeTestInstance;

    act(
      () : void =>
      {
        baseElement = render(
          <div></div>
        ).baseElement;
      }
    );

    // TypeScript thinks this is being used before assigned, but the above call to act guarantees it will be assigned
    // @ts-ignore
    expect(baseElement).toMatchSnapshot();
  }
);

What you did:

I ran the above test with jest.

What happened:

I get this in the console:

yarn run v1.19.1
$ jest
 FAIL  __tests__/integration-tests/login/index.test.tsx
  βœ• rendering in act works (193ms)

  ● rendering in act works

    Can't access .root on unmounted test renderer

       99 |       () : void =>
      100 |       {
    > 101 |         baseElement = render(
          |                       ^
      102 |           <div></div>
      103 |         ).baseElement;
      104 |       }

      at Object.get [as root] (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12960:17)
      at root (node_modules/@testing-library/react-native/dist/index.js:96:54)
      at __tests__/integration-tests/login/index.test.tsx:101:23
      at fn (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12334:12)
      at batchedUpdates (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12988:18)
      at _callee$ (__tests__/integration-tests/login/index.test.tsx:98:5)
      at call (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:40)
      at Generator.tryCatch [as _invoke] (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:271:22)
      at Generator._invoke [as next] (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:97:21)
      at call (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:40)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        2.948s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Reproduction:

Copy the test above to a test file (either a .tsx or strip the TypeScript-specific bits out). Then, run the test normally with jest.

Extra potentially-related environment bits:

    "@babel/core": "^7.4.4",
    "@babel/runtime": "^7.4.4",
    "@testing-library/react-native": "^5.0.2",
    "@types/jest": "^24.0.11",
    "@types/react": "^16.8.14",
    "@types/react-native": "^0.57.50",
    "@types/react-test-renderer": "^16.8.1",
    "babel-jest": "^24.7.1",
    "jest": "^24.7.1",
    "metro-react-native-babel-preset": "^0.53.1",
    "react-test-renderer": "16.8.3",
    "typescript": "^3.4.5"

Problem description:

It is not possible to test React components that use state changes without using act, and it is not possible to render inside of act, or so it seems. Because of this, I cannot run the integration tests I am trying to write.

Suggested solution:

Honestly, I am not exactly sure where this issue comes from. I did some Googling, but issues showing this error message are very sparse, and I actually get more results for the source code with the error message in it versus problems with the error itself.

Admittedly, due to the lack of information on Google, I cannot 100% say this is an issue with this library directly; only that the symptoms occur from using it.

Can you help us fix this issue by submitting a pull request?

If I knew what the problem was and understood enough to come up with a solution (assuming this is an issue with this library), I would happily submit a PR. This is holding me up at my job, so the faster the resolution the better.

`getByText` type might be wrong

Relevant code or config:

getByText(DISPLAY_STRINGS.page01.body, {
  // @ts-ignore
  normalizer: (string: string) => string.trim()
});

What you did:

Tried to add options to getByText

What happened:

Argument of type '{ normalizer: (string: string) => string; }' is not assignable to parameter of type 'WaitForElementOptions'.
Object literal may only specify known properties, and 'normalizer' does not exist in type 'WaitForElementOptions'.ts(2345)

Reproduction:

demo

Problem description:

This behavior doesn't match documentation

Suggested solution:

Update type, essentially,

- WaitForElementOptions
+ SelectorMatcherOptions

Can you help us fix this issue by submitting a pull request?

I am able to submit a PR with the change

Rename testID to be consistent to react-testing-library

Renaming of testID

In react-testing-library the testID property is named data-testid. For consistency reasons, in my opinion the property should be renamed to data-testid. Are there any reasons why it could not be renamed?

Suggested Solution

Old:
<Text testID="printed-username">{name}</Text>

New:
<Text data-testid="printed-username">{name}</Text>

est suite failed to run => babel-plugin-jest-hoist: The second argument of `jest.mock` must be an inline function.

πŸ› Bug Report

Environment

  Expo CLI 3.4.0 environment info:
    System:
      OS: macOS 10.15
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 10.16.3 - ~/.nvm/versions/node/v10.16.3/bin/node
      Yarn: 1.19.1 - ~/.nvm/versions/node/v10.16.3/bin/yarn
      npm: 6.9.0 - ~/.nvm/versions/node/v10.16.3/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    IDEs:
      Android Studio: 3.1 AI-173.4720617
      Xcode: 11.0/11A420a - /usr/bin/xcodebuild
    npmPackages:
      @testing-library/react-native: ^4.0.7 => 4.0.7
      expo: ^35.0.0 => 35.0.0
      react: 16.8.3 => 16.8.3
      react-native: https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz => 0.59.8
      react-navigation: ^3.11.1 => 3.11.1
    npmGlobalPackages:
      expo-cli: 3.4.0

app's target: Standalone

// jestconfig.js

const expoPreset = require('jest-expo/jest-preset');
const jestPreset = require('@testing-library/react-native/jest-preset');

module.exports = Object.assign({}, expoPreset, jestPreset, {
  setupFiles: [...expoPreset.setupFiles, ...jestPreset.setupFiles, './jestSetup.js'],
  transformIgnorePatterns: [
    'node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|sentry-expo|native-base)',
  ],
});
// jestSetup.js

import mocks from 'react-native-jest-mocks';

mocks.initAll();

// eslint-disable-next-line no-underscore-dangle
global.__DEV__ = false;

Steps to Reproduce

I'm trying to run my tests using yarn test

"test": "jest -i --colors --config jestconfig.js",

Expected Behavior

My test run normally

Actual Behavior

I get this error:

Screen Shot 2019-10-24 at 14 39 48

Test config not initialized in non-<rootdir> monorepo packages anymore

  • react-native
  • native-testing-library version: 3.0.0
  • jest-preset: native-testing-library
  • react-native version: 0.59.3
  • node version: 12.2.0

Relevant code or config:

...example tests from docs

What you did:

Ran a test in a shared package in a monorepo that worked before upgrading to 3.0.0

roots: ['<rootDir>', '../shared'],

What happened:

after upgrading from 2.x to 3.x all tests in the shared package that use getByText return the following error:

"TypeError: Cannot read property 'includes' of undefined"

when calling (in query-helpers.js):

function validComponentFilter(node, key) {
  return key ? (0, _config.getConfig)(key).includes(node.type) : typeof node.type === 'string';
}

the issue is that the config key for textComponents is nowhere to be found.

Problem description:

Tests in a shared folder in a monorepo previously ran fine. I would like to keep them where they are :)

Suggested solution:

I haven't fully grokked yet, but it seems the config is called twice when another root is added, but the second time the call to configure() doesn't happen at all. My next step is to see if the react-native preset does anything similar that I can borrow to ensure all roots get the same treatment :D :D

selector? option is not typed properly

Looks like this option is implemented with the namespace 'filter' rather than selector, and the typescript definition flags this.

e.g in query-helpers.js:

Relevant code or config:

function queryAllByProp(
  prop,
  container,
  match,
  { filter = n => n, exact = true, collapseWhitespace, trim, normalizer } = {},
) { ... }

What you did:

I tried using the selector option for one of my custom queries

What happened:

Reproduction:

Example:

test.only('selector? bug', () => {
  const { baseElement, debug } = ntlRender(
    <Text accessibilityLabel="Hi" accessibilityStates={['disabled']}>
      Hi
    </Text>
  );

  // always finds because selector is not recognized as a filter
  const alwaysFinds = getByLabelText(baseElement, 'Hi', {
    selector: ({ props }) => props.acessibilityStates.includes('selected'),
  });

  debug(alwaysFinds);

  const willFind = getByLabelText(baseElement, 'Hi', {
    // @ts-ignore
    filter: ({ props }) => props.accessibilityStates.includes('disabled'),
  });

  debug(willFind);

  // throws as expected:
  const willNotFind = getByLabelText(baseElement, 'Hi', {
    // @ts-ignore
    filter: ({ props }) => props.accessibilityStates.includes('selected'),
  });

  debug(willNotFind);
});

Problem description:

I think this is just a naming issue between filter and selector

Suggested solution:

Either update the implementation to change the named parameter to be selector or update the typings / docs to reflect that the name should be filter

Can you help us fix this issue by submitting a pull request?

Yup

Typescript Error: findAllByTestId

Relevant code or config:

	it('should render the typed password', () => {
		let login = render(<Login />);
		const emailField = login.findAllByTestId('login_email');
	//TODO
	});

What happened:

I get a typescript error saying: "login_email" is not compatible with type 'MatcherOptions | undefined'.

Issue

I read the source code... and the example in the documentations, and I think that the right type for this function's argument should be Match, as declared in matches.d.ts

Workaround

If I write 'login_email' as any, it works normally

Remove styles object from `debug()` output

Describe the feature you'd like:

Currently, in debug output, we filter out any prop that has a function as its value because it's noisy and not very helpful. I would like to propose that we also filter out styles because they have a tendency to be long and noisy, and generally not provide much value.

Suggested implementation:

I'd like to implement this by filtering these values out in debug output, but not snapshots. I don't see a reason to exclude the styles from snapshots, especially since in that context they could definitely be useful to ensure that your components are still being rendered as expected.

Describe alternatives you've considered:

I'd considered filtering styles out of snapshot output as well, but I think that's too far. That output could be useful, at least sometimes. I also thought about making this behavior configurable, but I think it unnecessarily complicates the API. I also don't see how style props are usually useful for debugging a query, and they make the output hard to grep.

Teachability, Documentation, Adoption, Migration Strategy:

I don't think this has much impact on any of these areas πŸ€”

Update the example on this repository readme file

Details

The example on this repository's readme file isn't working, but the one on the docs is working fine, it would be helpful to have the same example in order for the new comers not get frustrated that the example isn't working.

import React from 'react';
import { Button, Text, TextInput, View } from 'react-native';
import { fireEvent, render, wait } from '@testing-library/react-native';

function Example() {
  const [name, setUser] = React.useState('');
  const [show, setShow] = React.useState(false);

  return (
    <View>
      <TextInput value={name} onChangeText={setUser} testID="input" />
      <Button
        title="Print Username"
        onPress={() => {
          // let's pretend this is making a server request, so it's async
          // (you'd want to mock this imaginary request in your unit tests)...
          setTimeout(() => {
            setShow(!show);
          }, Math.floor(Math.random() * 200));
        }}
      />
      {show && <Text testID="printed-username">{name}</Text>}
    </View>
  );
}

test('examples of some things', async () => {
  const { getByTestId, getByText, queryByTestId, baseElement } = render(<Example />);
  const famousWomanInHistory = 'Ada Lovelace';

  const input = getByTestId('input');
  fireEvent.changeText(input, famousWomanInHistory);

  const button = getByText('Print Username');
  fireEvent.press(button);

  await wait(() => expect(queryByTestId('printed-username')).toBeTruthy());

  expect(getByTestId('printed-username').props.children).toBe(famousWomanInHistory);
  expect(baseElement).toMatchSnapshot();
});

Typings for *ByDisplayValue and *ByTitle queries

  • react-native or expo: react-native
  • native-testing-library version: 4.0.6
  • jest-preset: @testing-library/react-native
  • react-native version: 0.59.9
  • node version: 12.4.0

Relevant code or config:

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

import Form from '../src/components/Form';

describe('Form', () => {
  it('should render 1 <TextInput /> and 1 <TouchableOpacity />', () => {
    const { getByPlaceholderText, getByTestId } = render(<Form />);
    const input = getByPlaceholderText('Type some text'); // We are searching for <TextInput />;
    expect(input).toHaveProp('value', '');
    const button = getByTestId('SubmitButton'); // We are searching for <TouchableOpacity />;
    expect(button).toHaveTextContent('Save text');
  });
  it('should call onSubmit prop after pressing <TouchableOpacity />', () => {
    const onSubmit = jest.fn();
    const { getByTestId } = render(<Form onSubmit={onSubmit} />);
    const button = getByTestId('SubmitButton');
    fireEvent.press(button);
    expect(onSubmit).toBeCalledTimes(1);
  });
  it('should change <TextInput /> value after typing some text', () => {
    const { getByPlaceholderText, getByDisplayValue } = render(<Form />);
    const input = getByPlaceholderText('Type some text');
    const textValue = 'SomeTextValue';
    fireEvent.changeText(input, textValue);
    getByDisplayValue(textValue);
  });
});

What you did:

I tried to use GetByDisplayValue in project with Typescript

What happened:

Typescript shows error:
Property 'getByDisplayValue' does not exist on type 'RenderResult<typeof import("e:/reactnative/submitTextApp/node_modules/@testing-library/react-native/typings/queries")>'

Reproduction:

Repository: https://gitlab.com/Mateusz_Medrek/reactnativewithnativetestinglibrary

Example code is from tests/Form.spec.tsx

Problem description:

I can't use *ByDisplayValue in Typescript project. In typings directory there is no type for any of ByDisplayValue queries, similar problem is for *ByTitle queries. Instead, there are types for *ByA11yStates and ByA11yTraits queries, which are not present in package since version 3.x.x

Suggested solution:

I would suggest changing typings/queries.d.ts, to include *ByDisplayValue and *ByTitle queries, and remove *ByA11yStates and *ByA11yTraits

example for GetByDisplayValue

export const getByDisplayValue: GetByBoundProp;
export const getByHintText: GetByBoundProp;
export const getByLabelText: GetByBoundProp;
export const getByRole: GetByBoundProp;
export const getByPlaceholderText: GetByBoundProp;
export const getByTestId: GetByBoundProp;
export const getByText: GetByText;
export const getByTitle: GetByBoundProp;

Update React and React Native dependencies to get async act

The React Native update to 0.61.1 was released in the last few days and it would be great if we could update to it to take advantage of things like async act.

Updating to the new versions should (in theory) not break anything since they are all minor versions. There might be some potential work involved in updating the act calls to allow for async acts (maybe wrapping everything into async act by default?).

Typescript error "does not satisfy the constraint 'Queries'

  • react-native or expo: react-native
  • native-testing-library version: ^4.0.2
  • jest-preset: @testing-library/react-native
  • react-native version: 0.59.8
  • node version: v11.10.1

Relevant code or config:

__test__/App.spec.tsx

import 'react-native'
import React from 'react'
import App from 'app/src/App'

import { render } from '@testing-library/react-native'

it('renders correctly', () => {
  const { baseElement } = render(<App />)
  expect(baseElement).toMatchSnapshot()
})

What you did:

Rendered a component and use toMatchSnapshot.

What happened:

TypeScripts error occurred.

node_modules/@testing-library/react-native/typings/get-queries-for-element.d.ts:31:58 - error TS2344: Type 'typeof import("/Users/me/workspace/react-native/react-native-sample/node_modules/@testing-library/react-native/typings/queries")' does not satisfy the constraint 'Queries'.
  Property 'getByHintText' is incompatible with index signature.
    Type 'GetByBoundProp' is not assignable to type 'Query'.
      Type 'Pick<ReactTestInstance, "children" | "type" | "props" | "parent" | "find" | "findAll">' is not assignable to type 'Error | ReactTestRenderer | ReactTestRenderer[] | Promise<ReactTestRenderer[]> | Promise<ReactTestRenderer> | null'.
        Type 'Pick<ReactTestInstance, "children" | "type" | "props" | "parent" | "find" | "findAll">' is missing the following properties from type 'ReactTestRenderer[]': length, pop, push, concat, and 27 more.

31 export function getQueriesForElement<T extends Queries = typeof queries>(
                                                            ~~~~~~~~~~~~~~

node_modules/@testing-library/react-native/typings/index.d.ts:26:46 - error TS2344: Type 'typeof import("/Users/me/workspace/react-native/react-native-sample/node_modules/@testing-library/react-native/typings/queries")' does not satisfy the constraint 'Queries'.
  Property 'getByHintText' is incompatible with index signature.
    Type 'GetByBoundProp' is not assignable to type 'Query'.
      Types of parameters 'testRenderer' and 'testRenderer' are incompatible.
        Type 'ReactTestRenderer | Pick<ReactTestInstance, "children" | "type" | "props" | "parent" | "find" | "findAll">' is not assignable to type 'ReactTestRenderer'.
          Type 'Pick<ReactTestInstance, "children" | "type" | "props" | "parent" | "find" | "findAll">' is missing the following properties from type 'ReactTestRenderer': toJSON, toTree, unmount, update, and 2 more.

26 export type RenderResult<Q extends Queries = typeof queries> = {
                                                ~~~~~~~~~~~~~~

node_modules/@testing-library/react-native/typings/index.d.ts:35:52 - error TS2344: Type 'typeof import("/Users/me/workspace/react-native/react-native-sample/node_modules/@testing-library/react-native/typings/queries")' does not satisfy the constraint 'Queries'.

35 export interface RenderOptions<Q extends Queries = typeof queries> {
                                                      ~~~~~~~~~~~~~~

node_modules/@testing-library/react-native/typings/query-helpers.d.ts:7:18 - error TS2430: Interface 'SelectorMatcherOptions' incorrectly extends interface 'MatcherOptions'.
  Types of property 'selector' are incompatible.
    Type 'string | undefined' is not assignable to type 'SelectorFn | undefined'.
      Type 'string' is not assignable to type 'SelectorFn | undefined'.

7 export interface SelectorMatcherOptions extends MatcherOptions {
                   ~~~~~~~~~~~~~~~~~~~~~~

node_modules/@testing-library/react-native/typings/query-helpers.d.ts:12:13 - error TS7051: Parameter has a name but no type. Did you mean 'arg0: string'?

12   getProp: (string) => NativeTestInstance;
               ~~~~~~


Found 5 errors.

Reproduction:

Problem description:

Cannot compile it.

Suggested solution:

I temporarily skip typing check using paths option in tsconfig.json and create types/@testing-library/react-native.d.ts like this:

tsconfig.json

"compilerOptions": {
  "paths": {"@testing-library/react-native": ["types/@testing-library/react-native.d.ts"]}
}

Could you please fix this typing error or give me any suggestions?

setTimeout is not a function

  • react-native or expo: rect-native
  • native-testing-library version: ^4.0.14
  • jest-preset: @testing-library/react-native
  • react-native version: 0.60.5
  • node version: 10.14.2

Relevant code or config:

TextSwitcher.js

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

const animationDuration = 300;

function TextSwitcher({ isOn, onText, offText }) {
	const [onTextOpacity] = useState(new Animated.Value(0));
	const [offTextOpacity] = useState(new Animated.Value(1));

	useEffect(
		() => {
			Animated.parallel([
				Animated.timing(onTextOpacity, {
					toValue: isOn ? 1 : 0,
					duration: animationDuration,
					delay: isOn ? animationDuration : 0,
				}).start(),
				Animated.timing(offTextOpacity, {
					toValue: isOn ? 0 : 1,
					duration: animationDuration,
					delay: isOn ? 0 : animationDuration,
				}).start(),
			]);
		},
		[isOn]
	);

	return (
		<View>
			<Animated.Text style={{ opacity: onTextOpacity}}>
				{onText}
			</Animated.Text>
			<Animated.Text style={{ opacity: offTextOpacity}}>
				{offText}
			</Animated.Text>
		</View>
	);
}


export default TextSwitcher;

TextSwitcher.test.js

import React from 'react';
import '@testing-library/jest-dom/extend-expect';
import { render, wait } from '@testing-library/react-native';
import TextSwitcher from './TextSwitcher';

it('if on, shows onText', async () => {
	const { getByText } = render(
		<TextSwitcher isOn={true} offText={offText} onText={onText} />
	);
	await wait(() => {
		expect(getByText(onText)).toBeVisible();
	});
});

What you did:

I created a component that switches 2 texts based on a boolean value

What happened:

When I run the test, it returns setTimeout is not a function

Problem description:

Since the fade-in and fade-out animations of the text when it switches have a delay, I need to test it within an async function.

I followed the example in the example in the documentation
https://www.native-testing-library.com/docs/guide-disappearance#waiting-for-disappearance

When I run the test, it returns this error setTimeout is not a function

Picker onValueChange callback not working

<!-

  • react-native:
  • native-testing-library version: @testing-library/react-native": "^5.0.1"
  • jest-preset: "preset": "@testing-library/react-native"
  • react-native version: 0.61.4
  • node version: 13.2.0

Relevant code or config:

I'm having trouble changing the value of a native Picker component to test a component I've built on my own that uses the react-native Picker.
Observing that calling fireEvent.valueChange did trigger the onValueChange callback, I was intrigued why wasn't my hook useState wasn't been updated if it worked in the ios and android simulator.

I decided to test the example given in the React Native docs, but it also did not work.

source of the example: https://facebook.github.io/react-native/docs/picker

My component code:

export class PickerComponent extends React.Component {
  state = {
    language: ''",
  };
  render() {
    return (
      <Picker
        accessibilityLabel="picker-ios"
        selectedValue={this.state.language}
        style={{ height: 50, width: 100 }}
        onValueChange={(itemValue, itemIndex) =>
          this.setState({ language: itemValue })
        }>
        <Picker.Item label="Java" value="java" />
        <Picker.Item label="JavaScript" value="js" />
      </Picker>
    );
  }
}

Jest example

it('should  render and change the selectedItem' , () => {
    const { getByLabelText } = render(<PickerComponent />);
    const Picker = getByLabelText('picker-ios');
    fireEvent.valueChange(Picker, items[0]);
    console.log(Picker);    

Testing it I observed that somehow the onValueChange callback is triggered but no update is done after calling it.

What you did:

Tested Picker component on OSX with react native.

What happened:

Doesn't update component status after changing values.

There is no error, it just doesn't update on Jest.

Reproduction:

This is the minimum code required

export class PickerComponent extends React.Component {
  state = {
    language: '',
  };
  render() {
    return (
      <Picker
        accessibilityLabel="picker-ios"
        selectedValue={this.state.language}
        style={{ height: 50, width: 100 }}
        onValueChange={(itemValue, itemIndex) =>
          this.setState({ language: itemValue })
        }>
        <Picker.Item label="Java" value="java" />
        <Picker.Item label="JavaScript" value="js" />
      </Picker>
    );
  }
}

Jest example

it('should  render and change the selectedItem' , () => {
    const { getByLabelText } = render(<PickerComponent />);
    const Picker = getByLabelText('picker-ios');
    fireEvent.valueChange(Picker, items[0]);
    console.log(Picker);    
})

Problem description:

When testing Picker component with the lib, using fireEvent with valueChange calls the Picker change value callback but doesn't update the state in the tested component.

Suggested solution:

Probably some inner problem related to the library itself.

Can you help us fix this issue by submitting a pull request?

Yes, but no idea where to start.

Add typescript types

As in the title. Typescript types will make it easier to use this library for both typescript and non-typescript users as they act as a documentation for the library's features and provide autocompletion hints.

implement closest

Describe the feature you'd like:

I'd like to have a similar closest function/helper of react-testing-library to find elements closest to another

Use case: find a Button/TouchableOpacity from the text inside of it

debug output

<TouchableOpacity
                            activeOpacity={0.2}
                          >
                            <Text
                              color="#e8ecf0"
                            >
                              Save
                            </Text>

const button = getByTest('Save').closest('TouchableOpacity')

Suggested implementation:

try to follow the react/dom implementation

Describe alternatives you've considered:

Teachability, Documentation, Adoption, Migration Strategy:

Return type of query methods don't align with fireEvent methods.

  • react-native or expo: react-native
  • native-testing-library version: 3.0.0
  • jest-preset: native-testing-library
  • react-native version: 0.59.2
  • node version: 10.13.0

Relevant code or config:

import * as React from "react";
import { Button, Text, View } from "react-native";
import { fireEvent, render } from "native-testing-library";

function Example() {
  const [ visible, toggleVisibility ] = React.useState(false);

  return (
    <View>
      <Button
        testID="button"
        title="Press Me"
        onPress={() => toggleVisibility(!visible)}
      />
      {visible
        ? <Text testID="text">Hello World!</Text>
        : null
      }
    </View>
  );
}

test("example", () => {
  const { getByTestId } = render(<Example />);

  const button = getByTestId("button");

  fireEvent.press(button);

  const text = getByTestId("text");

  expect(text.props.children).toEqual("Hello World!");
});

What you did:

Followed the documentation and code examples for firing events and accessing props but found TypeScript errors.

What happened:

TypeScript error for fireEvent.press call:

Screenshot 2019-05-21 at 20 52 47

Error:(28, 19) TS2345: Argument of type 'ReactTestRenderer' is not assignable to parameter of type 'Pick<ReactTestInstance, "type" | "props" | "parent" | "children" | "find" | "findAll">'.

TypeScript error when accessing element props:

Screenshot 2019-05-21 at 21 14 14

Error:(32, 15) TS2339: Property 'props' does not exist on type 'ReactTestRenderer'.

Reproduction:

See full code example above.

Problem description:

The TypeScript error suggest that I'm using the library wrong even though I'm following exactly as the documentation states. The only way to run the tests is to use @ts-ignore comments above each line potentially suppressing other issues TypeScript may find with my tests.

Suggested solution:

I found that modifying the return type of the exported methods in typings/queries.d.ts from ReactTestRenderer to NativeTestInstance seemed to solve the issue, but I'm not exactly sure if that's correct. My knowledge of react-test-renderer is rather limited.

getByText unusable

  • react-native or expo: react-native
  • native-testing-library version: 4.0.6
  • jest-preset: react-native
  • react-native version: 0.59.1
  • node version: 11.4.0

Relevant code or config:

const { getByText } = render(<SomeComponent />)
expect(getByText(/.*/).props.children).toEqual('some value')

What you did:

I updated from version 2 to 4.

What happened:

The tests failed because of the following error:

TypeError: Cannot read property 'includes' of undefined
      at validComponentFilter (node_modules/@testing-library/react-native/dist/lib/query-helpers.js:37:43)
      at node_modules/@testing-library/react-native/dist/lib/queries/text.js:32:47
      at overrideCb (node_modules/@testing-library/react-native/dist/lib/query-helpers.js:75:22)
      at _findAll (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12981:7)
      at Proxy.findAll (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12910:12)
      at Proxy.<anonymous> (node_modules/@testing-library/react-native/dist/lib/query-helpers.js:78:24)
      at queryAllByText (node_modules/@testing-library/react-native/dist/lib/queries/text.js:31:31)
      at node_modules/@testing-library/react-native/dist/lib/query-helpers.js:172:24
      at node_modules/@testing-library/react-native/dist/lib/query-helpers.js:156:24
      at Object.<anonymous> (test/ui/ProfileAndWallet/Profile/SecurityScreen.test.ts:20:21)

Problem description + Suggested solution

Calling the getConfig function from validComponentFilter given the key "textComponents" makes it return undefined and throw an error when attempting to call .includes
https://github.com/testing-library/native-testing-library/blob/master/src/lib/query-helpers.js#L24

The solution is to call configure when loading the library or permit any element to be queried if the function returns undefined

fireEvent or some other utility for RN specific events

Describe the feature you'd like:

I want to be able to fire some RN specific events -- namely Linking and BackButton. In the past I've mocked these out with an imperative API similar to fireEvent, I thought it would make a nice addition to the library, as I'm not sure it's possible at the moment

Suggested implementation:

Something to the effect of fireEvent.backButton() and fireEvent.linkChanged('url') would be the desired end result

`fireEvent.changeValue()` on Switch component doesn't work

Sorry for not having time to fill up the template, but there might be a problem with calling fireEvent.changeValue() on a react-native Switch component. I tried it for several hours and in several ways and the handler was not called (maybe others will find this useful).

I did change to react-native-testing-library where it worked.

Implement better async act detection

Describe the feature you'd like:

As implemented by @threepointone in testing-library/react-testing-library#407, more can be done to check if the async version of act is available. We'll probably need to implement this here as well, even though there's no version of React Native yet that officially supports React 16.9.

Suggested implementation:

I'd imagine most of what's in the PR i referenced will work here, but I also don't know and async act (kinda act in general) is a bit of a mystery to me. Based off of a very high level overview of the PR, I think the tests would probably pass as well, assuming we get act from the test renderer instead of ReactTestUtils. But I'm not positive.

Describe alternatives you've considered:

We could always just not do this since no version of RN supports it and there haven't been any bug reports because of the current patch for those who already use the alpha in their apps.

Teachability, Documentation, Adoption, Migration Strategy:

Won't change anything here.

find* methods does not work as expected?

  • react-native
  • native-testing-library version: 5.0.1
  • jest-preset: @testing-library/react-native
  • react-native version: 16.12.0
  • node version: 11

Relevant code or config:

    const button = await findByTestId('button-id');
    fireEvent.press(button);
    const button = getByTestId('button-id');
    fireEvent.press(button);

What you did:

Hi, I am trying to use the find* methods to attempt to wait for an element to appear. The second block works but the first one doesn't. Shouldn't both be equivalent?

What happened:

I got the error here: : Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:

Reproduction:

In fact, I wasn't able to run the async method in the README - I get this error:
Screenshot 2019-11-18 at 6 16 28 PM

Problem description:

Both methods should work similarly because the Promise in the find implementation should resolve once the get* returns true

Can you help us fix this issue by submitting a pull request?

I can try if I have a direction how to fix this!

JavaScript heap out of memory when using `.toMatchSnapshot()` after `render`

  • react-native or expo: react-native
  • native-testing-library version: 4.0.9
  • jest-preset: react-native
  • react-native version: 0.60.5
  • node version: 10.16.0

Relevant code or config:

In a fresh project add the following:

/**
 * @format
 */

import 'react-native';
import React from 'react';
import App from '../App';

import {render} from '@testing-library/react-native';

describe('The App', () => {
  it('This passes', () => {
    const {baseElement} = render(<App />);

    expect(baseElement).toBeTruthy();
  });

  it('This causes "JavaScript heap out of memory"', async () => {
    const {baseElement} = render(<App />);

    expect(baseElement).toMatchSnapshot();
  });
});

What you did:

Ran yarn test

What happened:

Tests timed out and the following error occured: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

Reproduction:

Minimal reproduction: https://github.com/jhalvorson/test-lib-rn-minimal-reproduction

Problem description:

Can't generate snapshots or run other tests if one test includes .toMatchSnapshot()

Suggested solution:

Haven't taken a proper look yet but will do either later today or tomorrow morning.

Can you help us fix this issue by submitting a pull request?

Yes, would be more than happy to help out if pointed in the right direction.

provided preset does not cover native-module event-emitter

Relevant code or config:

// jest.config.js

const testingLibraryJestPreset = require('@testing-library/react-native/jest-preset');

module.exports = {
  preset: '@testing-library/react-native',
  setupFiles: [...testingLibraryJestPreset.setupFiles],
  ...
}

What you did:

npx jest

What happened:

crash on falsy presence of NativeEventEmitter

 ● Test suite failed to run

    Invariant Violation: Native module cannot be null.

      1 | // @flow
      2 | import React from 'react';
    > 3 | import { render } from '@testing-library/react-native';
        | ^
      4 | import TestRenderer from 'react-test-renderer';
      5 |

      at invariant (node_modules/invariant/invariant.js:40:15)
      at new NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:36:7)
      at Object.<anonymous> (node_modules/react-native/Libraries/Components/Keyboard/Keyboard.js:19:30)
      at Object.<anonymous> (node_modules/react-native/Libraries/Components/ScrollResponder.js:15:18)
      at Object.<anonymous> (node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js:17:25)
      at mockComponent (node_modules/@testing-library/react-native/dist/preset/mock-component.js:26:28)
      at Object.user:/Users/cdaringe/src/myapp/node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js: (node_modules/@testing-library/react-native/dist/preset/mock-modules.js:22:47)
      at Object.<anonymous> (node_modules/react-native/Libraries/Lists/VirtualizedList.js:18:20)
      at Object.<anonymous> (node_modules/react-native/Libraries/Lists/FlatList.js:16:25)
      at Object.<anonymous> (node_modules/react-native/Libraries/YellowBox/UI/YellowBoxList.js:15:18)
      at Object.<anonymous> (node_modules/react-native/Libraries/YellowBox/YellowBox.js:50:25)
      at Object.<anonymous> (node_modules/react-native/Libraries/ReactNative/AppContainer.js:132:23)
      at Object.<anonymous> (node_modules/@testing-library/react-native/dist/index.js:37:44)
      at Object.<anonymous> (src/__tests__/app.test.js:3:1)

Reproduction:

  • i'm willing to make one of these, but i'd like to have a discussion first if feasible

Problem description:

  • tests wont run due to invariant violation due to missing mocks? for native modules

Suggested solution:

this issue is generally discussed verbatim here:

jestjs/jest#2208

it's a bit of a messy thread, but more or less lands on that the presets should mock this out. in our case, it didn't seem to do so πŸ€”

Can you help us fix this issue by submitting a pull request?

πŸ’― . however, i could use some coaching. whilst doing s/w and react for a long while, i'm brand new to RN :)

Custom Events not triggered

  • react-native or expo: react-native
  • native-testing-library version: 4.0.9
  • jest-preset: @testing-library/react-native
  • react-native version: 0.59
  • node version: 12.6.0

What you did:

fireEvent(getByTestId('SegmentedControlIOS'), new NativeTestEvent('change',  { nativeEvent: { selectedSegmentIndex: 1, value: 'some value' }}))

What happened:

event does not get triggered

Reproduction:

https://github.com/northbank/ntl-sample

Problem description:

Event listeners on components not in the eventMap in src/lib/events.js do not get triggered if the event could have belonged to one of the arrays in the eventMap

Suggested solution:

+function shouldValidate(element) {
+  return eventMap[element.type] || eventMap[element.type.displayName];
+}
+
 function isValidTarget(element, event) {
-  return event.validTargets.length ? validateElementType(event.validTargets, element) : true;
+  return shouldValidate(element) ? validateElementType(event.validTargets, element) : true;
 }

Can you help us fix this issue by submitting a pull request?

yes

DisplayValue Queries on Empty Text Fields

Hello,

I am using React Native 0.61.5 with native-testing-library version 5.0.1 and Node 10.14. I recently upgraded my React Native project from 0.59 to 0.61. As a part of that upgrade, I also upgraded my Testing Library version from 4.0.7 to 5.0.1. It appears that the *DisplayValue queries cannot find text elements with empty values.

I believe the issue is the "if" block on Line 25 of this file (I have not confirmed yet, but I will spend some time on it):

https://github.com/testing-library/native-testing-library/blob/master/src/lib/matches.js

Relevant code or config:

Here is an example failing test.

import React from 'react';
import mount from 'core/test/support/mount'; // In my project, this is basically just the render function from native-testing-library
import { TextInput } from 'react-native';

function TextElement() {
  return <TextInput value={''} />;
}

function mountComponent() {
  return mount(
    <TextElement />
  );
}

it('finds the empty text element', () => {
  const { getByDisplayValue } = mountComponent();

  getByDisplayValue('');
});

For reference, here is the debug output:

<View
      pointerEvents="box-none"
      style={
        Object {
          "flex": 1,
        }
      }
    >
      <View
        collapsable={true}
        pointerEvents="box-none"
        style={
          Object {
            "flex": 1,
          }
        }
      >
        <TextInput
          allowFontScaling={true}
          rejectResponderTermination={true}
          underlineColorAndroid="transparent"
          value=""
        />
      </View>
    </View>

I'll see if I can fix this locally. I'll try to submit a PR with a potential fix, but I am not sure why the code in matches.js was added between 4.0.7 and 5.0.1, and I don't want to introduce another potential bug. Any insight or guidance on how to test empty text fields would be great.

prettyPrint could take debug options when element was not found

  • react-native or expo: react-native
  • native-testing-library version: 5.0.1
  • jest-preset: native-testing-library
  • react-native version: 0.61.0
  • node version: 12.4.0

Relevant code or config:

expect(getByText('myText')).toBeTruthy();

What you did:

Try to find a text that is not in the native nodes

What happened:

it showed the debug() output but without take debug omitProps into consideration

Reproduction:

Problem description:

it should always take debug options in consideration when printing the native nodes

Suggested solution:

pass debug to getQueriesForElement

...getQueriesForElement(baseElement, queries),

Can you help us fix this issue by submitting a pull request?

I'll try

TypeError: require(...).configureNextLayoutAnimation is not a function.

  • react-native or expo: react-native
  • native-testing-library version: 3.1.1
  • jest-preset: native-testing-library
  • react-native version: 0.59.2
  • node version: 10.13.0

Relevant code or config:

import * as React from "react";
import { Button, LayoutAnimation, Text, View } from "react-native";
import { fireEvent, render, waitForElement } from "native-testing-library";

function Example() {
  const [ showMessage, setShowMessage ] = React.useState(false);

  const toggleMessage = () => {
    LayoutAnimation.configureNext({
      ...LayoutAnimation.Presets.easeInEaseOut,
      duration: 100
    });

    setShowMessage((prevState) => !prevState);
  };

  return (
    <View>
      <Button
        testID="button"
        title="Print Username"
        onPress={toggleMessage}
      />
      {showMessage
        ? <Text testID="text">Hello World!</Text>
        : null
      }
    </View>
  );
}

test("component using LayoutAnimation works as expected", async () => {
  const { getByTestId, queryByTestId } = render(<Example />);

  const $button = getByTestId("button");
  fireEvent.press($button);

  const $text = await waitForElement(() => queryByTestId("text"));
  expect($text!.props.children).toEqual("Hello World!");
});

What you did:

Rendered a component that uses the LayoutAnimation API from the react-native package.

What happened:

I get the following exception:

TypeError: require(...).configureNextLayoutAnimation is not a function

       7 |
       8 |   const toggleMessage = () => {
    >  9 |     LayoutAnimation.configureNext({
         |                     ^
      10 |       ...LayoutAnimation.Presets.easeInEaseOut,
      11 |       duration: 100
      12 |     });

Reproduction:

See code snippet above.

Problem description:

Unless mocked manually, it's not possible to test component trees that use LayoutAnimation.

Suggested solution:

In my Jest setup script, I use the auto-mocking feature to simply mock the API surface of LayoutAnimation:

jest.mock("LayoutAnimation");

Is this something that could be mocked by this library automatically to avoid confusion for users in the future?

An update to Test inside a test was not wrapped in act. With v5.0.1

Issue description

With the latest version of the library and with the latest RN I get the following error in the console:

Cannot log after tests are done. Did you forget to wait for something async in your test?
Attempted to log "Warning: An update to Test inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

There is more output in the console, but this is essential I think. Not sure if it is really related to #25

Also, test is marked as successful.

With @testing-library/react an equivalent test in a web app project causes no problems at all.

How to reproduce

npx react-native init TestApp
npm i --save-dev @testing-library/react-native

Create a Test.test.js inside of __tests__ with following content:

import React, {useEffect, useState} from 'react';
import {Text, View} from 'react-native';
import {render} from '@testing-library/react-native';

const Test = () => {
    const [v, setV] = useState(1);
    useEffect(()=>{
        setTimeout(() => {
            setV(2);
        }, 0)
    }, []);
    return <View><Text>{v}</Text></View>
};
test('Test', () => {
    render(<Test />);
});

Then npm run test

Versions

  • react-native or expo: react-native
  • native-testing-library version: 5.0.1
  • jest-preset: @testing-library/react-native
  • react-native version: 0.61.3
  • node version: v13.2.0

example request for react-navigation 2.x

We've a large scale app where we're using react-navigation v2.x. It will take us sometime to upgrade to 3.0. I've gone through the example for renderwithnavigation for v3.

Do you mind adding an example with v2 as well?

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.