4

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);
}
Darkbound
  • 3,026
  • 7
  • 34
  • 72

2 Answers2

9

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:

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Turning off the animations is the best way to go. – MBielski Aug 19 '15 at 14:32
  • To add to this a bit, make sure that you are accounting for css animations as well. I'm not sure if there is a way to reliably toggle them off, but make sure to know where they are and have a proper wait for them. – user2020347 Aug 19 '15 at 21:56
  • Thank you for your replies. Unfortunately I can't use ExpectedConditions since I am using the TS Definition for Protractor and it does not support it yet. Even if I could it would not solve the problem since I would have to replace browser.sleep with browser.wait and nothing would actually change. I have updated my main post and I added my test. I want to get rid of all of these `sleeps`. I have tried to disable the animations but it did not work - I added the code that I used in my config file in my main post aswell. Please help! :) – Darkbound Aug 20 '15 at 11:29
  • As you can see using the promises `isDisplayed` is also not helping since I still need a sleep... – Darkbound Aug 20 '15 at 11:31
  • @MBielski I get your point but I don't think that is a correct approach since you are testing your product end functionality. Animations are part of it and you should test it as the user experiences it. – José Manuel Blasco Mar 16 '20 at 10:41
4

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.

Community
  • 1
  • 1
JcT
  • 3,539
  • 1
  • 24
  • 34
  • Thanks, but I don't have the source code for the app, I am just testing it. – Darkbound Aug 31 '15 at 13:34
  • 1
    If you're unable to add any css to the app's source, I would wonder if it might be possible to dynamically add it from within protractor; possibly doing something like this within the function you pass to the `browser.executeScript(...)` call: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule – JcT Sep 01 '15 at 00:04