Подтвердить что ты не робот

Ошибка при попытке синхронизации 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 не синхронизируется с проектом.

4b9b3361

Ответ 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.