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





Вы можете заставить 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.
Это бесполезно, когда у вас отправляются десятки запросов, и последний из них - тот, которого вы хотели дождаться.
Можно дождаться нескольких маршрутов. Проверьте обновленный ответ.
Понятно, но все равно не очень полезно. Недавно я работал над этой проблемой, когда разработчики заставляют приложение выполнять пакетный запрос, когда оно обнаруживает, что кеш приложения не установлен. Если бы я добавил достаточно маршрутов / ожиданий, чтобы соответствовать количеству исходящих запросов в этом случае, есть две вещи, которые были бы неправильными: 1. Тест был бы очень хрупким. 2. Цель ожидания - дождаться завершения загрузки и готовности приложения. Если за это время запрос не будет выполнен, ожидание также не сработает. Наша работа заключалась в том, чтобы выставить флаг загрузки для использования cypress.
Может быть, тест будет хрупким, потому что приложение тоже хрупкое? Проблемы такого рода могут быть похожи на «запах кода», что означает, что это может быть признаком того, что архитектура приложения может быть улучшена.
Это справедливое заявление. В моем сценарии действительно используется нестабильное (устаревшее) приложение, в котором внесение изменений обычно связано с офисной войной. Это не оптимально, но вы должны сделать все возможное, чтобы добраться до хорошего места. Я бы хотел обсудить это с вами дальше, хотя, может быть ... на мета-канале? Понятия не имею, как это работает.
Мне жаль, что у меня не было времени обсудить и проанализировать проблемы, с которыми вы сталкиваетесь, но я думаю, что это будет работать лучше, если вы сможете структурировать проблемы, с которыми вы все еще сталкиваетесь, как вопрос SO, и, возможно, сообщество сможет помочь.
Для записи, что мы сделали для этого, так это добавили новую команду подождите, которую можно использовать следующим образом
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 великолепен, именно то, что нам нужно
будет эта работа?