19. Actions и навигация

Локаторы (Locators)
Заголовок раздела «Локаторы (Locators)»// Рекомендуемые локаторы (стабильные)page.getByRole('button', { name: 'Submit' });page.getByLabel('Email');page.getByPlaceholder('Search...');page.getByText('Welcome');page.getByAltText('Logo');page.getByTitle('Close dialog');page.getByTestId('submit-btn'); // data-testid
// CSS и XPath (менее предпочтительны)page.locator('.submit-button');page.locator('#email-input');page.locator('input[type="email"]');page.locator('//button[@type="submit"]');
// Комбинированиеpage.locator('.user-card').getByRole('button', { name: 'Edit' });page.getByRole('listitem').filter({ hasText: 'Alice' });page.locator('.card').first();page.locator('.card').nth(2);page.locator('.card').last();Клики и взаимодействие
Заголовок раздела «Клики и взаимодействие»// Обычный кликawait page.click('button');await page.getByRole('button').click();
// Двойной кликawait page.dblclick('.item');
// Правый кликawait page.click('.item', { button: 'right' });
// Клик по координатамawait page.click('.canvas', { position: { x: 100, y: 200 } });
// Hoverawait page.hover('.dropdown-toggle');
// Drag and Dropawait page.dragAndDrop('#source', '#target');
// Focusawait page.focus('input[name="email"]');Работа с формами
Заголовок раздела «Работа с формами»// Заполнить поле (очищает перед заполнением)
// Тип (посимвольно)await page.type('[name="search"]', 'hello', { delay: 50 });
// Очиститьawait page.fill('[name="email"]', '');
// Нажать клавишуawait page.press('[name="email"]', 'Enter');await page.press('body', 'Escape');
// Selectawait page.selectOption('select[name="country"]', 'ru');await page.selectOption('select', { label: 'Russia' });await page.selectOption('select', ['ru', 'us']); // multi-select
// Checkboxawait page.check('[name="agree"]');await page.uncheck('[name="agree"]');await page.getByRole('checkbox').check();
// File inputawait page.setInputFiles('input[type="file"]', './test-image.jpg');await page.setInputFiles('input[type="file"]', ['./file1.pdf', './file2.pdf']);
// Загрузка файла через диалогconst [fileChooser] = await Promise.all([ page.waitForEvent('filechooser'), page.click('button:has-text("Upload")'),]);await fileChooser.setFiles('./my-file.pdf');Навигация
Заголовок раздела «Навигация»// Перейти по URLawait page.goto('https://example.com');await page.goto('/login', { waitUntil: 'networkidle' });
// Назад / Вперёдawait page.goBack();await page.goForward();
// Перезагрузитьawait page.reload();
// Ждать URLawait page.waitForURL('/dashboard');await page.waitForURL('**/dashboard', { timeout: 5000 });
// Ждать навигацию после действияawait Promise.all([ page.waitForNavigation(), page.click('a[href="/next"]'),]);
// Получить текущий URLconst url = page.url();Ожидания
Заголовок раздела «Ожидания»// Playwright автоматически ждёт элемент// Явные ожидания только при необходимости
// Ждать видимостьawait page.waitForSelector('.modal', { state: 'visible' });
// Ждать скрытиеawait page.waitForSelector('.loader', { state: 'hidden' });
// Ждать появление текстаawait page.waitForFunction(() => document.title.includes('Loaded'));
// Ждать сетевой запросconst [response] = await Promise.all([ page.waitForResponse('**/api/users'), page.click('button:has-text("Load Users")'),]);const data = await response.json();
// Ждать конкретный статус ответаawait page.waitForResponse( res => res.url().includes('/api/data') && res.status() === 200);
// Timeout кастомныйawait page.waitForSelector('.lazy-content', { timeout: 10000 });Скроллинг
Заголовок раздела «Скроллинг»// Прокрутить к элементуawait page.locator('.footer').scrollIntoViewIfNeeded();
// Прокрутить страницуawait page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
// Прокрутить внутри элементаawait page.locator('.scrollable-list').evaluate(el => el.scrollTop = 500);Работа с iframes
Заголовок раздела «Работа с iframes»const frame = page.frameLocator('#payment-iframe');await frame.getByLabel('Card Number').fill('4242 4242 4242 4242');await frame.getByLabel('Expiry').fill('12/26');await frame.getByRole('button', { name: 'Pay' }).click();Практические задания
Заголовок раздела «Практические задания»- Напиши тест для корзины: добавь товар → проверь количество → удали
- Протестируй форму с file input (загрузка аватара)
- Протестируй бесконечную прокрутку (scroll → loadMore)
- getByRole, getByLabel — стабильные локаторы
- fill() для форм, click() для кнопок
- waitForResponse() — перехват API вызовов
- Promise.all() для действия + ожидания