packages/js/email-editor/development.md
The most efficient way to develop the Email Editor is by using the WooCommerce plugin's watch command:
pnpm --filter='@woocommerce/plugin-woocommerce' watch:build:admin
To run component tests in the JS package:
pnpm run test:js
To run a specific test file:
pnpm run test:js -- src/components/my-component/test/my-component.spec.tsx
We use Jest with @testing-library/react. These are component tests, not strict unit tests, and include mocked dependencies.
should prefix in test names (e.g., should render the modal).@wordpress/data, @wordpress/components). Create shared mock setup files when possible.data-testid attributes when using them in mocked components (e.g., data-testid="modal").screen.getByRole(), getByText(), or similar accessible queries where applicable.__mocks__/setup-shared-mocks.ts) to keep individual test files clean.jest.mock() for external dependencies like WordPress packages or internal modules.React.ComponentProps<'button'> or specific prop interfaces to avoid any.Example for reusable mock setup:
// __mocks__/setup-shared-mocks.ts
jest.mock('@wordpress/data', () => ({
useSelect: jest.fn(),
useDispatch: jest.fn(),
createRegistrySelector: jest.fn(),
}));
/* eslint-disable @woocommerce/dependency-group -- because we import mocks first, we deactivate this rule to avoid es lint errors */
import '../../__mocks__/setup-shared-mocks';
/**
* External dependencies
*/
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
/**
* Internal dependencies
*/
import { MyComponent } from '../my-component';
describe('MyComponent', () => {
it('should render a button and respond to click', () => {
const onClickMock = jest.fn();
render(<MyComponent onClick={onClickMock} />);
const button = screen.getByRole('button', { name: /click me/i });
expect(button).toBeInTheDocument();
fireEvent.click(button);
expect(onClickMock).toHaveBeenCalled();
});
});
E2E tests: writing-e2e-tests.md