Ember Test Selectors
Ember Test Selectors is an Ember.js addon designed to facilitate robust and stable UI testing by providing a convention for marking elements in templates with `data-test-*` attributes. These attributes are automatically stripped from production builds to minimize bundle size and prevent leakage of internal testing details. The current stable version is 7.1.0, released recently with a new plugin for Vite. The project maintains an active release cadence, typically aligning with Ember and Node.js LTS updates. Key differentiators include its tight integration with the Ember build pipeline to automatically remove test attributes and its widespread adoption within the Ember ecosystem for defining clear test-only hooks. It supports Ember versions 3.8 to 4.12 and Node.js 18 or above, with a separate `strip-test-selectors` package available for Embroider+Vite applications.
Common errors
-
Error: Node.js version X is not supported by ember-test-selectors.
cause Running `ember-test-selectors` with an unsupported Node.js version (e.g., 12, 14, 16).fixUpgrade Node.js to version 18, 20, or 22+. -
Assertion Failed: You must apply `...attributes` to an HTML element in your component.
cause Attempting to pass `data-test-*` attributes to an Ember component without `...attributes` being explicitly spread on an element within its template, or using an older unsupported binding method.fixEnsure your component's template has `...attributes` on the root HTML element or the specific element where the attribute should be applied. For example: `<div ...attributes>...</div>`. -
Module build failed (from ./node_modules/babel-loader/lib/index.js): Error: Cannot find module 'ember-cli-babel'
cause `ember-cli-babel` is an outdated or missing dependency, often related to `ember-test-selectors` compatibility requirements.fixUpdate `ember-cli-babel` to a compatible version for your Ember CLI setup, typically `^8.0.0` for modern Ember projects, by running `npm install ember-cli-babel@latest`. -
document.querySelector('[data-test-some-element]') returns null in production builds.cause The `data-test-*` attributes are automatically stripped from production builds by default, making them unavailable in that environment.fixTo enable `data-test-*` attributes in production builds, modify `ember-cli-build.js`: `var app = new EmberApp({'ember-test-selectors': { strip: false }});`. Be aware that this will increase bundle size.
Warnings
- breaking Support for Node.js versions 12, 14, and 16 has been removed. Ensure your project is running on Node.js 18, 20, or >= 22.
- breaking Deprecated automatic attribute binding behavior for `data-test-*` attributes has been fully removed. You must explicitly apply `...attributes` to the target element within components.
- breaking Support for `ember-cli-babel` v5 has been dropped. Projects must upgrade `ember-cli-babel` to a compatible version (e.g., v8 for Ember 3.28+).
- breaking This addon drops support for Ember.js versions below v3.8 due to an update of `ember-cli-htmlbars`.
- gotcha By default, `data-test-*` attributes are stripped from production builds (`ember build -prod`) but are present for `ember test --environment=production`. If you need them in production or want to strip them differently, you must configure this behavior.
Install
-
npm install ember-test-selectors -
yarn add ember-test-selectors -
pnpm add ember-test-selectors
Quickstart
ember install ember-test-selectors
// app/templates/components/my-component.hbs
<article>
<h1 data-test-post-title data-test-resource-id={{post.id}}>{{post.title}}</h1>
<p>{{post.body}}</p>
<button data-test-like-button>Like</button>
</article>
// app/tests/integration/components/my-component-test.js
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | my-component', function(hooks) {
setupRenderingTest(hooks);
test('it renders post title and handles like click', async function(assert) {
this.set('post', { id: '123', title: 'Ember is great!', body: '...' });
await render(hbs`<MyComponent @post={{this.post}} />`);
assert.dom('[data-test-post-title]').hasText('Ember is great!');
assert.dom('[data-test-resource-id="123"]').exists();
await click('[data-test-like-button]');
assert.ok(true, 'Like button was clicked'); // Replace with actual assertion
});
});