Skip to content

Identical consecutive tests failing with await waitForElement() #121

Closed
@RT-TL

Description

@RT-TL

Thanks for this awesome testing library!

  • react-testing-library version: 4.0.1
  • react version: 16.3.1
  • node version: 8.4.0
  • npm (or yarn) version: yarn 0.27.5

Relevant code or config:

// test.js
import React from 'react';
import { render, fireEvent, cleanup, waitForElement } from 'react-testing-library';
import 'jest-dom/extend-expect';
import axiosMock from 'axios';
import renderAppWithState from '../../__mocks__/integration-utils'; 
// returns app wrapped in memory router and with created store
import DATA from '../../__mocks__/api/DATA';

describe('Questionnaire flow', () => {
  beforeEach(() => {
    axiosMock.get.mockResolvedValue({data: {data: { ...DATA }}})
  });

  afterEach(() => {
    cleanup();
  });

  it('First test', async () => {
    const { getByText } = render(renderAppWithState('/start'));
    await waitForElement(() => getByText('Some text'));
    expect(getByText('Some text')).toBeTruthy();
  });

  it('Second test', async () => {
    const { getByText } = render(renderAppWithState('/start'));
    await waitForElement(() => getByText('Some text'));
    expect(getByText('Some text')).toBeTruthy();
  });
});


// renderAppWithState.js
import React from 'react';
import { MemoryRouter, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import sampleData from '../src/initialState.json';
import MainLayout from '../src/components/views/MainLayout';
import storeFactory from '../src/store';
import SubRoutes from '../src/subroutes';

export default function renderAppWithState(url, state) {

  const store = state ? storeFactory(state) : storeFactory(sampleData);
  // automatically unmount and cleanup DOM after the test is finished.
  return (
      <MemoryRouter basename={env.basename} initialEntries={[url]}>
        <Provider store={store}>
          <MainLayout>
            <Route
              path="/"
              render={({location}) => {
                return (
                  <div>
                    <SubRoutes />
                  </div>
                );
              }}
            />
          </MainLayout>
        </Provider>
      </MemoryRouter>
  )
}

What you did:

I am setting up integration tests for my react app. I use react, react-router and redux. I am following the react-testing-library example, using axiosMock and await for the promise to be resolved.

When going to the /start route:

  • an redux action is triggered that uses a promise-based API call
  • this api call is intercepted with the axiosMock
  • the response data is used to update the app state
  • after state has been updated, a history.push() changes the current route of the app, rendering a different component

What happened:

In the example above I used two identical tests. I wanted to make sure tests are isolated. But while the first test always succeeds, the second test always fails due to timeout at await waitForElement(...) with the message 'Unable to find an element with the text...'

Problem description:

Identical, rather simple tests fail, although they should be indempotent. In the first test, history.push is called as expected, the route is changed and the correct component is rendered. In the second test component state / route are not updated as they should.

Suggested solution:

Without internal konwledge of react testing library I can think of two possible reasons: 1.) I made a mistake in the setup or misunderstood how react-testing-library works. 2.) async and waitForElement have some impact on consecutive tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions