O que é o browser.ignoreSynchronization no transferidor?

Eu já vi tantas vezes que as pessoas sugerem usar:

browser.ignoreSynchronization=true; // or false 

Mas eu não entendo porque precisamos disso?

A resposta simples é que ele faz com que o transferidor não espere pelas promises angulares, como as de $http ou $timeout a serem resolvidas, o que você pode querer fazer se estiver testando o comportamento durante $http ou $timeout (por exemplo, “message”, ou testar sites ou páginas não angulares, como uma página de login separada.

Por exemplo, para testar um botão que define uma mensagem de carregamento durante uma solicitação, você pode defini-la como true ao buscar um elemento + verificar seu conteúdo

 element(by.css('button[type="submit"]')).click(); browser.ignoreSynchronization = true; expect(element(by.css('.message')).getText().toBe('Loading...'); browser.ignoreSynchronization = false; expect(element(by.css('.message')).getText().toBe('Loaded'); 

Uma resposta mais envolvida é que configurá-la como true significa que adições / injeções subsequentes no stream de controle também não adicionam browser.waitForAngular . Há casos em que uma compreensão do stream de controle e quando / como as coisas são adicionadas / injetadas é importante. Por exemplo, se você estiver usando browser.wait para testar um processo de vários estágios, a function passada para wait é injetada no stream de controle após o restante das funções no teste serem incluídas no stream de controle.

 element(by.css('button[type="submit"]')).click(); browser.ignoreSynchronization = true; expect(element(by.css('.message')).getText().toBe('Stage 1'); browser.wait(function () { // This function is added to the control flow after the final // browser.ignoreSynchronization = false in the test // so we need to set it again here browser.ignoreSynchronization = true; return element(by.cssContainingText('.message', 'Stage 2')).isPresent().then(function(isPresent) { // Cleanup so later tests have the default value of false browser.ignoreSynchronization = false; return !isPresent; }); }); expect(element(by.css('.message')).getText().toBe('Stage 2'); browser.ignoreSynchronization = false; expect(element(by.css('.message')).getText().toBe('Stage 3'); 

Uma alternativa ao uso de browser.ignoreSynchronization é acessar a API padrão do webdriver diretamente

 element(by.css('button[type="submit"]')).click(); expect(browser.driver.findElement(by.css('.message')).getText().toBe('Loading...'); expect(element(by.css('.message')).getText().toBe('Loaded'); 

Usar os methods do driver diretamente para encontrar os elementos significa que o sistema tentará encontrá-los sem esperar que as solicitações $http andamento sejam concluídas, assim como definindo browser.ignoreSynchronization = true .

Essa configuração controla se o transferidor deve aguardar um ângulo em uma página ou não. Não está devidamente documentado, mas aqui está a seqüência de documentação do código :

 /** * If true, Protractor will not attempt to synchronize with the page before * performing actions. This can be harmful because Protractor will not wait * until $timeouts and $http calls have been processed, which can cause * tests to become flaky. This should be used only when necessary, such as * when a page continuously polls an API using $timeout. * * @type {boolean} */ 

Em outras palavras, se você estiver testando em um site não angular, defina a configuração ignoreSynchronization como true . Como um exemplo do mundo real, veja um dos desafios que tive ao abrir uma página não angular a partir de uma página angular: Página não angular aberta após um clique .