Merge pull request #4341 from hashicorp/feature/more-acceptance-tests

UI - More acceptance tests
This commit is contained in:
John Cowen 2018-07-06 11:03:25 +01:00 committed by GitHub
commit 865a20c03e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 536 additions and 254 deletions

View File

@ -13,37 +13,27 @@ You will need the following things properly installed on your computer.
## Installation
* `git clone <repository-url>` this repository
* `cd ui`
* `git clone https://github.com/hashicorp/consul.git` this repository
* `cd ui-v2`
* `yarn install`
## Running / Development
* `yarn run start`
* `make start-api` or `yarn start:api` (this starts a Consul API double running
on http://localhost:3000)
* `make start` or `yarn start` to start the ember app that connects to the
above API double
* Visit your app at [http://localhost:4200](http://localhost:4200).
* Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
### Code Generators
Make use of the many generators for code, try `ember help generate` for more details
### Running Tests
* `ember test`
* `ember test --server`
You do not need to run `make start-api`/`yarn run start:api` to run the tests
### Building
* `ember build` (development)
* `ember build --environment production` (production)
### Deploying
## Further Reading / Useful Links
* [ember.js](https://emberjs.com/)
* [ember-cli](https://ember-cli.com/)
* Development Browser Extensions
* [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
* [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
* `make test` or `yarn run test`
* `make test-view` or `yarn run test:view` to view the tests running in Chrome

View File

@ -35,7 +35,7 @@
{{# if (and (not create) (not-eq item.ID 'anonymous')) }}
{{#confirmation-dialog message='Are you sure you want to delete this ACL token?'}}
{{#block-slot 'action' as |confirm|}}
<button type="button" class="type-delete" {{action confirm 'delete' item parent}}>Delete</button>
<button type="button" data-test-delete class="type-delete" {{action confirm 'delete' item parent}}>Delete</button>
{{/block-slot}}
{{#block-slot 'dialog' as |execute cancel message|}}
<p>

View File

@ -1,7 +1,7 @@
{{#app-view class="acl edit" loading=isLoading}}
{{#block-slot 'breadcrumbs'}}
<ol>
<li><a href={{href-to 'dc.acls'}}>All Tokens</a></li>
<li><a data-test-back href={{href-to 'dc.acls'}}>All Tokens</a></li>
</ol>
{{/block-slot}}
{{#block-slot 'header'}}
@ -35,7 +35,7 @@
<button type="button" {{ action "clone" item }}>Clone token</button>
{{#confirmation-dialog message='Are you sure you want to use this ACL token?'}}
{{#block-slot 'action' as |confirm|}}
<button type="button" {{ action confirm 'use' item }}>Use token</button>
<button data-test-use type="button" {{ action confirm 'use' item }}>Use token</button>
{{/block-slot}}
{{#block-slot 'dialog' as |execute cancel message|}}
<p>

View File

@ -5,7 +5,7 @@
</h1>
{{/block-slot}}
{{#block-slot 'actions'}}
<a href="{{href-to 'dc.acls.create'}}" class="type-create">Create</a>
<a data-test-create href="{{href-to 'dc.acls.create'}}" class="type-create">Create</a>
{{/block-slot}}
{{#block-slot 'toolbar'}}
{{#if (gt items.length 0) }}

View File

@ -64,7 +64,7 @@
{{# if (and item.ID (not-eq item.ID 'anonymous')) }}
{{#confirmation-dialog message='Are you sure you want to delete this Intention?'}}
{{#block-slot 'action' as |confirm|}}
<button type="button" class="type-delete" {{action confirm 'delete' item parent}}>Delete</button>
<button data-test-delete type="button" class="type-delete" {{action confirm 'delete' item parent}}>Delete</button>
{{/block-slot}}
{{#block-slot 'dialog' as |execute cancel message|}}
<p>

View File

@ -1,7 +1,7 @@
{{#app-view class="acl edit" loading=isLoading}}
{{#block-slot 'breadcrumbs'}}
<ol>
<li><a href={{href-to 'dc.intentions'}}>All Intentions</a></li>
<li><a data-test-back href={{href-to 'dc.intentions'}}>All Intentions</a></li>
</ol>
{{/block-slot}}
{{#block-slot 'header'}}

View File

@ -5,7 +5,7 @@
</h1>
{{/block-slot}}
{{#block-slot 'actions'}}
<a href="{{href-to 'dc.intentions.create'}}" class="type-create">Create</a>
<a data-test-create href="{{href-to 'dc.intentions.create'}}" class="type-create">Create</a>
{{/block-slot}}
{{#block-slot 'toolbar'}}
{{#if (gt items.length 0) }}
@ -27,7 +27,7 @@
{{/block-slot}}
{{#block-slot 'row'}}
<td class="source" data-test-intention="{{item.ID}}">
<a href={{href-to 'dc.intentions.edit' item.ID}}>
<a href={{href-to 'dc.intentions.edit' item.ID}} data-test-intention-source="{{item.SourceName}}">
{{#if (eq item.SourceName '*') }}
All Services (*)
{{else}}
@ -35,10 +35,10 @@
{{/if}}
</a>
</td>
<td class="intent-{{item.Action}}">
<td class="intent-{{item.Action}}" data-test-intention-action="{{item.Action}}">
<strong>{{item.Action}}</strong>
</td>
<td class="destination">
<td class="destination" data-test-intention-destination="{{item.DestinationName}}">
{{#if (eq item.DestinationName '*') }}
All Services (*)
{{else}}
@ -58,7 +58,7 @@
<a href={{href-to 'dc.intentions.edit' item.ID}}>Edit</a>
</li>
<li>
<a onclick={{action confirm 'delete' item}}>Delete</a>
<a data-test-delete onclick={{action confirm 'delete' item}}>Delete</a>
</li>
</ul>
{{/action-group}}

View File

@ -33,7 +33,7 @@
<button type="reset" {{ action "cancel" item parent}}>Cancel changes</button>
{{#confirmation-dialog message='Are you sure you want to delete this key?'}}
{{#block-slot 'action' as |confirm|}}
<button type="button" class="type-delete" {{action confirm 'delete' item parent}}>Delete</button>
<button data-test-delete type="button" class="type-delete" {{action confirm 'delete' item parent}}>Delete</button>
{{/block-slot}}
{{#block-slot 'dialog' as |execute cancel message|}}
<p>

View File

@ -1,7 +1,7 @@
{{#app-view class="kv edit" loading=isLoading}}
{{#block-slot 'breadcrumbs'}}
<ol>
<li><a href={{href-to 'dc.kv.index'}}>Key / Values</a></li>
<li><a data-test-back href={{href-to 'dc.kv.index'}}>Key / Values</a></li>
{{#if (not-eq parent.Key '/') }}
{{#each (slice 0 -1 (split parent.Key '/')) as |breadcrumb index|}}
<li><a href={{href-to 'dc.kv.folder' (join '/' (append (slice 0 (add index 1) (split parent.Key '/')) ''))}}>{{breadcrumb}}</a></li>

View File

@ -27,9 +27,9 @@
{{/block-slot}}
{{#block-slot 'actions'}}
{{#if (not-eq parent.Key '/') }}
<a href="{{href-to 'dc.kv.create' parent.Key}}" class="type-create">Create</a>
<a data-test-create href="{{href-to 'dc.kv.create' parent.Key}}" class="type-create">Create</a>
{{else}}
<a href="{{href-to 'dc.kv.root-create'}}" class="type-create">Create</a>
<a data-test-create href="{{href-to 'dc.kv.root-create'}}" class="type-create">Create</a>
{{/if}}
{{/block-slot}}
{{#block-slot 'content'}}

View File

@ -37,7 +37,7 @@
<td>
{{#confirmation-dialog message='Are you sure you want to invalidate this session?'}}
{{#block-slot 'action' as |confirm|}}
<button type="button" class="type-delete" {{action confirm 'invalidateSession' item}}>Invalidate</button>
<button data-test-delete type="button" class="type-delete" {{action confirm 'invalidateSession' item}}>Invalidate</button>
{{/block-slot}}
{{#block-slot 'dialog' as |execute cancel message|}}
<p>

View File

@ -1,7 +1,7 @@
{{#app-view class="node show"}}
{{#block-slot 'breadcrumbs'}}
<ol>
<li><a href={{href-to 'dc.nodes'}}>All Nodes</a></li>
<li><a data-test-back href={{href-to 'dc.nodes'}}>All Nodes</a></li>
</ol>
{{/block-slot}}
{{#block-slot 'header'}}

View File

@ -1,7 +1,7 @@
{{#app-view class="service show"}}
{{#block-slot 'breadcrumbs'}}
<ol>
<li><a href={{href-to 'dc.services'}}>All Services</a></li>
<li><a data-test-back href={{href-to 'dc.services'}}>All Services</a></li>
</ol>
{{/block-slot}}
{{#block-slot 'header'}}

View File

@ -2,7 +2,7 @@
"name": "consul-ui",
"version": "2.2.0",
"private": true,
"description": "The web ui for Consul, by HashiCorp.",
"description": "The web UI for Consul, by HashiCorp.",
"directories": {
"doc": "doc",
"test": "tests"

View File

@ -1,5 +1,5 @@
@setupApplicationTest
Feature: dc / components /acl filter: Acl Filter
Feature: components / acl filter: Acl Filter
In order to find the acl token I'm looking for easier
As a user
I should be able to filter by type and freetext search tokens by name and token

View File

@ -0,0 +1,55 @@
@setupApplicationTest
Feature: components / intention filter: Intention Filter
In order to find the intention I'm looking for easier
As a user
I should be able to filter by 'policy' (allow/deny) and freetext search tokens by source and destination
Scenario: Filtering [Model]
Given 1 datacenter model with the value "dc-1"
And 2 [Model] models
When I visit the [Page] page for yaml
---
dc: dc-1
---
Then the url should be [Url]
Then I see 2 [Model] models
And I see allIsSelected on the filter
When I click allow on the filter
Then I see allowIsSelected on the filter
And I see 1 [Model] model
And I see 1 [Model] model with the action "allow"
When I click deny on the filter
Then I see denyIsSelected on the filter
And I see 1 [Model] model
And I see 1 [Model] model with the action "deny"
When I click all on the filter
Then I see 2 [Model] models
Then I see allIsSelected on the filter
Then I fill in with yaml
---
s: alarm
---
And I see 1 [Model] model
And I see 1 [Model] model with the source "alarm"
Then I fill in with yaml
---
s: feed
---
And I see 1 [Model] model
And I see 1 [Model] model with the destination "feed"
Then I fill in with yaml
---
s: transmitter
---
And I see 2 [Model] models
And I see 1 [Model] model with the source "transmitter"
And I see 1 [Model] model with the destination "transmitter"
Where:
---------------------------------------------
| Model | Page | Url |
| intention | intentions | /dc-1/intentions |
---------------------------------------------

View File

@ -1,5 +1,5 @@
@setupApplicationTest
Feature: Text input
Feature: components / text-input: Text input
Background:
Given 1 datacenter model with the value "dc-1"
Scenario:

View File

@ -1,17 +0,0 @@
@setupApplicationTest
Feature: dc / acls / delete: ACL Delete
Scenario: Delete ACL
Given 1 datacenter model with the value "datacenter"
And 1 acl model from yaml
---
Name: something
ID: key
---
When I visit the acls page for yaml
---
dc: datacenter
---
And I click actions on the acls
And I click delete on the acls
And I click confirmDelete on the acls
Then a PUT request is made to "/v1/acl/destroy/key?dc=datacenter"

View File

@ -0,0 +1,40 @@
@setupApplicationTest
Feature: dc / acls / use: Using an ACL token
Background:
Given 1 datacenter model with the value "datacenter"
And 1 acl model from yaml
---
ID: token
---
Scenario: Using an ACL token from the listing page
When I visit the acls page for yaml
---
dc: datacenter
---
Then I have settings like yaml
---
token: ~
---
And I click actions on the acls
And I click use on the acls
And I click confirmUse on the acls
Then I have settings like yaml
---
token: token
---
Scenario: Using an ACL token from the detail page
When I visit the acl page for yaml
---
dc: datacenter
acl: token
---
Then I have settings like yaml
---
token: ~
---
And I click use
And I click confirmUse
Then I have settings like yaml
---
token: token
---

View File

@ -1,16 +0,0 @@
@setupApplicationTest
Feature: dc / kvs / delete: KV Delete
Scenario: Delete ACL
Given 1 datacenter model with the value "datacenter"
And 1 kv model from yaml
---
- key-name
---
When I visit the kvs page for yaml
---
dc: datacenter
---
And I click actions on the kvs
And I click delete on the kvs
And I click confirmDelete on the kvs
Then a DELETE request is made to "/v1/kv/key-name?dc=datacenter"

View File

@ -0,0 +1,26 @@
@setupApplicationTest
Feature: dc / nodes / sessions / invalidate: Invalidate Lock Sessions
In order to invalidate a lock session
As a user
I should be able to invalidate a lock session by clicking a button and confirming
Scenario: Given 2 lock sessions
Given 1 datacenter model with the value "dc1"
And 1 node model from yaml
---
- ID: node-0
---
And 2 session models from yaml
---
- ID: 7bbbd8bb-fff3-4292-b6e3-cfedd788546a
- ID: 7ccd0bd7-a5e0-41ae-a33e-ed3793d803b2
---
When I visit the node page for yaml
---
dc: dc1
node: node-0
---
And I click lockSessions on the tabs
Then I see lockSessionsIsSelected on the tabs
And I click delete on the sessions
And I click confirmDelete on the sessions
Then a PUT request is made to "/v1/session/destroy/7bbbd8bb-fff3-4292-b6e3-cfedd788546a?dc=dc1"

View File

@ -1,5 +1,5 @@
@setupApplicationTest
Feature: dc / nodes / sessions /list: List Lock Sessions
Feature: dc / nodes / sessions / list: List Lock Sessions
In order to get information regarding lock sessions
As a user
I should be able to see a listing of lock sessions with necessary information under the lock sessions tab for a node

View File

@ -0,0 +1,34 @@
@setupApplicationTest
Feature: deleting: Deleting from the listing and the detail page with confirmation
Scenario: Deleting a [Model] from the [Model] listing page
Given 1 datacenter model with the value "datacenter"
And 1 [Model] model from json
---
[Data]
---
When I visit the [Model]s page for yaml
---
dc: datacenter
---
And I click actions on the [Model]s
And I click delete on the [Model]s
And I click confirmDelete on the [Model]s
Then a [Method] request is made to "[URL]"
When I visit the [Model] page for yaml
---
dc: datacenter
[Slug]
---
And I click delete
And I click confirmDelete
Then a [Method] request is made to "[URL]"
Where:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Model | Method | URL | Data | Slug |
| acl | PUT | /v1/acl/destroy/something?dc=datacenter | {"Name": "something", "ID": "something"} | acl: something |
| kv | DELETE | /v1/kv/key-name?dc=datacenter | ["key-name"] | kv: key-name |
| intention | DELETE | /v1/connect/intentions/ee52203d-989f-4f7a-ab5a-2bef004164ca?dc=datacenter | {"SourceName": "name", "ID": "ee52203d-989f-4f7a-ab5a-2bef004164ca"} | intention: ee52203d-989f-4f7a-ab5a-2bef004164ca |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ignore
Scenario: Sort out the wide tables ^
Then ok

View File

@ -8,36 +8,74 @@ Feature: Page Navigation
dc: dc-1
---
Then the url should be /dc-1/services
Scenario: Clicking [Link] in the navigation takes me to [Url]
Scenario: Clicking [Link] in the navigation takes me to [URL]
When I visit the services page for yaml
---
dc: dc-1
---
When I click [Link] on the navigation
Then the url should be [Url]
Then the url should be [URL]
Where:
--------------------------------------
| Link | Url |
----------------------------------------
| Link | URL |
| nodes | /dc-1/nodes |
| kvs | /dc-1/kv |
| acls | /dc-1/acls |
| intentions | /dc-1/intentions |
| settings | /settings |
--------------------------------------
Scenario: Clicking a [Item] in the [Model] listing
----------------------------------------
Scenario: Clicking a [Item] in the [Model] listing and back again
When I visit the [Model] page for yaml
---
dc: dc-1
---
When I click [Item] on the [Model]
Then the url should be [Url]
Then the url should be [URL]
And I click "[data-test-back]"
Then the url should be [Back]
Where:
--------------------------------------------------------
| Item | Model | Url |
| service | services | /dc-1/services/service-0 |
| node | nodes | /dc-1/nodes/node-0 |
| kv | kvs | /dc-1/kv/necessitatibus-0/edit |
| acl | acls | /dc-1/acls/anonymous |
--------------------------------------------------------
--------------------------------------------------------------------------------------------------------
| Item | Model | URL | Back |
| service | services | /dc-1/services/service-0 | /dc-1/services |
| node | nodes | /dc-1/nodes/node-0 | /dc-1/nodes |
| kv | kvs | /dc-1/kv/necessitatibus-0/edit | /dc-1/kv |
| acl | acls | /dc-1/acls/anonymous | /dc-1/acls |
| intention | intentions | /dc-1/intentions/ee52203d-989f-4f7a-ab5a-2bef004164ca | /dc-1/intentions |
--------------------------------------------------------------------------------------------------------
Scenario: Clicking a [Item] in the [Model] listing and canceling
When I visit the [Model] page for yaml
---
dc: dc-1
---
When I click [Item] on the [Model]
Then the url should be [URL]
And I click "[type=reset]"
Then the url should be [Back]
Where:
--------------------------------------------------------------------------------------------------------
| Item | Model | URL | Back |
| kv | kvs | /dc-1/kv/necessitatibus-0/edit | /dc-1/kv |
| acl | acls | /dc-1/acls/anonymous | /dc-1/acls |
| intention | intentions | /dc-1/intentions/ee52203d-989f-4f7a-ab5a-2bef004164ca | /dc-1/intentions |
--------------------------------------------------------------------------------------------------------
@ignore
Scenario: Clicking a kv in the kvs listing, without depending on the salt ^
Scenario: Clicking items in the listings, without depending on the salt ^
Then ok
Scenario: Clicking create in the [Model] listing
When I visit the [Model] page for yaml
---
dc: dc-1
---
When I click create
Then the url should be [URL]
And I click "[data-test-back]"
Then the url should be [Back]
Where:
------------------------------------------------------------------------
| Item | Model | URL | Back |
| kv | kvs | /dc-1/kv/create | /dc-1/kv |
| acl | acls | /dc-1/acls/create | /dc-1/acls |
| intention | intentions | /dc-1/intentions/create | /dc-1/intentions |
------------------------------------------------------------------------
Scenario: Using I click on should change the currentPage ^
Then ok

View File

@ -7,6 +7,10 @@ Feature: settings / update: Update Settings
Given 1 datacenter model with the value "datacenter"
When I visit the settings page
Then the url should be /settings
Then I have settings like yaml
---
token: ~
---
And I submit
Then I have settings like yaml
---

View File

@ -1,4 +1,4 @@
import steps from '../../steps';
import steps from '../steps';
// step definitions that are shared between features should be moved to the
// tests/acceptance/steps/steps.js file

View File

@ -0,0 +1,10 @@
import steps from '../../../steps';
// step definitions that are shared between features should be moved to the
// tests/acceptance/steps/steps.js file
export default function(assert) {
return steps(assert).then('I should find a file', function() {
assert.ok(true, this.step);
});
}

View File

@ -0,0 +1,11 @@
import steps from './steps';
// step definitions that are shared between features should be moved to the
// tests/acceptance/steps/steps.js file
export default function(assert) {
return steps(assert)
.then('I should find a file', function() {
assert.ok(true, this.step);
});
}

View File

@ -13,11 +13,12 @@ Feature: submit blank
And I submit
Then the url should be /datacenter/[Slug]/create
Where:
------------------
--------------------------
| Model | Slug |
| kv | kv |
| acl | acls |
------------------
| intention | intentions |
--------------------------
@ignore
Scenario: The button is disabled
Then ok

View File

@ -0,0 +1,11 @@
export default function(clickable, is) {
return function(obj) {
return {
...obj,
...{
cancel: clickable('[type=reset]'),
cancelIsEnabled: is(':not(:disabled)', '[type=reset]'),
},
};
};
}

View File

@ -0,0 +1,11 @@
export default function(clickable, is) {
return function(obj) {
return {
...obj,
...{
create: clickable('[data-test-create]'),
createIsEnabled: is(':not(:disabled)', '[data-test-create]'),
},
};
};
}

View File

@ -0,0 +1,11 @@
export default function(clickable) {
return function(obj) {
return {
...obj,
...{
delete: clickable('[data-test-delete]'),
confirmDelete: clickable('button.type-delete'),
},
};
};
}

View File

@ -0,0 +1,11 @@
export default function(clickable, is) {
return function(obj) {
return {
...obj,
...{
submit: clickable('[type=submit]'),
submitIsEnabled: is(':not(:disabled)', '[type=submit]'),
},
};
};
}

View File

@ -1,27 +1,48 @@
import { create, clickable, is, attribute, collection, text } from 'ember-cli-page-object';
import { visitable } from 'consul-ui/tests/lib/page-object/visitable';
import createDeletable from 'consul-ui/tests/lib/page-object/createDeletable';
import createSubmitable from 'consul-ui/tests/lib/page-object/createSubmitable';
import createCreatable from 'consul-ui/tests/lib/page-object/createCreatable';
import createCancelable from 'consul-ui/tests/lib/page-object/createCancelable';
import page from 'consul-ui/tests/pages/components/page';
import radiogroup from 'consul-ui/tests/lib/page-object/radiogroup';
import index from 'consul-ui/tests/pages/index';
import dcs from 'consul-ui/tests/pages/dc';
import settings from 'consul-ui/tests/pages/settings';
import catalogFilter from 'consul-ui/tests/pages/components/catalog-filter';
import services from 'consul-ui/tests/pages/dc/services/index';
import service from 'consul-ui/tests/pages/dc/services/show';
import nodes from 'consul-ui/tests/pages/dc/nodes/index';
import node from 'consul-ui/tests/pages/dc/nodes/show';
import kvs from 'consul-ui/tests/pages/dc/kv/index';
import kv from 'consul-ui/tests/pages/dc/kv/edit';
import aclFilter from 'consul-ui/tests/pages/components/acl-filter';
import acls from 'consul-ui/tests/pages/dc/acls/index';
import acl from 'consul-ui/tests/pages/dc/acls/edit';
import intentionFilter from 'consul-ui/tests/pages/components/intention-filter';
import intentions from 'consul-ui/tests/pages/dc/intentions/index';
import intention from 'consul-ui/tests/pages/dc/intentions/edit';
const deletable = createDeletable(clickable);
const submitable = createSubmitable(clickable, is);
const creatable = createCreatable(clickable, is);
const cancelable = createCancelable(clickable, is);
export default {
index,
dcs,
settings,
services,
service,
nodes,
node,
kvs,
kv,
acls,
acl,
intention,
index: create(index(visitable, collection)),
dcs: create(dcs(visitable, clickable, attribute, collection)),
services: create(services(visitable, clickable, attribute, collection, page, catalogFilter)),
service: create(service(visitable, attribute, collection, text, catalogFilter)),
nodes: create(nodes(visitable, clickable, attribute, collection, catalogFilter)),
node: create(node(visitable, deletable, clickable, attribute, collection, radiogroup)),
kvs: create(kvs(visitable, deletable, creatable, clickable, attribute, collection)),
kv: create(kv(visitable, submitable, deletable, cancelable, clickable)),
acls: create(acls(visitable, deletable, creatable, clickable, attribute, collection, aclFilter)),
acl: create(acl(visitable, submitable, deletable, cancelable, clickable)),
intentions: create(
intentions(visitable, deletable, creatable, clickable, attribute, collection, intentionFilter)
),
intention: create(intention(visitable, submitable, deletable, cancelable)),
settings: create(settings(visitable, submitable)),
};

View File

@ -0,0 +1,9 @@
import { triggerable } from 'ember-cli-page-object';
import radiogroup from 'consul-ui/tests/lib/page-object/radiogroup';
export default {
...radiogroup('action', ['', 'allow', 'deny']),
...{
scope: '[data-test-intention-filter]',
search: triggerable('keypress', '[name="s"]'),
},
};

View File

@ -1,6 +1,6 @@
import { clickable } from 'ember-cli-page-object';
export default {
navigation: ['services', 'nodes', 'kvs', 'acls', 'docs', 'settings'].reduce(
navigation: ['services', 'nodes', 'kvs', 'acls', 'intentions', 'docs', 'settings'].reduce(
function(prev, item, i, arr) {
const key = item;
return Object.assign({}, prev, {

View File

@ -1,9 +1,12 @@
import { create, visitable, attribute, collection, clickable } from 'ember-cli-page-object';
export default create({
export default function(visitable, clickable, attribute, collection) {
return {
visit: visitable('/:dc/'),
dcs: collection('[data-test-datacenter-picker]'),
showDatacenters: clickable('[data-test-datacenter-selected]'),
selectedDc: attribute('data-test-datacenter-selected', '[data-test-datacenter-selected]'),
selectedDatacenter: attribute('data-test-datacenter-selected', '[data-test-datacenter-selected]'),
});
selectedDatacenter: attribute(
'data-test-datacenter-selected',
'[data-test-datacenter-selected]'
),
};
}

View File

@ -1,11 +1,11 @@
import { create, clickable, triggerable, is } from 'ember-cli-page-object';
import { visitable } from 'consul-ui/tests/lib/page-object/visitable';
export default create({
// custom visitable
export default function(visitable, submitable, deletable, cancelable, clickable) {
return submitable(
cancelable(
deletable({
visit: visitable(['/:dc/acls/:acl', '/:dc/acls/create']),
// fillIn: fillable('input, textarea, [contenteditable]'),
name: triggerable('keypress', '[name="name"]'),
submit: clickable('[type=submit]'),
submitIsEnabled: is(':not(:disabled)', '[type=submit]'),
});
use: clickable('[data-test-use]'),
confirmUse: clickable('button.type-delete'),
})
)
);
}

View File

@ -1,14 +1,16 @@
import { create, visitable, collection, attribute, clickable } from 'ember-cli-page-object';
import filter from 'consul-ui/tests/pages/components/acl-filter';
export default create({
export default function(visitable, deletable, creatable, clickable, attribute, collection, filter) {
return creatable({
visit: visitable('/:dc/acls'),
acls: collection('[data-test-tabular-row]', {
acls: collection(
'[data-test-tabular-row]',
deletable({
name: attribute('data-test-acl', '[data-test-acl]'),
acl: clickable('a'),
actions: clickable('label'),
delete: clickable('[data-test-delete]'),
confirmDelete: clickable('button.type-delete'),
}),
use: clickable('[data-test-use]'),
confirmUse: clickable('button.type-delete'),
})
),
filter: filter,
});
});
}

View File

@ -1,8 +1,9 @@
import { create, clickable } from 'ember-cli-page-object';
import { visitable } from 'consul-ui/tests/lib/page-object/visitable';
export default create({
// custom visitable
export default function(visitable, submitable, deletable, cancelable) {
return submitable(
cancelable(
deletable({
visit: visitable(['/:dc/intentions/:intention', '/:dc/intentions/create']),
submit: clickable('[type=submit]'),
});
})
)
);
}

View File

@ -0,0 +1,19 @@
export default function(visitable, deletable, creatable, clickable, attribute, collection, filter) {
return creatable({
visit: visitable('/:dc/intentions'),
intentions: collection(
'[data-test-tabular-row]',
deletable({
source: attribute('data-test-intention-source', '[data-test-intention-source]'),
destination: attribute(
'data-test-intention-destination',
'[data-test-intention-destination]'
),
action: attribute('data-test-intention-action', '[data-test-intention-action]'),
intention: clickable('a'),
actions: clickable('label'),
})
),
filter: filter,
});
}

View File

@ -1,11 +1,9 @@
import { create, clickable, is } from 'ember-cli-page-object';
import { visitable } from 'consul-ui/tests/lib/page-object/visitable';
export default create({
// custom visitable
export default function(visitable, submitable, deletable, cancelable) {
return submitable(
cancelable(
deletable({
visit: visitable(['/:dc/kv/:kv/edit', '/:dc/kv/create'], str => str),
// fillIn: fillable('input, textarea, [contenteditable]'),
// name: triggerable('keypress', '[name="additional"]'),
submit: clickable('[type=submit]'),
submitIsEnabled: is(':not(:disabled)', '[type=submit]'),
});
})
)
);
}

View File

@ -1,12 +1,13 @@
import { create, visitable, collection, attribute, clickable } from 'ember-cli-page-object';
export default create({
export default function(visitable, deletable, creatable, clickable, attribute, collection) {
return creatable({
visit: visitable('/:dc/kv'),
kvs: collection('[data-test-tabular-row]', {
kvs: collection(
'[data-test-tabular-row]',
deletable({
name: attribute('data-test-kv', '[data-test-kv]'),
kv: clickable('a'),
actions: clickable('label'),
delete: clickable('[data-test-delete]'),
confirmDelete: clickable('button.type-delete'),
}),
});
})
),
});
}

View File

@ -1,11 +1,10 @@
import { create, visitable, collection, attribute, clickable } from 'ember-cli-page-object';
import filter from 'consul-ui/tests/pages/components/catalog-filter';
export default create({
export default function(visitable, clickable, attribute, collection, filter) {
return {
visit: visitable('/:dc/nodes'),
nodes: collection('[data-test-node]', {
name: attribute('data-test-node'),
node: clickable('header a'),
}),
filter: filter,
});
};
}

View File

@ -1,7 +1,5 @@
import { create, visitable, collection, attribute } from 'ember-cli-page-object';
import radiogroup from 'consul-ui/tests/lib/page-object/radiogroup';
export default create({
export default function(visitable, deletable, clickable, attribute, collection, radiogroup) {
return {
visit: visitable('/:dc/nodes/:node'),
tabs: radiogroup('tab', ['health-checks', 'services', 'round-trip-time', 'lock-sessions']),
healthchecks: collection('[data-test-node-healthcheck]', {
@ -10,7 +8,11 @@ export default create({
services: collection('#services [data-test-tabular-row]', {
port: attribute('data-test-service-port', '.port'),
}),
sessions: collection('#lock-sessions [data-test-tabular-row]', {
sessions: collection(
'#lock-sessions [data-test-tabular-row]',
deletable({
TTL: attribute('data-test-session-ttl', '[data-test-session-ttl]'),
}),
});
})
),
};
}

View File

@ -1,9 +1,5 @@
import { create, visitable, collection, attribute, clickable } from 'ember-cli-page-object';
import page from 'consul-ui/tests/pages/components/page';
import filter from 'consul-ui/tests/pages/components/catalog-filter';
export default create({
export default function(visitable, clickable, attribute, collection, page, filter) {
return {
visit: visitable('/:dc/services'),
services: collection('[data-test-service]', {
name: attribute('data-test-service'),
@ -11,6 +7,6 @@ export default create({
}),
dcs: collection('[data-test-datacenter-picker]'),
navigation: page.navigation,
filter: filter,
});
};
}

View File

@ -1,7 +1,5 @@
import { create, visitable, collection, attribute, text } from 'ember-cli-page-object';
import filter from 'consul-ui/tests/pages/components/catalog-filter';
export default create({
export default function(visitable, attribute, collection, text, filter) {
return {
visit: visitable('/:dc/services/:service'),
nodes: collection('[data-test-node]', {
name: attribute('data-test-node'),
@ -15,4 +13,5 @@ export default create({
address: text('header strong'),
}),
filter: filter,
});
};
}

View File

@ -1,6 +1,6 @@
import { create, visitable, collection } from 'ember-cli-page-object';
export default create({
export default function(visitable, collection) {
return {
visit: visitable('/'),
dcs: collection('[data-test-datacenter-list]'),
});
};
}

View File

@ -1,6 +1,5 @@
import { create, visitable, clickable } from 'ember-cli-page-object';
export default create({
export default function(visitable, submitable) {
return submitable({
visit: visitable('/settings'),
submit: clickable('[type=submit]'),
});
});
}

View File

@ -5,6 +5,8 @@ import getDictionary from '@hashicorp/ember-cli-api-double/dictionary';
import pages from 'consul-ui/tests/pages';
import api from 'consul-ui/tests/helpers/api';
// const dont = `( don't| shouldn't| can't)?`;
const create = function(number, name, value) {
// don't return a promise here as
// I don't need it to wait
@ -83,6 +85,15 @@ export default function(assert) {
.when('I click "$selector"', function(selector) {
return click(selector);
})
// TODO: Probably nicer to think of better vocab than having the 'without " rule'
.when('I click (?!")$property(?!")', function(property) {
try {
return currentPage[property]();
} catch (e) {
console.error(e);
throw new Error(`The '${property}' property on the page object doesn't exist`);
}
})
.when('I click $prop on the $component', function(prop, component) {
// Collection
var obj;
@ -240,7 +251,9 @@ export default function(assert) {
assert.equal(len, num, `Expected ${num} ${model}s, saw ${len}`);
})
.then(['I see $num $model model with the $property "$value"'], function(
// TODO: I${ dont } see
.then([`I see $num $model model[s]? with the $property "$value"`], function(
// negate,
num,
model,
property,

View File

@ -82,8 +82,8 @@
js-yaml "^3.10.0"
"@hashicorp/consul-api-double@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@hashicorp/consul-api-double/-/consul-api-double-1.2.0.tgz#2cd2a991818e13e7b97803af3d62ec6c9cb83b28"
version "1.3.0"
resolved "https://registry.yarnpkg.com/@hashicorp/consul-api-double/-/consul-api-double-1.3.0.tgz#fded48ca4db1e63c66e39b4433b2169b6add69ed"
"@hashicorp/ember-cli-api-double@^1.3.0":
version "1.3.0"