Cypress испускает ряд событий во время выполнения в вашем браузере.
Эти события полезны не только для управления поведением вашего приложения, но и для целей отладки.
Вот несколько примеров, которые вы можете выполнить с этими событиями:
- Прослушивайте
uncaught exceptions и предотвращайте провал теста Cypress - Прослушивайте вызовы
alert или confirm и изменяйте поведение confirm - Прослушивайте события
window:before:load и изменяйте window перед выполнением любого из кода вашего приложения между переходами на страницы - Прослушивайте события
command:retry для понимания причин внутреннего повторного выполнения Cypress для целей отладки
Типы событий
События приложения
Эти события поступают от приложения, которое в настоящее время тестируется (ваше приложение). Это самые полезные события для прослушивания.
| Событие |
Подробности |
| Имя: |
uncaught:exception |
| Возвращает: |
ошибку (Объект), исполняемый модуль Mocha (Объект)
|
| Описание: |
Срабатывает при возникновении непредвиденной ошибки в вашем приложении. Cypress завершит тест при срабатывании этого события. Возвратите false из этого события, и Cypress не завершит тест. Также полезно для отладки, так как предоставляется фактический экземпляр error. См. рецепт Обработка ошибок. |
| Событие |
Подробности |
| Имя: |
window:confirm |
| Возвращает: |
текст подтверждения (Строка)
|
| Описание: |
Срабатывает, когда ваше приложение вызывает глобальный метод window.confirm(). Cypress автоматически примет подтверждение. Возвратите false из этого события, и подтверждение будет отменено. |
| Событие |
Подробности |
| Имя: |
window:alert |
| Возвращает: |
текст предупреждения (Строка)
|
| Описание: |
Срабатывает, когда ваше приложение вызывает глобальный метод window.alert(). Cypress автоматически примет предупреждение. Вы не можете изменить это поведение. |
| Событие |
Подробности |
| Имя: |
window:before:load |
| Возвращает: |
удаленный браузерный окошко (Объект)
|
| Описание: |
Срабатывает, когда страница начинает загружаться, но прежде чем любой из JavaScript вашего приложения выполнится. Это срабатывает в то же самое время, что и cy.visit() onBeforeLoad обратный вызов. Полезно для изменения окна при переходе на страницу. |
| Событие |
Подробности |
| Имя: |
window:load |
| Возвращает: |
удаленный браузерный окошко (Объект)
|
| Описание: |
Срабатывает после завершения загрузки всех ваших ресурсов после перехода на страницу. Это срабатывает в то же самое время, что и cy.visit() onLoad обратный вызов. |
| Событие |
Подробности |
| Имя: |
window:before:unload |
| Возвращает: |
фактическое событие перед закрытием (Объект)
|
| Описание: |
Срабатывает, когда ваше приложение собирается перейти к другому направлению. Вам предоставляется реальный объект события. Ваше приложение может задать returnValue для события, что полезно для проверки. |
| Событие |
Подробности |
| Имя: |
window:unload |
| Возвращает: |
фактическое событие закрытия (Объект)
|
| Описание: |
Срабатывает, когда ваше приложение закрылось и переходит к другому направлению. Вам предоставляется реальный объект события. Это событие нельзя отменить. |
| Событие |
Подробности |
| Имя: |
url:changed |
| Возвращает: |
новый URL (Строка)
|
| Описание: |
Срабатывает всякий раз, когда Cypress обнаруживает изменение URL вашего приложения. |
События Cypress
Эти события поступают от Cypress, когда он выполняет команды и реагирует на их состояние. Все они полезны для прослушивания в целях отладки.
| Событие |
Подробности |
| Имя: |
fail |
| Возвращает: |
ошибку (Объект), исполняемый модуль Mocha (Объект)
|
| Описание: |
Срабатывает, когда тест завершается неудачно. Привязка к этому событию без повторного возбуждения ошибки предотвратит провал теста. Однако это настоятельно не рекомендуется. Тесты никогда не должны законно завершаться неудачно. Это событие существует, потому что оно чрезвычайно полезно для целей отладки. См. рецепт Обработка ошибок. |
| Событие |
Подробности |
| Имя: |
viewport:changed |
| Возвращает: |
новое область просмотра (Объект)
|
| Описание: |
Срабатывает всякий раз, когда область просмотра изменяется с помощью cy.viewport() или естественным образом, когда Cypress сбрасывает область просмотра по умолчанию между тестами. Полезно для целей отладки. |
| Событие |
Подробности |
| Имя: |
scrolled |
| Возвращает: |
элемент или окно, прокручиваемое (Объект)
|
| Описание: |
Срабатывает всякий раз, когда Cypress прокручивает ваше приложение. Это событие срабатывает, когда Cypress выполняет ожидание и расчет возможности выполнения действий. Он будет прокручивать, чтобы «раскрыть» элементы, которые в данный момент скрыты. Это событие чрезвычайно полезно для отладки, если Cypress считает, что элемент не интерактивен. |
| Событие |
Подробности |
| Имя: |
command:enqueued |
| Возвращает: |
свойства и аргументы команды (Объект)
|
| Описание: |
Срабатывает, когда команда cy сначала вызывается и помещается в очередь для выполнения позже. Полезно для отладки, если вы не уверены в порядке выполнения команд. |
| Событие |
Подробности |
| Имя: |
command:start |
| Возвращает: |
экземпляр команды (Объект)
|
| Описание: |
Срабатывает, когда cy начинает фактическое выполнение и выполнение вашей команды. Полезно для отладки и понимания, как обрабатывается асинхронная очередь команд. |
| Событие |
Подробности |
| Имя: |
command:end |
| Возвращает: |
экземпляр команды (Объект)
|
| Описание: |
Срабатывает, когда cy завершает выполнение и выполнение вашей команды. Полезно для отладки и понимания того, как обрабатываются команды. |
| Событие |
Подробности |
| Имя: |
command:retry |
| Возвращает: |
параметры повторного выполнения (Объект)
|
| Описание: |
Срабатывает всякий раз, когда команда начинает свои процедуры повторного выполнения. Это вызывается на заключительном этапе после того, как Cypress внутренне ожидал интервал повторного выполнения. Полезно понять, почему команда повторяет выполнение, и обычно включает фактическую ошибку, вызывающую повторное выполнение. Когда команды завершаются неудачно, окончательная ошибка — это та, которая фактически передается для завершения теста. Это событие по сути предназначено для отладки причин завершения Cypress с ошибкой. |
| Событие |
Подробности |
| Имя: |
log:added |
| Возвращает: |
атрибуты журнала (Объект), находится ли Cypress в интерактивном режиме (выполнение через cypress open) (Булево значение)
|
| Описание: |
Срабатывает всякий раз, когда команда испускает это событие, чтобы его можно было отобразить в журнале команд. Полезно увидеть, как внутренние команды Cypress используют API Cypress.log(). |
| Событие |
Подробности |
| Имя: |
log:changed |
| Возвращает: |
атрибуты журнала (Объект), находится ли Cypress в интерактивном режиме (выполнение через cypress open) (Булево значение)
|
| Описание: |
Срабатывает всякий раз, когда атрибуты команды изменяются. Это событие дебаунсится, чтобы предотвратить его срабатывание слишком быстро и слишком часто. Полезно увидеть, как внутренние команды Cypress используют API Cypress.log(). |
| Событие |
Подробности |
| Имя: |
test:before:run |
| Возвращает: |
атрибуты теста (Объект), экземпляр исполняемого модуля (Объект)
|
| Описание: |
Срабатывает перед запуском теста и всех хуков before и beforeEach. |
| Событие |
Подробности |
| Имя: |
test:after:run |
| Возвращает: |
атрибуты теста (Объект), экземпляр исполняемого модуля (Объект)
|
| Описание: |
Срабатывает после запуска теста и всех хуков afterEach и after. |
Другие события
Существует множество других событий, которые Cypress генерирует для взаимодействия с процессом сервера Node, серверами автоматизации, Mocha, запуском и репортером. Они строго внутренние для работы Cypress и не полезны для пользователей.
Связывание с событиями
Оба глобальных объекта Cypress и cy являются стандартными эмиттерами событий Node. Это означает, что вы можете использовать следующие методы для связывания и отвязывания от событий.
Важно понять, почему вы хотите привязаться к Cypress или cy.
Cypress
Cypress — глобальный объект, который существует на протяжении всех ваших тестов. Любые события, к которым вы привязываетесь в Cypress, будут применяться ко всем тестам и не будут отвязаны, пока вы их не отвяжете вручную.
Это полезно при отладке и позволяет добавить единственное «глобальное» событие для отслеживания таких проблем, как сбои тестов или необработанные исключения из вашего приложения.
cy
Объект cy привязан к каждому отдельному тесту. События, привязанные к cy, будут автоматически удалены при завершении теста. Вам не нужно беспокоиться о завершении работы, и ваши обработчики событий будут вызываться только в течение одного теста.
Примеры
Необработанные исключения
Отключение обработки всех необработанных исключений
// likely want to do this in a support file
// so it's applied to all spec files
// cypress/support/index.js
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from
// failing the test
return false
})
Условное отключение обработки необработанных исключений для определенной ошибки
// likely want to do this in a support file
// so it's applied to all spec files
// cypress/support/index.js
Cypress.on('uncaught:exception', (err, runnable) => {
// we expect a 3rd party library error with message 'list not defined'
// and don't want to fail the test so we return false
if (err.message.includes('list not defined')) {
return false
}
// we still want to ensure there are no other unexpected
// errors, so we let them fail the test
})
Условное отключение обработки необработанных исключений — необработанных отклонений промисов
// likely want to do this in a support file
// so it's applied to all spec files
// cypress/support/index.js
Cypress.on('uncaught:exception', (err, runnable, promise) => {
// when the exception originated from an unhandled promise
// rejection, the promise is provided as a third argument
// you can turn off failing the test in this case
if (promise) {
return false
}
// we still want to ensure there are no other unexpected
// errors, so we let them fail the test
})
Перехват единственного необработанного исключения
it('is doing something very important', (done) => {
// this event will automatically be unbound when this
// test ends because it's attached to 'cy'
cy.on('uncaught:exception', (err, runnable) => {
expect(err.message).to.include('something about the error')
// using mocha's async done callback to finish
// this test so we prove that an uncaught exception
// was thrown
done()
// return false to prevent the error from
// failing this test
return false
})
// assume this causes an error
cy.get('button').click()
})
Перехват сбоев тестов
Отладка момента сбоя теста
// if you want to debug when any test fails
// You likely want to put this in a support file,
// or at the top of an individual spec file
Cypress.on('fail', (error, runnable) => {
debugger
// we now have access to the err instance
// and the mocha runnable this failed on
throw error // throw error to have test still fail
})
it('calls the "fail" callback when this test fails', () => {
// when this cy.get() fails the callback
// is invoked with the error
cy.get('element-that-does-not-exist')
})
Прочитайте Cypress Metaprogramming для получения дополнительных примеров.
Навигация по страницам
Проверка перенаправления вашего приложения
// app code
$('button').on('click', (e) => {
// change the page programmatically
window.location.href = '/some/new/link'
})
// test code
it('redirects to another page on click', (done) => {
// this event will automatically be unbound when this
// test ends because it's attached to 'cy'
cy.on('window:before:unload', (e) => {
// no return value on the event
expect(e.returnValue).to.be.undefined
})
cy.on('window:unload', (e) => {
// using mocha's async done callback to finish
// this test so we are guaranteed the application
// was unloaded while navigating to the new page
done()
})
// click the button causing the page redirect
cy.get('button').click()
})
Окно Before Load
Изменение вашего приложения перед его загрузкой после переходов на страницы
it('can modify the window prior to page load on all pages', () => {
// create the stub here
const ga = cy.stub().as('ga')
// prevent google analytics from loading
// and replace it with a stub before every
// single page load including all new page
// navigations
cy.on('window:before:load', (win) => {
Object.defineProperty(win, 'ga', {
configurable: false,
get: () => ga, // always return the stub
set: () => {}, // don't allow actual google analytics to overwrite this property
})
})
cy
// window:before:load will be called here
.visit('/first/page')
.then((win) => {
// and here
win.location.href = '/second/page'
})
// and here
.get('a')
.click()
})
Окно Confirm
Управление принятием или отклонением подтверждений
Это позволяет протестировать реакцию вашего приложения на подтверждения и отклонения.
// app code
$('button').on('click', (e) => {
const one = confirm('first confirm')
if (one) {
const two = confirm('second confirm')
if (!two) {
const three = confirm('third confirm')
confirm('third confirm was ' + three)
}
}
})
// test code
it('can control application confirms', (done) => {
let count = 0
// make sure you bind to this **before** the
// confirm method is called in your application
//
// this event will automatically be unbound when this
// test ends because it's attached to 'cy'
cy.on('window:confirm', (str) => {
count += 1
switch (count) {
case 1:
expect(str).to.eq('first confirm')
// returning nothing here automatically
// accepts the confirmation
case 2:
expect(str).to.eq('second confirm')
// reject the confirmation
return false
case 3:
expect(str).to.eq('third confirm')
// don't have to return true but it works
// as well
return true
case 4:
expect(str).to.eq('third confirm was true')
// using mocha's async done callback to finish
// this test so we are guaranteed everything
// got to this point okay without throwing an error
done()
}
})
// click the button causing the confirm to fire
cy.get('button').click()
})
it('could also use a stub instead of imperative code', () => {
const stub = cy.stub()
// not necessary but showing for clarity
stub.onFirstCall().returns(undefined)
stub.onSecondCall().returns(false)
stub.onThirdCall().returns(true)
cy.on('window:confirm', stub)
cy.get('button')
.click()
.then(() => {
expect(stub.getCall(0)).to.be.calledWith('first confirm')
expect(stub.getCall(1)).to.be.calledWith('second confirm')
expect(stub.getCall(2)).to.be.calledWith('third confirm')
expect(stub.getCall(3)).to.be.calledWith('third confirm was true')
})
})
Окно Alert
Проверка текста алерта
Cypress автоматически принимает алерт, но вы всё равно можете проверить текст.
// app code
$('button').on('click', (e) => {
alert('hi')
alert('there')
alert('friend')
})
it('can assert on the alert text content', () => {
const stub = cy.stub()
cy.on('window:alert', stub)
cy.get('button')
.click()
.then(() => {
expect(stub.getCall(0)).to.be.calledWith('hi')
expect(stub.getCall(1)).to.be.calledWith('there')
expect(stub.getCall(2)).to.be.calledWith('friend')
})
})
Примечания
Ведение журнала всех событий
Cypress использует модуль debug как для серверного процесса на стороне сервера, так и для всего, что работает в браузере (так называемый драйвер).
Если вы хотите увидеть (обширный) поток событий, которые генерирует Cypress, вы можете открыть свои Dev Tools и ввести эту строку в консоли.
localStorage.debug = 'cypress:*'
Перезагрузите браузер и включите «подробные» логи, чтобы увидеть сообщения отладки в консоли Developer Tools.