Ошибка при попытке синхронизации Protractor со страницей с базовым тестом на транспортир
describe('my homepage', function() {
var ptor = protractor.getInstance();
beforeEach(function(){
// ptor.ignoreSynchronization = true;
ptor.get('http://localhost/myApp/home.html');
// ptor.sleep(5000);
})
describe('login', function(){
var email = element.all(protractor.By.id('email'))
, pass = ptor.findElement(protractor.By.id('password'))
, loginBtn = ptor.findElement(protractor.By.css('#login button'))
;
it('should input and login', function(){
// email.then(function(obj){
// console.log('email', obj)
// })
email.sendKeys('[email protected]');
pass.sendKeys('shakalakabam');
loginBtn.click();
})
})
});
приведенный выше код возвращает
Error: Error while waiting for Protractor to sync with the page: {}
и я понятия не имею, почему это так, ptor загружает страницу правильно, это, кажется, выбор элементов, которые терпят неудачу.
В SSHMSH:
Спасибо, ты почти прав, и дал мне правильную философию, поэтому ключ к ptor.sleep(3000), чтобы каждая страница подождала, пока ptor не синхронизируется с проектом.
Ответы
Ответ 1
Я получил то же сообщение об ошибке (Angular 1.2.13). Мои тесты были начаты слишком рано, и Транспортер, похоже, не дождался загрузки Angular.
Оказалось, что я неправильно сконфигурировал конфигурационный файл транспортира. Если директива ng-app
не определена в элементе BODY, а на потомке, вы должны настроить свойство rootElement
в конфигурационном файле транспортира селектору, который определяет ваш корневой элемент Angular, например:
// protractor-conf.js
rootElement: '.my-app',
когда ваш HTML:
<div ng-app="myApp" class="my-app">
Ответ 2
Я использую ChromeDriver, и вышеприведенная ошибка обычно возникает для первого теста. Мне удалось обойти это следующим образом:
ptor.ignoreSynchronization = true;
ptor.get(targetUrl);
ptor.wait(
function() {
return ptor.driver.getCurrentUrl().then(
function(url) {
return targetUrl == url;
});
}, 2000, 'It\ taking too long to load ' + targetUrl + '!'
);
По сути, вы ожидаете, что текущий URL-адрес браузера станет тем, что вы просили, и разрешите 2s для этого.
Вероятно, вы захотите снова включить ignoreSynchronization = false
, возможно, завернув его в ptor.wait(...)
. Просто интересно, неудобно ли ptor.sleep(5000);
не помогать?
EDIT:
После некоторого опыта работы с Promise/Deferred я понял, что правильный способ сделать это:
loginBtn.click().then(function () {
ptor.getCurrentUrl(targetUrl).then(function (newURL){
expect(newURL).toBe(whatItShouldBe);
});
});
Обратите внимание, что если вы меняете URL-адрес (то есть, удаляясь от текущей активированной страницы AngularJS к другой, подразумевая, что библиотека AngularJS нуждается в перезагрузке и инициализации), чем, по крайней мере, по моему опыту, нет способа избежать вызов ptor.sleep(...)
. Вышеуказанное будет работать только в том случае, если вы остаетесь на той же странице Angular, но измените часть URL после хэштега.
Ответ 3
В моем случае я столкнулся с ошибкой со следующим кодом:
describe("application", function() {
it("should set the title", function() {
browser.getTitle().then(function(title) {
expect(title).toEqual("Welcome");
});
});
});
Исправлено:
describe("application", function() {
it("should set the title", function() {
browser.get("#/home").then(function() {
return browser.getTitle();
}).then(function(title) {
expect(title).toEqual("Welcome");
});
});
});
Другими словами, я забыл перейти к странице, которую я хотел проверить, поэтому у Protractor возникли проблемы с поиском Angular. D'о!
Ответ 4
Параметр rootElement
объекта exports.config
, определенный в файле файла конфигурации транспортира, должен соответствовать элементу, содержащему вашу директиву ng-app
. Это не должно однозначно идентифицировать элемент - 'div' достаточно, если директива находится в div
, как в моем случае.
От referenceConf.js
:
// Selector for the element housing the angular app - this defaults to
// body, but is necessary if ng-app is on a descendant of <body>
rootElement: 'div',
Я начал работу с Протрактор, наблюдая отличную лекцию egghead.io, где он использует сжатый exports.config
. Поскольку rootElement
по умолчанию используется body
, нет никакой подсказки относительно того, что не так с вашей конфигурацией, если вы не начинаете с копии предоставленной ссылочной конфигурации, и даже тогда
Ошибка при ожидании синхронизации Protractor со страницей: {}
Сообщение не дает большой информации.
Ответ 5
Мне пришлось перейти от этого:
describe('navigation', function(){
browser.get('');
var navbar = element(by.css('#nav'));
it('should have a link to home in the navbar', function(){
//validate
});
it('should have a link to search in the navbar', function(){
//validate
});
});
:
describe('navigation', function(){
beforeEach(function(){
browser.get('');
});
var navbar = element(by.css('#nav'));
it('should have a link to home in the navbar', function(){
//validate
});
it('should have a link to search in the navbar', function(){
//validate
});
});
ключевое отличие:
beforeEach(function(){
browser.get('');
});
надеюсь, что это может помочь кому-то.
Ответ 6
ng-app должен быть инициализирован тегом HTML, но не тегом body.
Он начал работать, как только я заменил "ng-app" с тега DIV на тег HTML.