add waitForElement helper

This commit is contained in:
Jake McDermott 2019-05-22 08:46:16 -04:00
parent 6bfbcb35cd
commit 7965f94027
No known key found for this signature in database
GPG Key ID: 9A6F084352C3A0B7
3 changed files with 82 additions and 8 deletions

View File

@ -1,6 +1,6 @@
import React from 'react';
import { mountWithContexts } from './enzymeHelpers';
import { mountWithContexts, waitForElement } from './enzymeHelpers';
import { asyncFlush } from '../jest.setup';
@ -66,11 +66,9 @@ describe('<App />', () => {
expect(wrapper.find(aboutModalContent)).toHaveLength(0);
wrapper.find(aboutDropdown).simulate('click');
wrapper.find(aboutButton).simulate('click');
wrapper.update();
// check about modal content
const content = wrapper.find(aboutModalContent);
expect(content).toHaveLength(1);
const content = await waitForElement(wrapper, aboutModalContent);
expect(content.find('dd').text()).toContain(ansible_version);
expect(content.find('pre').text()).toContain(`< Tower ${version} >`);

View File

@ -158,3 +158,26 @@ export function mountWithContexts (node, options = {}) {
};
return mount(wrapContexts(node, context), { context, childContextTypes });
}
/**
* Wait for element to exist.
*
* @param[wrapper] - A ReactWrapper instance
* @param[selector] - The selector of the element to wait for.
*/
export function waitForElement (wrapper, selector) {
const interval = 100;
return new Promise((resolve, reject) => {
let attempts = 30;
(function pollElement () {
wrapper.update();
if (wrapper.exists(selector)) {
return resolve(wrapper.find(selector));
}
if (--attempts <= 0) {
return reject(new Error(`Element not found using ${selector}`));
}
return setTimeout(pollElement, interval);
}());
});
}

View File

@ -1,8 +1,8 @@
import React from 'react';
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { mountWithContexts } from './enzymeHelpers';
import { mountWithContexts, waitForElement } from './enzymeHelpers';
import { Config } from '../src/contexts/Config';
import { withNetwork } from '../src/contexts/Network';
import { withRootDialog } from '../src/contexts/RootDialog';
@ -185,12 +185,12 @@ describe('mountWithContexts', () => {
});
it('should set props on wrapped component', () => {
function Component ({ text }) {
function TestComponent ({ text }) {
return (<div>{text}</div>);
}
const wrapper = mountWithContexts(
<Component text="foo" />
<TestComponent text="foo" />
);
expect(wrapper.find('div').text()).toEqual('foo');
wrapper.setProps({
@ -199,3 +199,56 @@ describe('mountWithContexts', () => {
expect(wrapper.find('div').text()).toEqual('bar');
});
});
/**
* This is a fixture for testing async components. It renders a div
* after a short amount of time.
*/
class TestAsyncComponent extends Component {
constructor (props) {
super(props);
this.state = { displayElement: false };
}
componentDidMount () {
setTimeout(() => {
this.setState({ displayElement: true });
}, 1000);
}
render () {
const { displayElement } = this.state;
if (displayElement) {
return (<div id="test-async-component" />);
}
return null;
}
}
describe('waitForElement', () => {
it('waits for the element and returns it', async (done) => {
const selector = '#test-async-component';
const wrapper = mountWithContexts(<TestAsyncComponent />);
expect(wrapper.exists(selector)).toEqual(false);
const elem = await waitForElement(wrapper, selector);
expect(elem.props().id).toEqual('test-async-component');
expect(wrapper.exists(selector)).toEqual(true);
done();
});
it('eventually throws an error for elements that don\'t exist', async (done) => {
const selector = '#does-not-exist';
const wrapper = mountWithContexts(<div />);
let error;
try {
await waitForElement(wrapper, selector);
} catch (err) {
error = err;
} finally {
expect(error).toEqual(new Error(`Element not found using ${selector}`));
done();
}
});
});