diff --git a/docs/angular/testing.md b/docs/angular/testing.md index 1278551b0b9..5fc0e2efb16 100644 --- a/docs/angular/testing.md +++ b/docs/angular/testing.md @@ -109,6 +109,34 @@ describe('TabsPage', () => { When doing component class testing, the component object is accessed using the component object defined via `component = fixture.componentInstance;`. This is an instance of the component class. When doing DOM testing, the `fixture.nativeElement` property is used. This is the actual `HTMLElement` for the component, which allows the test to use standard HTML API methods such as `HTMLElement.querySelector` in order to examine the DOM. +### Waiting for Components + +When testing Ionic components, use the `componentOnReady` helper exported from `@ionic/core` rather than calling `el.componentOnReady()` directly. The `el.componentOnReady()` method only exists on lazy-loaded elements and calling it directly throws an error on custom-element builds, which is what standalone projects use. The helper handles both. It awaits the element's own `componentOnReady()` promise when that exists. Otherwise it waits one animation frame, giving the component's inner contents a chance to render. Wait for the callback before asserting against the rendered DOM or running accessibility tests. + +```tsx +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { componentOnReady } from '@ionic/core'; +import { HomePage } from './home.page'; + +describe('HomePage', () => { + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HomePage], + }).compileComponents(); + fixture = TestBed.createComponent(HomePage); + fixture.detectChanges(); + }); + + it('renders the submit button', async () => { + const button = fixture.nativeElement.querySelector('ion-button'); + await new Promise((resolve) => componentOnReady(button, () => resolve())); + expect(button.textContent).toContain('Submit'); + }); +}); +``` + ## Services Services often fall into one of two broad categories: utility services that perform calculations and other operations, and data services that perform primarily HTTP operations and data manipulation. diff --git a/docs/react/testing/unit-testing/best-practices.md b/docs/react/testing/unit-testing/best-practices.md index ce1562d391f..7576b13b868 100644 --- a/docs/react/testing/unit-testing/best-practices.md +++ b/docs/react/testing/unit-testing/best-practices.md @@ -49,3 +49,25 @@ test('example', async () => { ``` For more information on `user-event`, see the [user-event documentation](https://testing-library.com/docs/user-event/intro/). + +## Waiting for Components + +When you need to wait for an Ionic component to render before asserting against its DOM, use the `componentOnReady` helper exported from `@ionic/core`. Do not call `el.componentOnReady()` directly. `@ionic/react` uses Stencil's custom elements build, where that method does not exist on the element. The helper waits one animation frame instead, giving the component's inner contents a chance to render. + +```tsx +import { test, expect } from 'vitest'; +import { render } from '@testing-library/react'; +import { componentOnReady } from '@ionic/core'; + +import App from './App'; + +test('renders the submit button', async () => { + const { container } = render(); + + const button = container.querySelector('ion-button'); + + await new Promise((resolve) => componentOnReady(button!, () => resolve())); + + expect(button?.textContent).toContain('Submit'); +}); +``` diff --git a/docs/vue/testing.md b/docs/vue/testing.md new file mode 100644 index 00000000000..184ed834fda --- /dev/null +++ b/docs/vue/testing.md @@ -0,0 +1,19 @@ +--- +title: Testing +--- + + + Vue Unit and End-to-End Testing for Ionic App Components + + + +This document provides an overview of how to test an application built with `@ionic/vue`. Applications generated with the Ionic CLI are set up for unit testing with [Vitest](https://vitest.dev) and [Vue Test Utils](https://test-utils.vuejs.org), and for end-to-end testing with [Cypress](https://www.cypress.io). + +## Unit Testing + +### Waiting for Components + +When you need to wait for an Ionic component to render before asserting against its DOM, use the `componentOnReady` helper exported from `@ionic/core`. Do not call `el.componentOnReady()` directly. `@ionic/vue` uses Stencil's custom elements build, where that method does not exist on the element. The helper waits one animation frame instead, giving the component's inner contents a chance to render. diff --git a/sidebars.js b/sidebars.js index 06689adc351..82f1e873e93 100644 --- a/sidebars.js +++ b/sidebars.js @@ -183,6 +183,7 @@ module.exports = { 'vue/slides', 'vue/utility-functions', 'vue/platform', + 'vue/testing', 'vue/pwa', 'vue/storage', 'vue/troubleshooting',