Skip to content

Commit

Permalink
e2e: Reduce complexity of e2e and improve Jest coverage (facebook#1484)
Browse files Browse the repository at this point in the history
  • Loading branch information
Timer committed Feb 8, 2017
1 parent ea38a2a commit f2df11d
Show file tree
Hide file tree
Showing 36 changed files with 257 additions and 183 deletions.
2 changes: 1 addition & 1 deletion fixtures/kitchensink/.babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"presets": ["latest"]
"presets": ["react-app"]
}
1 change: 0 additions & 1 deletion fixtures/kitchensink/.template.dependencies.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"dependencies": {
"babel-preset-latest": "6.16.0",
"babel-register": "6.22.0",
"babel-polyfill": "6.20.0",
"chai": "3.5.0",
Expand Down
53 changes: 33 additions & 20 deletions fixtures/kitchensink/src/App.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
import React from 'react';
import React, { Component, PropTypes, createElement } from 'react';

class BuiltEmitter extends React.Component {
constructor(props) {
super(props)

this.callWhenDone = done => done();
class BuiltEmitter extends Component {
static propTypes = {
feature: PropTypes.func.isRequired
}

componentDidMount() {
this.callWhenDone(() => document.dispatchEvent(new Event('ReactFeatureDidMount')));
const { feature } = this.props

// Class components must call this.props.onReady when they're ready for the test.
// We will assume functional components are ready immediately after mounting.
if (!Component.isPrototypeOf(feature)) {
this.handleReady();
}
}

render() {
const feature = React.cloneElement(React.Children.only(this.props.children), {
setCallWhenDone: done => {
this.callWhenDone = done;
}
});
handleReady() {
document.dispatchEvent(new Event('ReactFeatureDidMount'));
}

return <div>{feature}</div>;
render() {
const {
props: { feature },
handleReady
} = this;
return (
<div>
{createElement(feature, {
onReady: handleReady
})}
</div>
);
}
}

class App extends React.Component {
class App extends Component {
constructor(props) {
super(props);

Expand Down Expand Up @@ -105,9 +117,7 @@ class App extends React.Component {
case 'unknown-ext-inclusion':
require.ensure([], () => this.setFeature(require('./features/webpack/UnknownExtInclusion').default));
break;
default:
this.setFeature(null);
break;
default: throw new Error('Unknown feature!');
}
}

Expand All @@ -116,8 +126,11 @@ class App extends React.Component {
}

render() {
const Feature = this.state.feature;
return Feature ? <BuiltEmitter><Feature /></BuiltEmitter> : null;
const { feature } = this.state;
if (feature !== null) {
return <BuiltEmitter feature={feature} />;
}
return null;
}
}

Expand Down
8 changes: 0 additions & 8 deletions fixtures/kitchensink/src/App.test.js

This file was deleted.

20 changes: 11 additions & 9 deletions fixtures/kitchensink/src/features/env/NodePath.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import React from 'react'
import React, { Component, PropTypes } from 'react'
import load from 'absoluteLoad'

export default class extends React.Component {
export default class extends Component {
static propTypes = {
onReady: PropTypes.func.isRequired
}

constructor(props) {
super(props);

this.done = () => {};
this.props.setCallWhenDone && this.props.setCallWhenDone((done) => {
this.done = done;
});

this.state = { users: [] };
}

async componentDidMount() {
const users = load();
this.setState({ users }, () => this.done());
this.setState({ users });
}

componentDidUpdate() {
this.props.onReady();
}

render() {
Expand Down
4 changes: 3 additions & 1 deletion fixtures/kitchensink/src/features/env/NodePath.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import NodePath from './NodePath';
describe('NODE_PATH', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<NodePath />, div);
return new Promise(resolve => {
ReactDOM.render(<NodePath onReady={resolve} />, div);
});
});
});
20 changes: 11 additions & 9 deletions fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { Component, PropTypes } from 'react'

function load() {
return [
Expand All @@ -9,21 +9,23 @@ function load() {
];
}

export default class extends React.Component {
export default class extends Component {
static propTypes = {
onReady: PropTypes.func.isRequired
}

constructor(props) {
super(props);

this.done = () => {};
this.props.setCallWhenDone && this.props.setCallWhenDone((done) => {
this.done = done;
});

this.state = { users: [] };
}

async componentDidMount() {
const users = load();
this.setState({ users }, () => this.done());
this.setState({ users });
}

componentDidUpdate() {
this.props.onReady();
}

render() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import ArrayDestructuring from './ArrayDestructuring';
describe('array destructuring', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<ArrayDestructuring />, div);
return new Promise(resolve => {
ReactDOM.render(<ArrayDestructuring onReady={resolve} />, div);
});
});
});
20 changes: 11 additions & 9 deletions fixtures/kitchensink/src/features/syntax/ArraySpread.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { Component, PropTypes } from 'react'

function load(users) {
return [
Expand All @@ -9,21 +9,23 @@ function load(users) {
];
}

export default class extends React.Component {
export default class extends Component {
static propTypes = {
onReady: PropTypes.func.isRequired
}

constructor(props) {
super(props);

this.done = () => {};
this.props.setCallWhenDone && this.props.setCallWhenDone((done) => {
this.done = done;
});

this.state = { users: [] };
}

async componentDidMount() {
const users = load([{ id: 42, name: '42' }]);
this.setState({ users }, () => this.done());
this.setState({ users });
}

componentDidUpdate() {
this.props.onReady();
}

render() {
Expand Down
4 changes: 3 additions & 1 deletion fixtures/kitchensink/src/features/syntax/ArraySpread.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import ArraySpread from './ArraySpread';
describe('array spread', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<ArraySpread />, div);
return new Promise(resolve => {
ReactDOM.render(<ArraySpread onReady={resolve} />, div);
});
});
});
20 changes: 11 additions & 9 deletions fixtures/kitchensink/src/features/syntax/AsyncAwait.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { Component, PropTypes } from 'react'

async function load() {
return [
Expand All @@ -9,21 +9,23 @@ async function load() {
];
}

export default class extends React.Component {
export default class extends Component {
static propTypes = {
onReady: PropTypes.func.isRequired
}

constructor(props) {
super(props);

this.done = () => {};
this.props.setCallWhenDone && this.props.setCallWhenDone((done) => {
this.done = done;
});

this.state = { users: [] };
}

async componentDidMount() {
const users = await load();
this.setState({ users }, () => this.done());
this.setState({ users });
}

componentDidUpdate() {
this.props.onReady();
}

render() {
Expand Down
4 changes: 3 additions & 1 deletion fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import AsyncAwait from './AsyncAwait';
describe('async/await', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<AsyncAwait />, div);
return new Promise(resolve => {
ReactDOM.render(<AsyncAwait onReady={resolve} />, div);
});
});
});
12 changes: 10 additions & 2 deletions fixtures/kitchensink/src/features/syntax/ClassProperties.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import React from 'react'
import React, { Component, PropTypes } from 'react'

export default class extends Component {
static propTypes = {
onReady: PropTypes.func.isRequired
}

export default class extends React.Component {
users = [
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
{ id: 4, name: '4' }
];

componentDidMount() {
this.props.onReady()
}

render() {
return (
<div id="feature-class-properties">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import ClassProperties from './ClassProperties';
describe('class properties', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<ClassProperties />, div);
return new Promise(resolve => {
ReactDOM.render(<ClassProperties onReady={resolve} />, div);
});
});
});
20 changes: 11 additions & 9 deletions fixtures/kitchensink/src/features/syntax/ComputedProperties.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { Component, PropTypes } from 'react'

function load(prefix) {
return [
Expand All @@ -9,21 +9,23 @@ function load(prefix) {
];
}

export default class extends React.Component {
export default class extends Component {
static propTypes = {
onReady: PropTypes.func.isRequired
}

constructor(props) {
super(props);

this.done = () => {};
this.props.setCallWhenDone && this.props.setCallWhenDone((done) => {
this.done = done;
});

this.state = { users: [] };
}

async componentDidMount() {
const users = load('user_');
this.setState({ users }, () => this.done());
this.setState({ users });
}

componentDidUpdate() {
this.props.onReady();
}

render() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import ComputedProperties from './ComputedProperties';
describe('computed properties', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<ComputedProperties />, div);
return new Promise(resolve => {
ReactDOM.render(<ComputedProperties onReady={resolve} />, div);
});
});
});
Loading

0 comments on commit f2df11d

Please sign in to comment.