Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to explain using browser.sleep in protractor

I'm a new to protractor,and I'm trying to test popover event, here is my code:

    describe('popover directive', function() {
        var buttons= element.all(by.tagName('button'));

        it('should show the popover title by clicking', function() {
            var popTitle="testTitle";               
            var popContent="testContent";                   

            element(by.model('title')).clear().sendKeys(popTitle);     
            element(by.model('content')).clear().sendKeys(popContent).then(function(){
                 buttons.get(0).click().then(function(){
                     browser.sleep(1000);
                     expect(element(by.className('popover-title')).getText()).toMatch(popTitle);                
                     expect(element(by.className('popover-content')).getText()).toMatch(popContent);
                 });    
             });                    
            buttons.get(0).click(); 
            browser.sleep(1000);      
            expect(element(by.css('[class="popover fade top in"]')).isPresent()).toBe(false);      
        });
    }); 

1.If I don't add delay time code like browser.sleep(), the test will fail and show a message:

NoSuchElementError: No element found using locator: By.className('popover-title')

Is that possible not to add delay time code ...like browser.sleep()? If that is impossible, how to make sense to set the sleep time well? Is that have some connection with CSS animations?

2.Using browser.waitForAngular() or click().then(function(){...}) instead of browser.sleep() seems no work, will get the same error message.

That would be great if someone can answer these questions, thanks a lot.

like image 265
Kiry Avatar asked Jan 21 '15 09:01

Kiry


1 Answers

The reason that you had to add a sleep is likely because of your animation. Many animations use setTimeout, which Angular (thus Protractor) does not know about and do not wait for. The angular equivalent to setTimeout is its $timeout service.

But often you cannot change the animation library to stop using setTimeout. To work with this in protractor, use browser.wait with a timeout (not sleep).

buttons.get(0).click(); 

browser.wait(function() {
  return element(by.css('[class="popover fade top in"]')).isPresent().then(function(present) {
    return !present;
  });
  // or by checking any other element to know that the animation completed
}, 1000);

expect(element(by.css('[class="popover fade top in"]')).isPresent()).toBe(false);      

With Protractor 1.7, you will be able to use the expectedConditions library so you can do this:

var EC = protractor.ExpectedConditions
buttons.get(0).click(); 

var e = element(by.css('[class="popover fade top in"]'));
browser.wait(EC.not(EC.presenceOf(e)), 1000);

expect(e.isPresent()).toBe(false); 
like image 55
hankduan Avatar answered Sep 28 '22 19:09

hankduan