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

Мы хотим углубиться в две возможные проблемы синхронизации, с которыми вы можете столкнуться при работе с Protractor — комплексной тестовой средой для приложений Angular и AngularJS. Хорошая новость в том, что есть официальная документация от команды Protractor, но плохая новость в том, что она не помогла нам решить эти проблемы, поэтому мы поделимся найденным решением.

Ошибка «Angular не найден на странице»

Давайте проверим базовое решение Часто задаваемые вопросы о Protractor:

Protractor поддерживает Angular и AngularJS 1.0.6/1.1.4 и выше. Убедитесь, что ваша версия Angular обновлена. Для приложений AngularJS переменная angular должна быть доступна в глобальном контексте. .

Чтобы проверить это, попробуйте открыть Chrome DevTools или Firefox и посмотреть, определен ли angular. Для приложений Angular вы должны увидеть глобальный метод getAllAngularTestabilities.

Ошибка тайм-аута «Ожидание Angular»

Асинхронные и многокомпонентные тесты WebDriver могут вызывать различные ошибки тайм-аута в тесте Protractor. Одной из них может быть ошибка Ожидание Angular. Вот информация из Protractor’s Documentation:

Прежде чем выполнять какое-либо действие, Protractor ждет, пока в вашем приложении Angular не останется ожидающих выполнения асинхронных задач. Это означает, что все тайм-ауты и HTTP-запросы завершены.

  • Ошибка в результатах теста будет выглядеть следующим образом: Истекло время ожидания завершения асинхронных задач Angular через 11 секунд.
  • Время ожидания по умолчанию: 11 секунд
  • Как изменить: добавьте allScriptsTimeout: timeout_in_millis в файл конфигурации Protractor.

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

AngularJS

Если ваше приложение AngularJS постоянно опрашивает $timeout или $http, Protractor будет ждать неопределенное время и истечет время ожидания. Чтобы исправить бесконечное время ожидания, вы должны использовать $interval для всего, что опрашивает непрерывно (Примечание: $interval был введен в Angular 1.2rc3).

Угловой

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

Пример:

this.ngZone.runOutsideAngular(() => { 
  setTimeout(() => { // Changes here will not propagate into your view. 
   this.ngZone.run(() => { // Run inside the ngZone to trigger change detection. 
  }); 
}, REALLY_LONG_DELAY); });

Устранение ошибок

Так как подсказки из официальной документации не помогли нам так, как мы ожидали, мы попробовали отключить синхронизацию. Тем не менее, это вызвало большое количество проблемэлементам страницы не хватило времени для загрузки, и тест не прошел. Ожидание загрузки элементов страницы потребует от нас создания дополнительных функций. Не лучший способ. Мы были расстроены, но остались решительны. Мы пришли к следующему решению, чтобы покрыть обе ошибки:

  1. Создайте небольшой тест, содержащий одно действие для навигации по странице и одно утверждение, отображающее элемент.
  2. Определите причину проблемы:
if ('You are sure that all your application is written with Angular, but you get the error "Angular could not be found on the page"') {   
  try { 
    browser.waitForAngularEnabled(false); 
    browser.get('/your-page.html'); 
    expect(element(by.id('logo')).isDisplayed()).toBeTruthy(); 
// If this code works, check out examples of detected code parts below in this article.  
      } 
} else if ('You are not sure that all your application is written with Angular') { 
  try { 
    checkItManuallyforAngularJS = 'For AngularJS apps, the angular variable is expected to be available in the global context. Try opening Chrome DevTools or Firefox and see if Angular is defined.'; 
    checkItManuallyforAngular = 'For Angular apps, you should see a global method getAllAngularTestabilities.'; 
   } 
// Can't manually check? Check the hints on identifying technologies the site is built on* 
} else if ('You are sure that the main part of your application is written with Angular, but login page (or any other) isn't.') { 
  try { 
     browser.waitForAngularEnabled(false); 
     browser.get('/non-angular-login-page.html'); 
     element(by.id('username')).sendKeys('Jane'); 
     element(by.id('password')).sendKeys('1234'); 
     element(by.id('button')).click(); 
     browser.waitForAngularEnabled(true); 
     browser.get('/page-containing-angular.html');  
   } 
}

* Вот подсказки по определению технологий, на которых построен сайт.

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

3. Для каждой части приложения, написанной не с использованием Angular, используйте следующую функцию:

browser.waitForAngularEnabled(false);

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

browser.waitForAngularEnabled(true);

4. Обнаружить код, который нужно переписать:

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

а. Найдите все функции setInterval, Observable.timers, таймеры и т. д.

б. Закомментируйте все найденные части, соберите приложение и запустите небольшой тест (обязательно включите синхронизацию).

в. Повторяйте шаги 4.a и 4.b, пока тест не будет пройден.

д. Вернитесь к закомментированным строкам кода. Методом исключения раскомментируйте все части, не относящиеся к синхронизации.

е. Когда все части кода, блокировавшие синхронизацию ранее, будут обнаружены, перепишите код импорта ngZone в компонент и используйте функцию runOutsideAngular.

Примеры обнаруженных частей кода

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

Вывод

Излишне говорить, что использование инструментов с открытым исходным кодом делает нашу жизнь проще. К сожалению, при работе с новым инструментом вы часто можете столкнуться с различными проблемами и не иметь подходящего примера их устранения. Отсутствие исчерпывающей документации и быстрой поддержки иногда может быть проблемой.

Специализируясь на веб-разработке на Angular, нам нужно находить все больше и больше подходящих передовых практик, которым можно следовать. Ранее мы говорили о тестировании Cypress, а в этой статье мы углубились в проблемы синхронизации, которые могут возникнуть при тестировании приложений на основе Angular с помощью Protractor.

Мы надеемся, что после прочтения этой статьи вам еще больше понравится работать с Protractor! Желаем удачи в покорении новых QA-горизонтов!

Первоначально опубликовано на https://valor-software.com.

Если у вас есть вопросы\предложения\комментарии — свяжитесь со мной через:
- Прямые комментарии
- Twitter
- Linkedin