Skip to content
This repository has been archived by the owner on Jan 3, 2019. It is now read-only.

Commit

Permalink
docs: add todo-mvc example
Browse files Browse the repository at this point in the history
  • Loading branch information
clebert committed Mar 4, 2018
1 parent 0012a47 commit 3b73a85
Show file tree
Hide file tree
Showing 15 changed files with 363 additions and 0 deletions.
Binary file added docs/examples/todo-mvc/images/label.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/todo-mvc/images/new-todo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/todo-mvc/images/page.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/todo-mvc/images/todo-app.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/todo-mvc/images/todo-list.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/todo-mvc/images/todo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/todo-mvc/images/toggle.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
104 changes: 104 additions & 0 deletions docs/examples/todo-mvc/index.js
@@ -0,0 +1,104 @@
const {FlexiblePageObject, FlexibleKey} = require('@pageobject/flexible');
const {PuppeteerAdapter} = require('@pageobject/flexible-puppeteer');
const {TestCase, equals} = require('@pageobject/reliable');

class TodoApp extends FlexiblePageObject {
get selector() {
return '.todoapp';
}

get newTodo() {
return this.select(NewTodo);
}

get todoList() {
return this.select(TodoList);
}
}

class NewTodo extends FlexiblePageObject {
get selector() {
return '.new-todo';
}
}

class TodoList extends FlexiblePageObject {
get selector() {
return '.todo-list';
}

get todos() {
return this.select(Todo);
}
}

class Todo extends FlexiblePageObject {
get selector() {
return 'li';
}

get label() {
return this.select(Label);
}

get toggle() {
return this.select(Toggle);
}
}

class Label extends FlexiblePageObject {
get selector() {
return 'label';
}
}

class Toggle extends FlexiblePageObject {
get selector() {
return '.toggle';
}

isSelected(operator = equals(true)) {
return this.getProperty('checked', operator);
}
}

function describe(testCase, todoApp) {
const todo1 = todoApp.todoList.todos.nth(1);
const todo2 = todoApp.todoList.todos.nth(2);

testCase
.perform(todoApp.navigateTo('http://todomvc.com/examples/react/#/'), 30)

.assert(todoApp.newTodo.hasFocus())

.perform(todoApp.newTodo.type('foo'))
.perform(todoApp.newTodo.sendKey(FlexibleKey.ENTER))
.assert(todo1.label.getRenderedText(equals('foo')))

.perform(todoApp.newTodo.type('bar'))
.perform(todoApp.newTodo.sendKey(FlexibleKey.ENTER))
.assert(todo2.label.getRenderedText(equals('bar')))

.assert(todo2.toggle.isSelected(equals(false)))
.perform(todo2.toggle.click())
.assert(todo2.toggle.isSelected());
}

(async () => {
const testCase = new TestCase(3);
const todoApp = new TodoApp(await PuppeteerAdapter.create());

try {
describe(testCase, todoApp);

await testCase.run();

console.log('OK');
} finally {
await todoApp.adapter.browser.close();
}
})().catch(error => {
console.error(error.toString());

process.exit(1);
});
38 changes: 38 additions & 0 deletions docs/examples/todo-mvc/index.md
@@ -0,0 +1,38 @@
# Example: TodoMVC

![page](./images/page.png)

## Page objects

- [`TodoApp`](./page-objects/1-todo-app.md)
- `TodoApp` > [`NewTodo`](./page-objects/2-new-todo.md)
- `TodoApp` > [`TodoList`](./page-objects/3-todo-list.md)
- `TodoApp` > `TodoList` > [`Todo`](./page-objects/4-todo.md)[ ]
- `TodoApp` > `TodoList` > `Todo`[ ] > [`Label`](./page-objects/5-label.md)
- `TodoApp` > `TodoList` > `Todo`[ ] > [`Toggle`](./page-objects/6-toggle.md)

## Test case

```js
function describe(testCase, todoApp) {
const todo1 = todoApp.todoList.todos.nth(1);
const todo2 = todoApp.todoList.todos.nth(2);

testCase
.perform(todoApp.navigateTo('http://todomvc.com/examples/react/#/'), 30)

.assert(todoApp.newTodo.hasFocus())

.perform(todoApp.newTodo.type('foo'))
.perform(todoApp.newTodo.sendKey(FlexibleKey.ENTER))
.assert(todo1.label.getRenderedText(equals('foo')))

.perform(todoApp.newTodo.type('bar'))
.perform(todoApp.newTodo.sendKey(FlexibleKey.ENTER))
.assert(todo2.label.getRenderedText(equals('bar')))

.assert(todo2.toggle.isSelected(equals(false)))
.perform(todo2.toggle.click())
.assert(todo2.toggle.isSelected());
}
```
21 changes: 21 additions & 0 deletions docs/examples/todo-mvc/page-objects/1-todo-app.md
@@ -0,0 +1,21 @@
# Page object: `TodoApp`

