E2E Tests
E2E tests use the Playwright Test API and run in a real browser. There are two approaches:
| Approach | When to use | Import |
|---|---|---|
| Component Sandbox | Testing a component in isolation | ui.test.e2e.sandbox |
| Real interface | Testing on product pages | @playwright/test or ui.test.e2e.auth |
Structure
local/js/vendor/my-extension/
└── tests/
└── e2e/
├── my-extension.spec.ts
└── navigation.spec.tsComponent Sandbox
For testing components in isolation — without tying tests to a specific product page. See Component Sandbox for details.
ts
import { test, expect } from 'ui.test.e2e.sandbox';
test('button renders correctly', async ({ sandbox }) => {
await sandbox.loadExtension('ui.buttons');
await sandbox.mount((selector) => {
const btn = new BX.UI.Button({ text: 'Click me', color: 'success' });
document.querySelector(selector).appendChild(btn.render());
});
await expect(sandbox.page.locator('.ui-btn-success')).toBeVisible();
await expect(sandbox.page.locator('.ui-btn-success')).toHaveText('Click me');
});For Vue components see E2E Tests Vue 3.
Real Interface
For testing on product pages — navigation, forms, interaction with the actual UI.
Public Pages
Pages accessible without authentication:
ts
import { test, expect } from '@playwright/test';
test('widget renders on page', async ({ page }) => {
await page.goto('/my-page/');
const widget = page.locator('.my-widget');
await expect(widget).toBeVisible();
});
test('button click shows popup', async ({ page }) => {
await page.goto('/my-page/');
await page.click('.my-widget__button');
const popup = page.locator('.popup-window');
await expect(popup).toBeVisible();
await expect(popup).toContainText('Settings');
});Authenticated Pages
For pages that require authentication, import test from ui.test.e2e.auth. Before each test, automatic login will be performed using credentials from .env.test:
ts
import { test, expect } from 'ui.test.e2e.auth';
test('admin panel is accessible', async ({ page }) => {
// page is already authenticated
await page.goto('/bitrix/admin/');
await expect(page.locator('.adm-header')).toBeVisible();
});Working with Forms
ts
import { test, expect } from 'ui.test.e2e.auth';
test('should save form data', async ({ page }) => {
await page.goto('/settings/');
await page.fill('input[name="title"]', 'New Title');
await page.selectOption('select[name="category"]', 'news');
await page.click('button[type="submit"]');
await expect(page.locator('.success-message')).toBeVisible();
});Waiting for AJAX Requests
ts
import { test, expect } from 'ui.test.e2e.auth';
test('should load items via ajax', async ({ page }) => {
await page.goto('/items/');
const response = page.waitForResponse('**/ajax/**');
await page.click('.load-more');
await response;
const items = page.locator('.item-card');
await expect(items).toHaveCount(20);
});Useful Links
- Writing Tests — test writing basics
- Locators — finding elements on the page
- Assertions — checks (
expect) - Actions — clicks, text input, file uploads
- Auto-waiting — how Playwright waits for element readiness