Как надежно дождаться простоя страницы в тесте cypress.io

При использовании cypress.io для тестирования веб-страницы с угловой загрузкой, какой лучший / самый надежный способ определить, когда страница полностью загружена и находится в режиме ожидания. Не только событие onload. Необходимо включить все запросы XHR, завершенные циклы углового дайджеста и весь рендеринг, включая все анимации.

Причина в том, что на этом этапе я хочу проверить, что страница НЕ содержит элемента, и не могу проверить это, пока все вышеперечисленное не будет полностью завершено.

будет эта работа?

dwelle 26.05.2018 10:42

Спасибо за вклад, Dwelle. Это сработает для некоторых из вышеперечисленных случаев, но я не очень доволен изменением кода только для того, чтобы тесты работали, а также удаление этого кода в производстве означает, что мы не тестируем точный код, который находится в производстве. В нашем приложении есть тысячи контроллеров, директив и сервисов, и я ищу единственный метод, чтобы определить, когда страница простаивает. Спасибо, в любом случае.

chrisp_68 29.05.2018 10:21
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
14
2
3 249
2

Ответы 2

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

cy.server();
cy.route('**/api/getData').as('getData');
cy.visit('/home');
cy.wait('@getData');

Или дождаться нескольких маршрутов:

cy.server();
cy.route('**/api/getData').as('getDataX');
cy.route('**/api/getData').as('getDataY');

cy.visit('/home');
cy.wait(['@getDataX', '@getDataY']);

Лучшие практики Cypress: ожидание без необходимости.

Cypress документы на wait Alias.

Это бесполезно, когда у вас отправляются десятки запросов, и последний из них - тот, которого вы хотели дождаться.

Axle 07.10.2020 17:28

Можно дождаться нескольких маршрутов. Проверьте обновленный ответ.

Rui Marques 07.10.2020 19:52

Понятно, но все равно не очень полезно. Недавно я работал над этой проблемой, когда разработчики заставляют приложение выполнять пакетный запрос, когда оно обнаруживает, что кеш приложения не установлен. Если бы я добавил достаточно маршрутов / ожиданий, чтобы соответствовать количеству исходящих запросов в этом случае, есть две вещи, которые были бы неправильными: 1. Тест был бы очень хрупким. 2. Цель ожидания - дождаться завершения загрузки и готовности приложения. Если за это время запрос не будет выполнен, ожидание также не сработает. Наша работа заключалась в том, чтобы выставить флаг загрузки для использования cypress.

Axle 07.10.2020 21:22

Может быть, тест будет хрупким, потому что приложение тоже хрупкое? Проблемы такого рода могут быть похожи на «запах кода», что означает, что это может быть признаком того, что архитектура приложения может быть улучшена.

Rui Marques 08.10.2020 12:01

Это справедливое заявление. В моем сценарии действительно используется нестабильное (устаревшее) приложение, в котором внесение изменений обычно связано с офисной войной. Это не оптимально, но вы должны сделать все возможное, чтобы добраться до хорошего места. Я бы хотел обсудить это с вами дальше, хотя, может быть ... на мета-канале? Понятия не имею, как это работает.

Axle 21.10.2020 19:29

Мне жаль, что у меня не было времени обсудить и проанализировать проблемы, с которыми вы сталкиваетесь, но я думаю, что это будет работать лучше, если вы сможете структурировать проблемы, с которыми вы все еще сталкиваетесь, как вопрос SO, и, возможно, сообщество сможет помочь.

Rui Marques 22.10.2020 10:00

Для записи, что мы сделали для этого, так это добавили новую команду подождите, которую можно использовать следующим образом

cy.waitforpageidle();

Машинопись выглядит следующим образом

Cypress.Commands.add(
"waitforpageidle",
() =>
{
    console.warn("Waiting for page idle state");

    const pageIdleDetector = new PageIdleDetector();

    pageIdleDetector.WaitForPageToBeIdle();
});

Где PageIdleDetector выглядит следующим образом

export class PageIdleDetector
{   
defaultOptions: Object = { timeout: 60000 };

public WaitForPageToBeIdle(): void
{
    this.WaitForPageToLoad();
    this.WaitForAngularRequestsToComplete();
    this.WaitForAngularDigestCycleToComplete();
    this.WaitForAnimationsToStop();
}

public WaitForPageToLoad(options: Object = this.defaultOptions): void
{
    cy.document(options).should((myDocument: any) =>
    {
        expect(myDocument.readyState, "WaitForPageToLoad").to.be.oneOf(["interactive", "complete"]);
    });
}

public WaitForAngularRequestsToComplete(options: Object = this.defaultOptions): void
{
    cy.window(options).should((myWindow: any) =>
    {
        if (!!myWindow.angular)
        {
            expect(this.NumberOfPendingAngularRequests(myWindow), "WaitForAngularRequestsToComplete").to.have.length(0);
        }
    });
}

public WaitForAngularDigestCycleToComplete(options: Object = this.defaultOptions): void
{
    cy.window(options).should((myWindow: any) =>
    {
        if (!!myWindow.angular)
        {
            expect(this.AngularRootScopePhase(myWindow), "WaitForAngularDigestCycleToComplete").to.be.null;
        }
    });
}

public WaitForAnimationsToStop(options: Object = this.defaultOptions): void
{
    cy.get(":animated", options).should("not.exist");
}

private getInjector(myWindow: any)
{
    return myWindow.angular.element(myWindow.document.body).injector();
}

private NumberOfPendingAngularRequests(myWindow: any)
{
    return this.getInjector(myWindow).get('$http').pendingRequests;
}

private AngularRootScopePhase(myWindow: any)
{
    return this.getInjector(myWindow).get("$rootScope").$$phase;
}

}

Большое спасибо! Ваш PageIdleDetector великолепен, именно то, что нам нужно

Bruno Schäpper 31.05.2021 07:40

Другие вопросы по теме