GithubHelp home page GithubHelp logo

ember-classy-page-object's Introduction

ember-classy-page-object

Provides a super simple class-like wrapper around ember-cli-page-object.

Supports Ember 2.8-LTS through Ember 3.28-LTS

Usage

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.

Jquery vs Native

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.

Helpers

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.

Collection

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 index
  • forEach(fn: (item, index, list) => void): void: Run a function for every item in the collection
  • map(fn: (item, index, list) => any): Array<any>: Map a transform over every item in the collection
  • findAll(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)

Installation

  • git clone <repository-url> this repository
  • cd ember-classy-page-object
  • yarn install

Running

Running Tests

  • yarn test (Runs ember try:each to test your addon against multiple Ember versions)
  • ember test
  • ember test --server

Building

  • ember build

For more information on using ember-cli, visit https://ember-cli.com/.

ember-classy-page-object's People

Contributors

addepar-andy avatar ascudder avatar bantic avatar billy-addepar avatar c69-addepar avatar danmonroe avatar ember-tomster avatar faf0-addepar avatar jonny-hein avatar mixonic avatar navkast avatar pzuraq avatar svc-security-workflows avatar twokul avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-classy-page-object's Issues

`useNativeEvents` should not be a part of the page object out of the box?

I've just observed the following in the codebase

// pre-emptively turn on native events since we'll need them
useNativeEvents();

I believe it should not be here, and if really needed, it should be called on the consumer test setup side.

The useNativeEvents( is used to enable the ember-native-dom-helpers, which was needed in the era of moduleFor* tests. Now, for the test suites using modern @ember/test-helpers, I don't think we need it anymore.

Also, useNativeEvents( is now removed in the v2-beta of the ec-page-objects, cause moduleFor test helpers are now removed completelly from @ember/test-helpers, so I think this invocation would break ember-classy-page-object under ember-cli-page-object@v2 when it's released.

So my guess is that we should remove it from here at some point, as a breaking change? @mixonic what do you think?

Build error when using ember-cli-page-object v2.0.0-beta.4

The version of ember-cli-page-object required in package.json is ~v2.0.0-beta.3, which includes the newly-released v2.0.0-beta.4. However, that version converts ember-cli-page-object to a V2 addon, and we now see this error when trying to build our app:

ember-classy-page-object needs to depend on ember-auto-import in order to use ember-cli-page-object

Our workaround is to force ember-cli-page-object to v2.0.0-beta.3 using yarn resolutions. But it seems like this addon should probably move ember-auto-import to dependencies instead of devDependencies as recommended in the ember-auto-import documentation.

I'll open a PR but I'm not sure if this is a breaking change for consuming apps/addons, so some additional thought might be required there.

Nested Page Object `length` errors out

I get an error whenever I call any function that calls length on my nested page object. The page object works just fine other than being unable to call length (I can call eq(10) on the page object, grab a field and interact with that nested page object)

> this.fields.length
jquery.js:1541 Uncaught Error: Syntax error, unrecognized expression: [data-test-beta-transaction-panel] scope(scope) {
      return this.extend({ scope });
    }
    at Function.Sizzle.error (jquery.js:1541)
    at Sizzle.tokenize (jquery.js:2193)
    at Function.Sizzle [as find] (jquery.js:815)
    at jQuery.fn.init.find (jquery.js:2873)
    at new jQuery.fn.init (jquery.js:2988)
    at jQuery (jquery.js:139)
    at AcceptanceNativeEventsExecutionContext.$ (native-events-context.js:54)
    at AcceptanceNativeEventsExecutionContext.find (native-events-context.js:91)
    at executionContext.run.context (count.js:91)
    at AcceptanceNativeEventsExecutionContext.run (native-events-context.js:19)

for my collection that looks like:
fields: collection(TransactionFieldPageObject.scope('[data-test-beta-transaction-value-editor]')),

Nested collection bug

I have a table that contains a collection of rows whose element contains a collection of cells.

  rows: collection({
    scope: 'tr',

    cells: collection({
      scope: 'td'
    })
  }),

When I use forEach to iterate through all cells and print cell text, it prints incorrect result.

      this.rows.forEach((row) => {
        row.cells.forEach((cell) => {
          console.log(cell.text);
        })
      })

Further debugging shows that cell text does not match row text:

screen shot 2017-12-06 at 11 21 41 am

This makes me believe that there is a bug with nested collection.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.