Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protractor - How to handle site that is heavily animated?

I have to write tests for a website that is an Angular application and has a ton of Animations. Almost everything has a "mini" window that slides in from the top and goes in the center and then its contents sldie in from the right till they go in it and so on.

This breaks my tests, A LOT. Protractor sees the elements since they are shown but it cant click on them because they are moving and it throws an error saying that other element will receive the click. This happens very often and I do not know how to handle it (except using browser.sleep(xxxx)).

Is there any solution to this except using the sleep function? If I really have no other option I have to use it every on 2nd row...

**I have tried this browser.manage().timeouts().implicitlyWait(30000); and it did not help.

P.S. I also have cases where Protractor tries to click on an element before it is visible.

I can make a short video to show what are the animations if its needed.

test.describe('Profile tests: ', function(){
this.timeout(0);

test.before(function(){
    browser.get('......');
});

test.it('Change Username', function() {
    var newUsername = 'Sumuser';

    welcome.continueLink.click();  
    bonus.takeBonus.isDisplayed().then(function() {                
        bonus.takeBonus.click();            
    });
    entrance.openEntrance.click();

    browser.sleep(300);
    loginBasic.openNormalLogin.isDisplayed().then(function() {
        loginBasic.openNormalLogin.click();
    });

    browser.sleep(300);
    login.usernameField.isDisplayed().then(function() {
        login.usernameField.sendKeys(username);
    });

    login.passwordField.sendKeys(password);
    login.loginButton.click();
    infoBar.avatar.click();

    browser.sleep(1000);
    myProfile.editProfileButton.click();

    browser.sleep(1000);
    username.field.clear();
    username.field.sendKeys(newUsername);
    editProfileButtons.saveChanges.click();

    browser.sleep(1000);
    myProfile.username.getText().then(function (text){
        expect(text).to.equal(newUsername);
    });
});
});

I have also tried adding the following in my config file to disable animations:

onPrepare: function() {
    var disableNgAnimate = function() {
        angular.module('disableNgAnimate', []).run(['$animate', function($animate) {
            $animate.enabled(false);
        }]);
    };

    browser.addMockModule('disableNgAnimate', disableNgAnimate);
}
like image 805
Darkbound Avatar asked Dec 10 '22 21:12

Darkbound


2 Answers

Explicit waits with browser.wait() might make the tests more reliable.

For instance, wait for element to become clickable:

var EC = protractor.ExpectedConditions;
var elm = element(by.css(".myclass"));

browser.wait(EC.elementToBeClickable(elm), 5000);

You can also entirely turn off angular animations, see:

  • How to disable animations in protractor for angular js application
like image 88
alecxe Avatar answered Jan 15 '23 23:01

alecxe


I have just added an answer to How to disable animations in protractor for angular js appliction that you may find useful - disabling css transitions.

For convenience I'll repeat the important code here. I added a class to one of my stylesheets like:

.notransition * {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  -ms-transition: none !important;
  transition: none !important;
}

... and in protractor, I've got something like:

_self.disableCssAnimations = function() {
  return browser.executeScript("document.body.className += ' notransition';");
};

There may be slicker ways of applying this concept, but the above has worked for me.

like image 25
JcT Avatar answered Jan 16 '23 00:01

JcT