J'ai un test de rapporteur pour la page de connexion, qui soumet des crédits et vérifie si la page d'index est chargée. Je passe une fonction de rappel à la fonction then du clic sur le bouton, en supposant que le rappel sera appelé après la résolution de la promesse retournée par la fonction click.

var protractor = require('protractor')
describe('E2E: main page', function() {
  beforeEach(function() {
    browser.get('http://localhost:8001/login.html/');
  });
  it("login in the portal", function(){
    var d = protractor.promise.defer();
    element(by.model('loginParams.email')).sendKeys('saravana0209@r.com');
    element(by.model('loginParams.password')).sendKeys('password');
    element(by.name('normalLogin')).click().then(function(){
        //it crashes here before selecting the sub menu item
        element(by.xpath('//a[@title="subMenuItem"]')).click()
        console.log("sub-menu item has been chosen in the ribbon")
        setTimeout(function() { d.fulfill('ok')}, 50000)
    })
    expect(d).toBe('ok');
  })
});

Mais le rappel est appelé, lorsque le chargement de la page est en cours et qu'il plante le test, puisque l'élément avec title, subMenuItem n'est toujours pas chargé. L'erreur est,

Error: Failed: invalid selector: Unable to locate an element with the xpath expression //a[@title="Venues"] because of the following error:
TypeError: Failed to execute 'createNSResolver' on 'Document': parameter 1 is not of type 'Node'.
3
user2879704 19 juil. 2015 à 08:11

2 réponses

Meilleure réponse

Vous pouvez attendre que le sous-menu soit visible avant de faire un clic:

var EC = protractor.ExpectedConditions;

element(by.name('normalLogin')).click().then(function() {
    var subMenu = element(by.xpath('//a[@title="subMenuItem"]'));

    browser.wait(EC.visibilityOf(subMenu), 5000);
    subMenu.click();

    console.log("sub-menu item has been chosen in the ribbon");
    setTimeout(function() { d.fulfill('ok')}, 50000);
});

Comme il semble que tous les problèmes proviennent du bootstraping angulaire manuel , vous devriez doit utiliser browser.driver.get():

Si votre page démarre manuellement, Protractor ne pourra pas charger votre page à l'aide de browser.get. À la place, utilisez l'instance de base du pilote Web - browser.driver.get. Cela signifie que Protractor ne sait pas quand votre page est complètement chargée et vous devrez peut-être ajouter une instruction d'attente pour vous assurer que vos tests évitent les conditions de concurrence.

Ce qui pourrait conduire à quelque chose comme:

element(by.name('normalLogin')).click(); 
browser.sleep(3000); 
browser.driver.get("index.html");

Connectez-vous, laissez-le vous connecter en ayant un délai (le sommeil est mauvais, oui) et récupérez manuellement la page d'index après.


Vous pouvez également travailler avec une synchronisation désactivée entre le rapporteur et angulaire en définissant le browser.ignoreSynchronization = true;, mais cela présente de nombreux inconvénients - vous devriez commencer à utiliser beaucoup d'attentes explicites (browser.wait()). Vous pouvez cependant essayer de jouer avec cet indicateur et de le définir temporairement sur true avant de charger une page et de revenir sur false après.

9
alecxe 19 juil. 2015 à 15:42

Avez-vous essayé cela?:

 element(by.name('normalLogin')).click()
    browser.wait(function() {
      return browser.driver.isElementPresent(by.xpath('//a[@title="Venues"]'))
    }).then(function(){
         var venueLink = by.xpath('//a[@title="Venues"]')
         browser.driver.isElementPresent(venueLink).then(function(){
           console.log("tenant login process successful")
           element(venueLink).click()
        })
    });

Le rapporteur fonctionne de manière asynchrone, donc

var venueLink = by.xpath('//a[@title="Venues"]')

Sera exécuté pendant

browser.wait(function() {
      return browser.driver.isElementPresent(by.xpath('//a[@title="Venues"]'))
    })
1
jasuch 20 juil. 2015 à 09:50