{"id":20445193,"url":"https://github.com/addepar/ember-classy-page-object","last_synced_at":"2025-07-14T10:41:01.106Z","repository":{"id":39962706,"uuid":"109195607","full_name":"Addepar/ember-classy-page-object","owner":"Addepar","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-08T10:08:45.000Z","size":714,"stargazers_count":2,"open_issues_count":1,"forks_count":6,"subscribers_count":59,"default_branch":"master","last_synced_at":"2025-04-13T00:42:01.092Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Addepar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-01T23:38:54.000Z","updated_at":"2025-04-08T10:08:48.000Z","dependencies_parsed_at":"2024-06-18T19:58:32.138Z","dependency_job_id":"cfc18e78-53c0-42f9-9ff7-82ae308ecf81","html_url":"https://github.com/Addepar/ember-classy-page-object","commit_stats":{"total_commits":96,"total_committers":19,"mean_commits":5.052631578947368,"dds":0.6875,"last_synced_commit":"bb9702c4582659d5d70ba8e477386b2d889c9558"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Addepar%2Fember-classy-page-object","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Addepar%2Fember-classy-page-object/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Addepar%2Fember-classy-page-object/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Addepar%2Fember-classy-page-object/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Addepar","download_url":"https://codeload.github.com/Addepar/ember-classy-page-object/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650417,"owners_count":21139672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T10:11:22.284Z","updated_at":"2025-04-13T00:42:13.704Z","avatar_url":"https://github.com/Addepar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ember-classy-page-object\n\nProvides a super simple class-like wrapper around [ember-cli-page-object](https://github.com/san650/ember-cli-page-object).\n\nSupports Ember 3.28 LTS and also Ember 4 and 5 LTS versions.\nThis addon is embroider-safe.\n\n## Usage\n\nGiven a simple ToggleButton component that just toggles its active state with a\ntemplate like so:\n\n```hbs\n\u003c!-- note activeClass defaults to `is-active` --\u003e\n\u003cbutton {{action \"toggleActive\"}} data-test-toggle-button class=\"{{if this.active this.activeClass}}\"\u003e\n  {{if this.active \"Deactivate\" \"Activate\"}}\n\u003c/button\u003e\n```\n\nYou can represent it and test like this:\n\n```js\nimport { module, test } from 'qunit';\nimport PageObject, { clickable } from 'ember-classy-page-object';\nimport { findElement } from 'ember-classy-page-object/extend';\n\nconst ToggleButtonPage = PageObject.extend({\n  toggle: clickable('[data-test-toggle-button]'),\n\n  activeClass: 'is-active',\n\n  get isActive() {\n    return findElement(this, '[data-test-toggle-button]').classList.contains(this.activeClass);\n  }\n});\n\nmodule('toggle button');\n\ntest('can toggle', function(assert) {\n\tconst myToggleButton = new ToggleButtonPage();\n\n\tmyToggleButton.toggle();\n\n\tassert.ok(myToggleButton.isActive, 'it toggled!');\n});\n```\n\nIf you later need to reuse a component, you can extend it to override properties:\n\n```hbs\n\u003cToggleButton data-test-first-toggle /\u003e\n\u003cToggleButton data-test-second-toggle @activeClass=\"is-activated\" /\u003e\n```\n\n```js\nconst DoubleToggleButtonPage = PageObject.extend({\n  firstToggle: ToggleButtonPage.extend({\n\t  scope: '[data-test-first-toggle]'\n  }),\n\n  secondToggle: ToggleButtonPage.extend({\n\t  scope: '[data-test-second-toggle]',\n\t  activeClass: 'is-activated'\n  })\n});\n\nconst myDoubleToggle = new DoubleToggleButtonPage();\n\nmyDoubleToggle.firstToggle.toggle();\n// etc...\n```\n\nExtending deep merges the new definition into the previous definition. When you want to finally\nuse the page object, just call `create` which finalizes the object.\n\n## Jquery vs Native\n\nClassy page object defaults to running in native-dom mode, meaning it sends native events and\nuses native-dom helpers under the hood. Results from functions like `findElement` and\n`findElementWithAssert` return actual elements, not jquery selectors. However, ember-cli-page-object\nhasn't been able to get rid of the jquery dependency yet, so it's still possible to use jquery\nselectors within page objects themselves. It is _highly_ recommended that you avoid this to prevent\ntying yourself to jquery in your tests, as Ember continues to remove the dependency in the future.\n\n## Helpers\n\nClassy page object re-exports all of the helpers from ember-cli-page-object with the exception of\n`getter`, you can now use native ES getters instead. The list of exports is as follows:\n\n* `ember-classy-page-object`\n  * `default as PageObject`\n  * `alias`\n  * `attribute`\n  * `blurrable`\n  * `clickOnText`\n  * `clickable`\n  * `contains`\n  * `count`\n  * `fillable`\n  * `hasClass`\n  * `isHidden`\n  * `isPresent`\n  * `isVisible`\n  * `notHasClass`\n  * `property`\n  * `text`\n  * `triggerable`\n  * `value`\n  * `visitable`\n* `ember-classy-page-object/extend`\n  * `findElement`\n  * `findElementWithAssert`\n  * `buildSelector`\n  * `fullScope`\n\nSome helpers have been overridden to make them mergeable and easier to use, such as `collection`,\nso it's highly recommended that you use these helpers from `ember-classy-page-object` and not\nfrom `ember-cli-page-object` directly.\n\n### Collection\n\nThe collection helper in `ember-cli-page-object` has some shortcomings, mostly the fact that it\nrequires users to call it as a function to generate an enumerable, and can only query directly by\nindex. It also confusingly refers to both the enumerable items, and their immediate parent (which is\nwhy you must provide `itemScope` and `item` to the definition, for instance). Classy PageObject's\ncollection simplifies the collection helper.\n\n`collection` should now receive the definition for just the items that are enumerable themselves.\n\n```js\n// before\n\nlet page = create({\n  rows: collection({\n    scope: 'table',\n\n    itemScope: 'tr',\n\n    item: {\n      firstName: text('td.first-name'),\n      lastName: text('td.last-name')\n    }\n  })\n});\n\n// after\n\nlet Page = PageObject.extend({\n  table: {\n    scope: 'table',\n\n    rows: collection({\n      scope: 'tr',\n      firstName: text('td.first-name'),\n      lastName: text('td.last-name')\n    })\n  }\n});\n\nlet page = new Page();\n```\n\nCollections now return an instance of a class with the following public API methods:\n\n* `objectAt(index: number): Page`: Return the page for the item at the specified index\n* `forEach(fn: (item, index, list) =\u003e void): void`: Run a function for every item in the collection\n* `map(fn: (item, index, list) =\u003e any): Array\u003cany\u003e`: Map a transform over every item in the collection\n* `findAll(query: object | fn(item, index, list) =\u003e boolean): Array\u003cPage\u003e`: Find all items in the collection\n  which match the query. If the query is an object, it will return all items whose properties\n  are equal to every key/property on the query object. If it is a function it will return any\n  item that returns true when passed to the function.\n* `findOne(query: object | fn(item, index, list) =\u003e boolean): Page | undefined`: Find the first item in the\n  collection that matches the query. If the query is an object, it will return all items whose properties\n  are equal to every key/property on the query object. If it is a function it will return any\n  item that returns true when passed to the function. If more than one item is matched, the helper will\n  throw an error.\n* `toArray(): Array\u003cPage\u003e`: Convert the collection into a native array\n\nAnd the following properties\n\n* `length: number`: The number of items in the collection (`count`)\n\n## Installation\n\n* `git clone \u003crepository-url\u003e` this repository\n* `cd ember-classy-page-object`\n* `pnpm install`\n\n## Running\n\n* `ember serve`\n* Visit your app at [http://localhost:4200](http://localhost:4200).\n\n## Running Tests\n\n* `pnpm test` (Runs `ember try:each` to test your addon against multiple Ember versions)\n* `ember test`\n* `ember test --server`\n\n## Building\n\n* `ember build`\n\nFor more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddepar%2Fember-classy-page-object","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faddepar%2Fember-classy-page-object","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddepar%2Fember-classy-page-object/lists"}