A JavaScript framework for creating ambitious web applications
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Testing framework integration and utilities for writing unit and integration tests for Ember applications.
Functions for configuring the test environment and preparing applications for testing.
/**
* Configure application for testing environment
* Sets up test-specific behaviors and disables automatic run loop
*/
function setupForTesting(): void;
/**
* Setup application test container with test-specific configuration
* @param application - Application instance to setup for testing
*/
function setupApplicationTest(application: Application): void;
/**
* Setup rendering test context for component testing
* @param hooks - Test hooks object (typically QUnit or Mocha hooks)
*/
function setupRenderingTest(hooks: TestHooks): void;
/**
* Setup unit test context for isolated object testing
* @param hooks - Test hooks object
*/
function setupTest(hooks: TestHooks): void;Base adapter classes for integrating with different test frameworks.
/**
* Base test adapter for framework integration
*/
class TestAdapter {
/**
* Called when async test operation begins
*/
asyncStart(): void;
/**
* Called when async test operation ends
*/
asyncEnd(): void;
/**
* Called when test exception occurs
* @param error - Error that occurred
*/
exception(error: Error): void;
}
/**
* QUnit-specific test adapter
*/
class QUnitAdapter extends TestAdapter {
/**
* Create QUnit adapter instance
* @returns New QUnitAdapter
*/
static create(): QUnitAdapter;
asyncStart(): void;
asyncEnd(): void;
exception(error: Error): void;
}Helper functions for interacting with the application during tests.
/**
* Navigate to a URL in the test application
* @param url - URL to visit
* @returns Promise that resolves when navigation completes
*/
function visit(url: string): Promise<void>;
/**
* Click an element in the test application
* @param selector - CSS selector for element to click
* @returns Promise that resolves when click completes
*/
function click(selector: string): Promise<void>;
/**
* Fill in a form input with a value
* @param selector - CSS selector for input element
* @param value - Value to fill in
* @returns Promise that resolves when fill completes
*/
function fillIn(selector: string, value: string): Promise<void>;
/**
* Trigger an event on an element
* @param selector - CSS selector for target element
* @param eventType - Type of event to trigger
* @param options - Event options
* @returns Promise that resolves when event completes
*/
function triggerEvent(selector: string, eventType: string, options?: EventOptions): Promise<void>;
/**
* Find a single element in the test application
* @param selector - CSS selector for element
* @returns DOM element or null
*/
function find(selector: string): Element | null;
/**
* Find all elements matching selector in test application
* @param selector - CSS selector for elements
* @returns Array of DOM elements
*/
function findAll(selector: string): Element[];
/**
* Get current URL in test application
* @returns Current URL string
*/
function currentURL(): string;
/**
* Get current route path
* @returns Current route path
*/
function currentPath(): string;
/**
* Get current route name
* @returns Current route name
*/
function currentRouteName(): string;Helpers specifically for component rendering tests.
/**
* Render a template in the test context
* @param template - Handlebars template string to render
* @returns Promise that resolves when rendering completes
*/
function render(template: string): Promise<void>;
/**
* Clear the rendered content
* @returns Promise that resolves when clearing completes
*/
function clearRender(): Promise<void>;
/**
* Set properties on the test context
* @param properties - Properties to set
*/
function setProperties(properties: object): void;
/**
* Get property from test context
* @param key - Property key to get
* @returns Property value
*/
function getProperty(key: string): any;System for managing asynchronous operations in tests.
/**
* Register a test waiter that must complete before tests finish
* @param context - Context object for the waiter
* @param callback - Function that returns true when complete
*/
function registerWaiter(context: any, callback: () => boolean): void;
/**
* Unregister a previously registered test waiter
* @param context - Context object that was registered
* @param callback - Callback function that was registered
*/
function unregisterWaiter(context: any, callback: () => boolean): void;
/**
* Wait for all registered waiters to complete
* @returns Promise that resolves when all waiters complete
*/
function waitForWaiters(): Promise<void>;
/**
* Check if there are any pending waiters
* @returns Whether waiters are still pending
*/
function hasPendingWaiters(): boolean;Utilities for mocking services and dependencies in tests.
/**
* Create a stub service for testing
* @param properties - Properties to include in stub
* @returns Stub service object
*/
function createStubService(properties?: object): Service;
/**
* Register a stub service in the test container
* @param owner - Test container owner
* @param serviceName - Name of service to stub
* @param stub - Stub service instance
*/
function registerStubService(owner: Owner, serviceName: string, stub: Service): void;
/**
* Mock a service method for testing
* @param service - Service to mock
* @param methodName - Method name to mock
* @param mockImplementation - Mock function
*/
function mockServiceMethod(service: Service, methodName: string, mockImplementation: Function): void;Usage Examples:
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click, fillIn, find } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | login-form', function(hooks) {
setupRenderingTest(hooks);
test('it renders login form', async function(assert) {
await render(hbs`<LoginForm />`);
assert.dom('[data-test-login-form]').exists();
assert.dom('input[type="email"]').exists();
assert.dom('input[type="password"]').exists();
assert.dom('button[type="submit"]').hasText('Login');
});
test('it handles form submission', async function(assert) {
let submitted = false;
this.set('onSubmit', () => { submitted = true; });
await render(hbs`<LoginForm @onSubmit={{this.onSubmit}} />`);
await fillIn('input[type="email"]', 'test@example.com');
await fillIn('input[type="password"]', 'password123');
await click('button[type="submit"]');
assert.ok(submitted, 'Form submission handler was called');
});
});
// Acceptance test example
import { module, test } from 'qunit';
import { visit, currentURL, click, fillIn } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
module('Acceptance | login', function(hooks) {
setupApplicationTest(hooks);
test('visiting /login', async function(assert) {
await visit('/login');
assert.equal(currentURL(), '/login');
});
test('successful login redirects to dashboard', async function(assert) {
await visit('/login');
await fillIn('[data-test-email]', 'user@example.com');
await fillIn('[data-test-password]', 'password');
await click('[data-test-login-button]');
assert.equal(currentURL(), '/dashboard');
});
});
// Unit test with service mocking
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Service | session', function(hooks) {
setupTest(hooks);
test('login method calls API correctly', async function(assert) {
const service = this.owner.lookup('service:session');
// Mock fetch
const originalFetch = window.fetch;
window.fetch = () => Promise.resolve({
ok: true,
json: () => Promise.resolve({ id: 1, name: 'Test User' })
});
const result = await service.login('test@example.com', 'password');
assert.ok(result, 'Login should succeed');
assert.equal(service.currentUser.name, 'Test User');
assert.ok(service.isAuthenticated, 'Should be authenticated');
// Restore fetch
window.fetch = originalFetch;
});
});Configuration options and utilities for test environments.
/**
* Test configuration options
*/
interface TestConfig {
/** Test adapter to use */
adapter?: TestAdapter;
/** Whether to automatically advance timers */
autoAdvanceTimers?: boolean;
/** Default timeout for async operations */
timeout?: number;
}
/**
* Configure test environment
* @param config - Test configuration options
*/
function configureTest(config: TestConfig): void;interface TestHooks {
/** Setup hook called before each test */
beforeEach?: (callback: Function) => void;
/** Teardown hook called after each test */
afterEach?: (callback: Function) => void;
/** Setup hook called before all tests */
before?: (callback: Function) => void;
/** Teardown hook called after all tests */
after?: (callback: Function) => void;
}
interface EventOptions {
/** Event bubbles */
bubbles?: boolean;
/** Event is cancelable */
cancelable?: boolean;
/** Additional event properties */
[key: string]: any;
}
interface TestContext {
/** Test owner (DI container) */
owner: Owner;
/** Test element for rendering */
element: Element;
/** Set property on test context */
set(key: string, value: any): void;
/** Get property from test context */
get(key: string): any;
}Install with Tessl CLI
npx tessl i tessl/npm-ember-source