Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
ember-classy-page-object
Advanced tools
Provides a super simple class-like wrapper around ember-cli-page-object.
Supports Ember 2.8-LTS through Ember 3.28-LTS
Given a simple ToggleButton component that just toggles its active state with a template like so:
<!-- note activeClass defaults to `is-active` -->
<button {{action "toggleActive"}} data-test-toggle-button class="{{if active activeClass}}">
{{if active "Deactivate" "Activate"}}
</button>
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:
{{toggle-button data-test-first-toggle=true}}
{{toggle-button data-test-second-toggle=true activeClass="is-activated"}}
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 arrayAnd 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
yarn test
(Runs ember 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/.
FAQs
The default blueprint for ember-cli addons.
We found that ember-classy-page-object demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.