web-dev-qa-db-fra.com

Comment puis-je attendre une condition?

Je suis nouveau sur le rapporteur et j'essaie de mettre en œuvre un test e2e ... Je ne sais pas si c'est la bonne façon de faire cela, mais ... n'est pas une page angulaire complète, alors ... j'ai des problèmes.

Sur mon premier essai, j'ai: 

describe('should open contact page', function() {
var ptor = protractor.getInstance();

beforeEach(function(){

   var Login = require('./util/Login');
   new Login(ptor);
});

J'ai créé cette classe de connexion, mais après la connexion, je souhaite ouvrir la page de contact, mais le rapporteur tente immédiatement de trouver l'élément avant que la page ne soit complètement chargée.

J'ai essayé d'utiliser:

browser.driver.wait(function() {

    expect(browser.findElement(by.xpath("//a[@href='#/contacts']")).isDisplayed());
    ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();

});

Mais cela ne fonctionne pas ... il essaie toujours de trouver l'élément avant le chargement de la page ..__ J'ai aussi essayé celui-ci:

browser.driver.wait(function() {
    expect(ptor.isElementPresent(by.xpath("//a[@href='#/contacts']")));          
    ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();
});

Je suis capable de le faire en utilisant browser.sleep(); mais je ne pense pas que ce soit une bonne option. Une idée? Sur mon cours de connexion, j'ai:

ptor.ignoreSynchronization = true;

Comment puis-je attendre ce @href='#/contacts avant que le rapporteur tente de cliquer dessus?

48
Muratso

J'ai eu le même problème que vous aviez depuis très longtemps en utilisant rapporteur. Dans mon test e2e, je commence dans une application non angulaire, puis j'entre dans une partie angulaire, puis je retourne à une partie non angulaire. J'ai rendu les choses difficiles. La clé est de comprendre les promesses et leur fonctionnement. Voici quelques exemples de mon code du monde réel dans un test e2e qui fonctionne. En espérant que cela vous donne une idée de la structure de vos tests. Probablement une mauvaise pratique dans ce code, n'hésitez pas à l'améliorer, mais je sais que cela fonctionne, peut-être pas la meilleure façon.

Pour arriver à angulaire j'utilise

var ptor;
var events = require('events');
var eventEmitter = new events.EventEmitter();
var secondClick = require('./second-click');

beforeEach(function () {
    browser.driver.get('http://localhost:8080/');
},10000);

it("should start the test", function () {
    describe("starting", function () {
        it("should find the  link and start the test", function(){
            var elementToFind = by.linkText('Start'); //what element we are looking for
            browser.driver.isElementPresent(elementToFind).then(function(isPresent){
                expect(isPresent).toBe(true); //the test, kind of redundant but it helps pass or fail
                browser.driver.findElement(elementToFind).then(function(start){
                    start.click().then(function(){ //once we've found the element and its on the page click it!! :) 
                        ptor = protractor.getInstance(); //pass down protractor and the events to other files so we can emit events
                        secondClick(eventEmitter, ptor); //this is your callback to keep going on to other actions or test in another file
                    });
                });
            });
        });
    });
},60000);

En mode angulaire, ce code fonctionne

 describe("type in a message ", function(){
        it("should find and type in a random message", function(){
            var elementToFind = by.css('form textarea.limited');
            browser.driver.isElementPresent(elementToFind).then(function(isPresent){
                element(elementToFind).sendKeys(randomSentence).then(function(){
                    console.log("typed in random message");
                    continueOn();
                });
            });
        });
    },15000);

Après avoir quitté angulaire

browser.driver.wait(function(){
   console.log("polling for a firstName to appear");
   return    browser.driver.isElementPresent(by.name('firstName')).then(function(el){
         return el === true;
       });
     }).
   then(function(){
       somefunctionToExecute()
    });

J'espère que cela vous guidera et vous aidera!

23
asherrard

Protractor 1.7.0 a également introduit une nouvelle fonctionnalité: Conditions attendues .

Il existe plusieurs conditions prédéfinies à attendre explicitement. Si vous souhaitez attendre qu'un élément devienne présent:

var EC = protractor.ExpectedConditions;

var e = element(by.id('xyz'));
browser.wait(EC.presenceOf(e), 10000);

expect(e.isPresent()).toBeTruthy();

Voir également:

51
alecxe

Je découvre enfin ...

   var waitLoading = by.css('#loading.loader-state-hidden');

   browser.wait(function() {
       return ptor.isElementPresent(waitLoading);
   }, 8000);

   expect(ptor.isElementPresent(waitLoading)).toBeTruthy();

   var openContact = by.xpath("//a[@href='#/contacts']");
   element(openContact).click();

Avec ce rapporteur, on pouvait attendre cet élément jusqu'à ce que la page de chargement disparaisse .. Merci pour ceux qui ont essayé d'aider XD.

33
Muratso
browser.driver.wait(function() {
    return browser.driver.isElementPresent(by.xpath("//a[@href='#/contacts']"));
});

Cela fonctionne pour moi aussi (sans le paramètre timeout) ..

pour plus d'informations, voir http://angular.github.io/protractor/#/api?view=webdriver.WebDriver.prototype.wait

9
Henry Neo

Merci aux réponses ci-dessus, c'était mon utilisation simplifiée et mise à jour

function waitFor (selector) {
  return browser.wait(function () {
    return browser.isElementPresent(by.css(selector));
  }, 50000);
}
1
Kirk Strobeck

Je suis surpris que personne n'a ajouté cette solution. Fondamentalement, si vous utilisez des dialogues modaux, vous obtenez souvent un élément visible et disponible pour cliquer mais qui ne peut pas être cliqué en raison du dialogue modal qui le précède. Cela est dû au fait que le rapporteur se déplace plus rapidement qu’angle et qu’il est prêt à cliquer sur l’élément suivant pendant qu’il ferme encore le modal.

Je suggère d'utiliser

public async clickElementBug(elementLocator: Locator) {
const elem = await element(elementLocator);
await browser.wait(
  async function() {
    try {
      await elem.click();
      return true;
    } catch (error) {
      return false;
    }
  },
  this.TIMEOUT_MILLIS,
  'Clicking of element failed: ' + elem
);

}

0
Raymond Kelly

Avez-vous essayé de mettre le ng-app dans la balise <html> (en supposant que cette partie du code est sous votre contrôle)? Cela a résolu beaucoup de problèmes de synchronisation d’initialisation.

0
Konstantin A. Magg

Meilleure façon d'utiliser les conditions d'attente dans le rapporteur qui permet d'afficher le message d'erreur approprié à un élément en cas d'échec du scénario de test

const EC = ExpectedConditions;
const ele = element(by.xpath(your xpath));

return browser.wait(EC.visibilityOf(ele),9000,'element not found').then(() => {
            ele.click();
         });
0
rohit saini