6

I've found some answers on google, but they don't seem to be applicable to my project.

Some of the answers talked about adding some code to their conf.js file's onPrepare() function, but I don't have that file in my project. I have a file named protractor.config.js, which was in the angular quickstart project by default. Anyway, this config file also has an onPrepare() function, so I tried to add the code from answer #2 in this question: How to disable animations in protractor for angular js application, but then my tests failed with:

message: Failed: Trying to load mock modules on an Angular2 app is not yet supported.
Community
  • 1
  • 1
Jesper
  • 2,644
  • 4
  • 30
  • 65
  • 1
    The answer you are referencing relates to legacy AngularJS and not the Angular (>= 2.x) platform you are using. Basically though you should just need to swap out `BrowserAnimationsModule` with [NoopAnimationsModule](https://angular.io/docs/ts/latest/api/platform-browser/animations/index/NoopAnimationsModule-class.html) according to environment. At least in 4.x. – Neil Lunn May 10 '17 at 03:08
  • @NeilLunn Where to do that? I can't find any `BrowserAnimationModule` in my `protractor.config.js` file. – Jesper May 10 '17 at 14:47
  • @NeilLunn Have you seen my message? :) – Jesper May 16 '17 at 11:00

2 Answers2

8

If you want to disable the Angular 2 animation go for the answer as commented by @NeilLunn. If you want to disable CSS-animations you can override it with a customer css Javascript injection. The script below can be taken as an example. Place it in the onPrepare in your protractor config file

return browser.driver.executeScript(disableCSSAnimation);

function disableCSSAnimation() {
  var css = '* {' +
    '-webkit-transition-duration: 0s !important;' +
    'transition-duration: 0s !important;' +
    '-webkit-animation-duration: 0s !important;' +
    'animation-duration: 0s !important;' +
    '}',
    head = document.head || document.getElementsByTagName('head')[0],
    style = document.createElement('style');

  style.type = 'text/css';
  style.appendChild(document.createTextNode(css));
  head.appendChild(style);
}

What it will do is it will add a piece of custom CSS to override some animations. This will for example prevent a color animation when you hover.

Hope it helps

Update:

The script needs to be injected after loading the url. If you place it in the onPrepare and you don't load the url before injecting the script the script will be injected on the data-url. Using it like this would do the trick

describe('Demo test', () => {
  beforeEach(() => {
    browser.get('http://www.protractortest.org/#/');
    browser.driver.executeScript(disableCSSAnimation);

    function disableCSSAnimation() {
      var css = '* {' +
        '-webkit-transition-duration: 0s !important;' +
        'transition-duration: 0s !important;' +
        '-webkit-animation-duration: 0s !important;' +
        'animation-duration: 0s !important;' +
        '}',
        head = document.head || document.getElementsByTagName('head')[0],
        style = document.createElement('style');

      style.type = 'text/css';
      style.appendChild(document.createTextNode(css));
      head.appendChild(style);
    }
  });

  it('Should go to Protractor test page', () => {
    expect(browser.getTitle()).toEqual('Protractor - end-to-end testing for AngularJS')
  });
});

enter image description here

Important:

Make a method of it so you can re-use it because each time the page reloads / goes to an other url, the script needs to be injected.

This should do the trick in the end. Good luck with it.

wswebcreation
  • 2,365
  • 2
  • 10
  • 18
  • Thanks for your reply. It didn't work unfortunately. This is where I put it: https://gyazo.com/6462058198e0e8c96eb65a370baad172 – Jesper May 10 '17 at 15:09
  • Ok, code looks good. What if you add a `browser.sleep(60000)` and then check the DOM, is the code injected? – wswebcreation May 10 '17 at 17:22
  • Hmm, I'm not able to test it know, will do it tomorrow, let you know – wswebcreation May 10 '17 at 18:59
  • Thanks a lot! Regarding the Angular 2 animations, you told me to go for Neil Lunn's answer. Could you please elaborate on that, because I don't understand what he wants me to do, and he hasn't replied to me. – Jesper May 14 '17 at 01:55
  • Have you seen my message? :) – Jesper May 16 '17 at 11:00
  • @Jesper, sorry, I don't have experience with Angular 2+ animations. We don't use it in the project I work with. Is there a possibility to create a "special" build without the animations from your CI-pipeline? – wswebcreation May 16 '17 at 11:46
  • Alright, no problem. Thanks anyway. I will see if I can find a solution. – Jesper May 16 '17 at 12:15
  • In my case it worked better to add : `transition: none !important;` (and all browsers variations). – BlackHoleGalaxy Apr 04 '18 at 17:50
7

I managed to accomplish this using a query parameter.

Building on Neils answer I was able to update my SharedModule to switch between BrowserAnimationModule and NoopAnimationModule.

I created a method that appends a query parameter that I will look for later. I use this method for all navigation in my tests so I can be sure the parameter is always present.

E2eCommon

public static navigateTo(path: string) {
  browser.get('/' + path + '?qa=true');
  browser.waitForAngular();
}

Then in my module where I declare the animation module I check for the query parameter and based on whether or not it's present I either load BrowserAnimationModule or NoopAnimationModule

shared.module.ts

@NgModule({
  declarations: [
    ...
  ],
  exports: [
    AnimationModule(),
    ...
  ],
  imports: [
    AnimationModule(),
    ...
  ]
})
export class SharedModule { }

export function AnimationModule(): any {
  return window.location.search.indexOf('qa=true') > -1 ? NoopAnimationsModule : BrowserAnimationsModule;
}
efarley
  • 8,371
  • 12
  • 42
  • 65
  • very nice solution. I also abstracted the query param ike this `navigateTo(path: string) { return browser.get(path + "?qa=true"); }` – Nate May Sep 30 '18 at 20:33