Notification API

Notification API предоставляет возможность взаимодействовать с нативными уведомлениями браузера и веб-приложений. В контексте автоматизированного тестирования с помощью Cypress правильная работа с уведомлениями критически важна для проверки пользовательского интерфейса и логики приложения. В браузерах уведомления могут быть системными или веб-специфичными, и Cypress позволяет контролировать их поведение через замены, перехваты и проверки.


Настройка разрешений для уведомлений

Браузеры требуют разрешение на отображение уведомлений. В тестах Cypress можно управлять этим с помощью команды cy.window() и замены объекта Notification:

cy.visit('/example');
cy.window().then((win) => {
    cy.stub(win, 'Notification').callsFake((title, options) => {
        return { title, options, close: cy.stub() };
    });
});

Ключевой момент: использование cy.stub() позволяет перехватывать создание уведомлений, чтобы проверять заголовок, текст и другие параметры без фактического показа системного уведомления.


Создание и проверка уведомлений

Веб-приложения создают уведомления через конструктор Notification:

new Notification('Заголовок', { body: 'Текст уведомления' });

Для проверки этого в тесте Cypress используется следующий подход:

cy.window().then((win) => {
    const notificationStub = cy.stub(win, 'Notification');
    // Действие, которое вызывает уведомление
    cy.get('#notifyButton').click().then(() => {
        expect(notificationStub).to.have.been.calledOnce;
        expect(notificationStub.firstCall.args[0]).to.eq('Заголовок');
        expect(notificationStub.firstCall.args[1]).to.deep.equal({ body: 'Текст уведомления' });
    });
});

Важное замечание: Cypress не отображает нативные уведомления, поэтому проверка должна выполняться через перехват вызова конструктора.


Проверка интерактивных уведомлений

Некоторые уведомления содержат действия (actions) или события (onclick, onclose). Их можно тестировать через мок-объект:

cy.window().then((win) => {
    const notificationStub = cy.stub(win, 'Notification').callsFake((title, options) => {
        const notification = {
            title,
            options,
            onclick: options.onclick || cy.stub(),
            close: cy.stub(),
        };
        return notification;
    });

    cy.get('#notifyButton').click().then(() => {
        const notification = notificationStub.firstCall.returnValue;
        notification.onclick();
        // Проверка реакции приложения на клик по уведомлению
        cy.get('#status').should('contain', 'Уведомление открыто');
    });
});

Ключевой момент: имитация событий уведомления позволяет полностью тестировать интерактивное поведение без реальных системных уведомлений.


Работа с асинхронными уведомлениями

Иногда уведомление создается с задержкой, например после завершения запроса к API. Cypress предоставляет механизмы ожидания:

cy.window().then((win) => {
    const notificationStub = cy.stub(win, 'Notification');
    
    cy.get('#fetchDataButton').click();
    
    cy.wrap(null).should(() => {
        expect(notificationStub).to.have.been.called;
    });
});

Подсказка: использование cy.wrap().should() позволяет повторно проверять вызов уведомления до его появления, что предотвращает проблемы с асинхронностью.


Интеграция с Cypress Commands

Можно вынести логику проверки уведомлений в пользовательскую команду Cypress для удобства повторного использования:

Cypress.Commands.add('assertNotification', (title, options) => {
    cy.window().then((win) => {
        expect(win.Notification).to.have.been.calledWith(title, options);
    });
});

// Использование
cy.get('#notifyButton').click();
cy.assertNotification('Заголовок', { body: 'Текст уведомления' });

Преимущество: пользовательские команды делают тесты более читаемыми и уменьшают дублирование кода.


Особенности браузеров и ограничения

  • В Chrome и Firefox уведомления блокируются по умолчанию при автоматизации. Cypress заменяет объект Notification, чтобы обойти это.
  • Safari имеет ограниченную поддержку Notification API в контексте автоматизированного тестирования.
  • Проверка визуального отображения уведомлений невозможна без сторонних инструментов типа Percy или Cypress Component Testing.

Рекомендации по тестированию Notification API

  1. Всегда использовать cy.stub() или cy.spy() для перехвата уведомлений.
  2. Проверять заголовок и тело уведомления, а также любые колбэки (onclick, onclose).
  3. Для асинхронных уведомлений применять cy.wrap().should() или cy.wait() с разумными таймаутами.
  4. Вынести повторяющуюся логику проверки в пользовательские команды.
  5. Документировать ограничения браузеров для уведомлений, чтобы тесты были предсказуемыми.