Это головная боль автоматизаторов из прошлого, потому что в Selenium были только явные ожидания, которые нужно прописывать и про это душили на собесах. 😡
Базово в Selenium используется Polling-based подход:
Selenium постоянно опрашивает DOM каждые 500мс
В Playwright же используется Event-driven подход:
Playwright слушает события браузера и реагирует мгновенно
И это уже жирнючий плюс к скорости PW автотестов!
Подготовил для себя и вас памятку по ожиданиям в PW , сохрани чтобы не потерять :
Явные ожидания элементов на странице:
test('явные ожидания элементов', async ({ page }) => {
await page.goto('https://example.com')
// Ожидание появления элемента
await page.locator('#dynamic-content').waitFor()
// Ожидание видимости
await page.locator('.modal').waitFor({ state: 'visible' })
// Ожидание скрытия
await page.locator('.loading-spinner').waitFor({
state: 'hidden',
timeout: 5000
})
// Ожидание присутствия в DOM
await page.locator('#new-item').waitFor({ state: 'attached' })
// Ожидание удаления из DOM
await page.locator('#removed-item').waitFor({ state: 'detached' })
})
Ожидания страницы:
test('ожидания состояния страницы', async ({ page }) => {
await page.goto('https://example.com')
// Ожидание полной загрузки
await page.waitForLoadState('load')
// Ожидание завершения сетевых запросов
await page.waitForLoadState('networkidle')
// Ожидание готовности DOM
await page.waitForLoadState('domcontentloaded')
// Ожидание конкретного URL
await page.waitForURL('**/dashboard')
})
Ожидание API запросов: (работает из коробки и постоянно использую в АТ)
test('ожидания API запросов', async ({ page }) => {
// Ожидание конкретного запроса
const responsePromise = page.waitForResponse('**/api/users')
await page.locator('#load-users').click()
const response = await responsePromise
expect(response.status()).toBe(200)
// Ожидание запроса с условием
const apiResponse = page.waitForResponse(response =>
response.url().includes('/api/data') && response.status() === 200
)
})
Ожидания событий:
test('ожидания событий браузера', async ({ page }) => {
// Ожидание новой страницы/вкладки
const [newPage] = await Promise.all([
page.context().waitForEvent('page'),
page.locator('#open-new-tab').click()
])
// Ожидание скачивания файла
const [download] = await Promise.all([
page.waitForEvent('download'),
page.locator('#download-btn').click()
])
await download.saveAs('./downloads/' + download.suggestedFilename())
})
И кастомные ожидания с waitForFunction:
test('кастомные ожидания', async ({ page }) => {
await page.goto('https://example.com')
// Ожидание изменения количества элементов
await page.waitForFunction(() => {
return document.querySelectorAll('.item').length > 5
})
})
На собесах, вопросы про ожидания в автотестах тоже часто присутствуют, поэтому сохраняй, чтобы не забыть !
С вас 🎉 если было полезно!
#воскрессобес