![todo-app](../images/todo-app.png)

## Choosing a CSS selector

```html
<html> <!-- No page object (implementation detail) -->
<body> <!-- No page object (implementation detail) -->
<section class="todoapp"> <!-- TodoApp -->
```

## Implementing the page object

```js
class TodoApp extends FlexiblePageObject {
get selector() {
return '.todoapp';
}
}
```
36 changes: 36 additions & 0 deletions docs/examples/todo-mvc/page-objects/2-new-todo.md
@@ -0,0 +1,36 @@
# Page object: `TodoApp` > `NewTodo`

![new-todo](../images/new-todo.png)

## Choosing a CSS selector

```html
<section class="todoapp"> <!-- TodoApp (relative root) -->
<div> <!-- No page object (implementation detail) -->
<header class="header"> <!-- No page object (implementation detail) -->
<input class="new-todo"> <!-- NewTodo -->
```

## Implementing the page object

```js
class NewTodo extends FlexiblePageObject {
get selector() {
return '.new-todo';
}
}
```

## Integrating the page object

```js
class TodoApp extends FlexiblePageObject {
get selector() {
return '.todoapp';
}

get newTodo() {
return this.select(NewTodo);
}
}
```
40 changes: 40 additions & 0 deletions docs/examples/todo-mvc/page-objects/3-todo-list.md
@@ -0,0 +1,40 @@
# Page object: `TodoApp` > `TodoList`

![todo-list](../images/todo-list.png)

## Choosing a CSS selector

```html
<section class="todoapp"> <!-- TodoApp (relative root) -->
<div> <!-- No page object (implementation detail) -->
<section class="main"> <!-- No page object (implementation detail) -->
<ul class="todo-list"> <!-- TodoList -->
```

## Implementing the page object

```js
class TodoList extends FlexiblePageObject {
get selector() {
return '.todo-list';
}
}
```

## Integrating the page object

```js
class TodoApp extends FlexiblePageObject {
get selector() {
return '.todoapp';
}

get newTodo() {
return this.select(NewTodo);
}

get todoList() {
return this.select(TodoList);
}
}
```
46 changes: 46 additions & 0 deletions docs/examples/todo-mvc/page-objects/4-todo.md
@@ -0,0 +1,46 @@
# Page object: `TodoApp` > `TodoList` > `Todo`[ ]

![todo](../images/todo.png)

## Choosing a CSS selector

```html
<ul class="todo-list"> <!-- TodoList (relative root) -->
<li> <!-- Todo -->
<li> <!-- Todo -->
....
```

## Implementing the page object

```js
class Todo extends FlexiblePageObject {
get selector() {
return 'li';
}
}
```

## Integrating the page object

```js
class TodoList extends FlexiblePageObject {
get selector() {
return '.todo-list';
}

get todos() {
return this.select(Todo);
}
}
```

## Using the page object

```js
todoApp.todoList.todos.nth(1);
```

```js
todoApp.todoList.todos.where(todo => todo.label.getRenderedText(equals('foo')));
```
35 changes: 35 additions & 0 deletions docs/examples/todo-mvc/page-objects/5-label.md
@@ -0,0 +1,35 @@
# Page object: `TodoApp` > `TodoList` > `Todo`[ ] > `Label`

![label](../images/label.png)

## Choosing a CSS selector

```html
<li> <!-- Todo (relative root) -->
<div class="view"> <!-- No page object (implementation detail) -->
<label> <!-- Label -->
```

## Implementing the page object

```js
class Label extends FlexiblePageObject {
get selector() {
return 'label';
}
}
```

## Integrating the page object

```js
class Todo extends FlexiblePageObject {
get selector() {
return 'li';
}

get label() {
return this.select(Label);
}
}
```
43 changes: 43 additions & 0 deletions docs/examples/todo-mvc/page-objects/6-toggle.md
@@ -0,0 +1,43 @@
# Page object: `TodoApp` > `TodoList` > `Todo`[ ] > `Toggle`

![toggle](../images/toggle.png)

## Choosing a CSS selector

```html
<li> <!-- Todo (relative root) -->
<div class="view"> <!-- No page object (implementation detail) -->
<input class="toggle" type="checkbox"> <!-- Toggle -->
```

## Implementing the page object

```js
class Toggle extends FlexiblePageObject {
get selector() {
return '.toggle';
}

isSelected(operator = equals(true)) {
return this.getProperty('checked', operator);
}
}
```

## Integrating the page object

```js
class Todo extends FlexiblePageObject {
get selector() {
return 'li';
}

get label() {
return this.select(Label);
}

get toggle() {
return this.select(Toggle);
}
}
```

0 comments on commit 3b73a85

Please sign in to comment.