An open API service indexing awesome lists of open source software.

https://github.com/kaosat-dev/react-page-objects

Page Object pattern for testing React components
https://github.com/kaosat-dev/react-page-objects

Last synced: about 1 year ago
JSON representation

Page Object pattern for testing React components

Awesome Lists containing this project

README

          

# React Page Objects

[React](http://facebook.github.io/react/) [page objects](https://code.google.com/p/selenium/wiki/PageObjects) make it easy to test [react](http://facebook.github.io/react/) components.

React gives you some useful utilities for testing React components however they lead to verbose code that clutters your tests.

```js
var TestUtils = require("react/addons").addons.TestUtils;

var element = TestUtils.renderIntoDocument();
var emailNode = element.email.getDOMNode();

expect(emailNode.value).to.equal("foo@bar.com");

element.password.getDOMNode().value = "bar@baz.com";
TestUtils.Simulate.change(element.password.getDOMNode(), {
target: {
value: "password"
}
});

TestUtils.Simulate.click(element.login.getDOMNode());
```

React Page Objects hides this complexity by providing a simpler API

```
var page = new PageObject();

expect(page.email.value).to.equal("foo@bar.com");
page.email.value = "bar@baz.com";
page.login.click();
```

##Tutorial

Say you have a login page built in React you want to test

```js
var LoginPage = React.createClass({
render: function () {
return (






);
},
login: function () {
AuthService.authenticate(this.state.email, this.state.password);
},
onEmailChanged: function (e) {
this.setState({ email: e.target.value });
},
onPasswordChanged: function () {
this.setState({ password: this.refs.password.getDOMNode().value });
},
getInitialState: function () {
return {
email: "",
password: ""
};
}
});
```

To easily reference specific elements within the component, you should add [refs](http://facebook.github.io/react/docs/more-about-refs.html) to them.

If you then pass an instance of the component into a page object, any refs will be accessible. You can then get the values of the elements and simulate events (e.g. click, select, etc).

```js
var page = new PageObject();

page.email.value = "foo@bar.com";
page.password.value = "password";
page.login.click();
```

You can also create a custom type for a page using ``PageObject#extend``

```js
var LoginPageObject = PageObject.extend({
getComponent: function () {
return ;
},
loginAs: function (email, password) {
this.email.value = "foo@bar.com";
this.password.value = "password";
this.login.click();
}
});

var page = new LoginPageObject();

page.loginAs("foo@bar.com", "password");
```

The ``elements`` hash map allows you to specify the page object type of any [refs](http://facebook.github.io/react/docs/more-about-refs.html) allowing you to build more complex pages. They key in the ``elements`` is the name of the [ref](http://facebook.github.io/react/docs/more-about-refs.html) and the value is the page object type.

```js
var NewsFeedItem = React.createClass({
render: function () {
return (



{this.props.item.title}


{this.props.item.body}


);
}
});

var NewsFeedItemPageObject = PageObject.extend({
elements: {
user: PageObject
},
getComponent: function (props) {
return ;
}
});

var User = React.createClass({
render: function () {
return (


{this.props.user.name}

);
}
});

var item = new NewsFeedItemPageObject({
item: {
user: { name: "Foo Bar" },
title: "Foo",
body: "Lorum Ipsum"
}
});

expect(item.title.value).to.equal("Foo");
expect(item.user.name.value).to.equal("Foo Bar");
```

If you have an array of page objects, you should add a ref to the parent element and then in elements hash the value should be an array containing the page object type.

```js
var NewsFeed = React.createClass({
render: function () {
return (



{this.state.items.map(function (item) {
return ;
})}


);
},
getInitialState: function () {
return {
items: NewsFeedService.getNewsFeedItemsFor(this.props.user)
};
}
});

var NewsFeedPageObject = PageObject.extend({
elements: {
items: [NewsFeedItemPageObject]
},
getComponent: function (props) {
return ;
}
});

var newsFeed = new NewsFeedPageObject({
user: "foo"
});

expect(newsFeed.items).to.not.be.empty;
expect(newsFeed.items.get(1).user.name.value).to.equal("foo");
```