Provides a super simple class-like wrapper around ember-cli-page-object.
Given a simple ToggleButton component that just toggles its active state with a template like so:
You can represent it and test like this:
import { module, test } from 'ember-qunit';
import PageObject, { clickable } from 'ember-classy-page-object';
import { findElement } from 'ember-classy-page-object/extend';
const ToggleButtonPage = PageObject.extend({
toggle: clickable('[data-test-toggle-button]'),
activeClass: 'is-active',
get isActive() {
return findElement(this, '[data-test-toggle-button]').classList.contains(this.activeClass);
}
});
module('toggle button');
test('can toggle', function(assert) {
const myToggleButton = new ToggleButtonPage();
myToggleButton.toggle();
assert.ok(myToggleButton.isActive, 'it toggled!');
});
If you later need to reuse a component, you can extend it to override properties:
const DoubleToggleButtonPage = PageObject.extend({
firstToggle: ToggleButtonPage.extend({
scope: '[data-test-first-toggle]'
}),
secondToggle: ToggleButtonPage.extend({
scope: '[data-test-second-toggle]',
activeClass: 'is-activated'
})
});
const myDoubleToggle = new DoubleToggleButtonPage();
myDoubleToggle.firstToggle.toggle();
// etc...
Extending deep merges the new definition into the previous definition. When you want to finally
use the page object, just call create
which finalizes the object.
Classy page object defaults to running in native-dom mode, meaning it sends native events and
uses native-dom helpers under the hood. Results from functions like findElement
and
findElementWithAssert
return actual elements, not jquery selectors. However, ember-cli-page-object
hasn't been able to get rid of the jquery dependency yet, so it's still possible to use jquery
selectors within page objects themselves. It is highly recommended that you avoid this to prevent
tying yourself to jquery in your tests, as Ember continues to remove the dependency in the future.
Classy page object re-exports all of the helpers from ember-cli-page-object with the exception of
getter
, you can now use native ES getters instead. The list of exports is as follows:
ember-classy-page-object
default as PageObject
alias
attribute
blurrable
clickOnText
clickable
contains
count
fillable
hasClass
is
isHidden
isPresent
isVisible
notHasClass
property
text
triggerable
value
visitable
ember-classy-page-object/extend
findElement
findElementWithAssert
buildSelector
fullScope
getContext
Some helpers have been overridden to make them mergeable and easier to use, such as collection
,
so it's highly recommended that you use these helpers from ember-classy-page-object
and not
from ember-cli-page-object
directly.
The collection helper in ember-cli-page-object
has some shortcomings, mostly the fact that it
requires users to call it as a function to generate an enumerable, and can only query directly by
index. It also confusingly refers to both the enumerable items, and their immediate parent (which is
why you must provide itemScope
and item
to the definition, for instance). Classy PageObject's
collection simplifies the collection helper.
collection
should now receive the definition for just the items that are enumerable themselves.
// before
let page = create({
rows: collection({
scope: 'table',
itemScope: 'tr',
item: {
firstName: text('td.first-name'),
lastName: text('td.last-name')
}
})
});
// after
let Page = PageObject.extend({
table: {
scope: 'table',
rows: collection({
scope: 'tr',
firstName: text('td.first-name'),
lastName: text('td.last-name')
})
}
});
let page = new Page();
Collections now return an instance of a class with the following public API methods:
objectAt(index: number): Page
: Return the page for the item at the specified indexforEach(fn: (item, index, list) => void): void
: Run a function for every item in the collectionmap(fn: (item, index, list) => any): Array<any>
: Map a transform over every item in the collectionfindAll(query: object | fn(item, index, list) => boolean): Array<Page>
: Find all items in the collection which match the query. If the query is an object, it will return all items whose properties are equal to every key/property on the query object. If it is a function it will return any item that returns true when passed to the function.findOne(query: object | fn(item, index, list) => boolean): Page | undefined
: Find the first item in the collection that matches the query. If the query is an object, it will return all items whose properties are equal to every key/property on the query object. If it is a function it will return any item that returns true when passed to the function. If more than one item is matched, the helper will throw an error.toArray(): Array<Page>
: Convert the collection into a native array
And the following properties
length: number
: The number of items in the collection (count
)
git clone <repository-url>
this repositorycd ember-classy-page-object
yarn install
ember serve
- Visit your app at http://localhost:4200.
yarn test
(Runsember try:each
to test your addon against multiple Ember versions)ember test
ember test --server
ember build
For more information on using ember-cli, visit https://ember-cli.com/.