Karma: Allow setting of browser dimensions

Created on 28 Mar 2013  路  23Comments  路  Source: karma-runner/karma

For some basic visual tests it would be nice to be able to specify a browser window size. This would allow for checking dimensions of various elements, viewport, etc.

Most helpful comment

For anyone who is coming here from Google and has this problem: I wrote a simple karma plugin called karma-viewport which enables testing of responsive features at ease, as long as karma runs inside an iframe (default).

All 23 comments

I get around this by setting element dimensions with javascript/jquery prior to testing, (which also works for headless PhantomJS tests) is that approach good enough?

@psyked +1

An example of how to do this would be helpful. I've been spending most of my day trying to figure out how to test with specific custom viewport sizes and so far I haven't come up with much.

For my tests, it was enough to be calling $('container'),width(800).height(600); prior to measuring and/or testing values. I'm fairly confident you can do the same at the document level if needs be, and with raw Javascript instead of jQuery.

I'm using Jasmine for the tests, so I could do this in the beforeEach section ahead of my tests, and for some slightly funky tests we also found success using the Jasmine Mock Clock to handle things which used setTimeout or required re-renders of the page before testing values.

This issue shouldn't be considered "closed".
The workaround suggested by @psyked might be acceptable depending on the case, but it's not a solution.

PhantomJS (and other browsers) do allow to control the window size: the issue is that you need to do it from the outer context, not from within the page/frame context.

PhantomJS has specific API for it: Karma could simple get some extra config parameters to set the page size before running the tests.
For other browsers, I guess it depends on the "launcher" implementation.

Anyhow, if I was a karma contributor, I'd consider this feature.

@detro can you expand on how that approach is not a viable solution? What is your scenario where this solution is not working?

This is what we (at my job) do and it's working fine for us:

describe('when window is resized to fit content', function() {
  beforeEach(function() {
    element.css('width', '5000px');
    $(window).trigger('resize');
    scope.$digest();
  });

  it('should remove content pane preview class', function() {
    expect(element.single('.content')).not.toHaveClass('preview');
  });
});

We can reopen this issue if we conclude that Karma has to support this.

Thanks for your feedback

@sylvain-hamel I see your point and, as I said, the approach might work for specific cases.
But, aside from having to rely on jQuery to trigger an event, I think it's just not OK to pretend when it would be very easy to do the "real deal".

I was discussing earlier with the colleague that started this coversation about window resizing internally: won't be a good idea to have karma expose "special api" within the test scope, and have those wire to the outside scope to do window resizing?

This way the test could actually be about "test that at this window size that my responsive CSS/JS does what is suppose to do".

I'm sure there are plenty of other ways to circumvent the need. But if the Browsers do support such things, why not try to use them?

"This way the test could actually be about "test that at this window size that my responsive CSS/JS does what is suppose to do".

+1 for this feature in order to achieve the above

@detro I think this tests more integration tests.
I prefer approach @psyked in most cases you can avoiding use _live DOM_ for testing.
Also this issue more for launchers than karma itself.

Thanks!

I disagree: the launcher would have to expose the feature, but karma should provide it.

But I don't have enough bandwidth to provide a PR so, as you guys wish.

@sylvain-hamel, correct me if I'm wrong, but it seems to me that your work-around does not actually change the width of the window but rather some container element. It works for some cases, but it's really not the same as being able to drive the browser's size programmatically. I have a few components that rely on <body> width, which I believe is always linked to the size of the window, and I'd like to be able to automatically test with a live browser.

@jacobq, you are right, it wouldn't work in your case.

@vojtajina was this closed because it was deemed to be unnecessary / unhelpful or for another reason (possibly a technical constraint)? It seems like a feature that would allow more thorough testing of code used for responsive web design in a way that isn't otherwise possible. Would you consider re-opening this feature request? If you / the core team agree that it'd be a good fit I wouldn't mind putting in some effort implementing this feature.

Please consider reopening this.

+1, we wonder if it's possible to dynamically change resolution using Karma and Phantom.js, not only setting it in the config file

As @jacobq mentioned above, this solution won't work if you need to test anything that relies on media queries (e.g. any responsive designs) since media queries rely on the dimensions of the window itself.

It appears that PhantomJS has default dimensions of 400x300 when initialized by Karma--would be great if that was customizable so that we can set Phantom's dimensions to mimic a typical desktop browser.

I spoke too soon :)

See the docs for https://github.com/karma-runner/karma-phantomjs-launcher

It is customizable, just add this to karma.conf.js:

customLaunchers: {
  'PhantomJS_Desktop': {
    base: 'PhantomJS',
      options: {
        viewportSize: {
          width: 1228,
          height: 1000
      }
    }
  }
},

Well, I guess whoever implemented it in karma-phantomjs-launcher understood why this made perfect sense.
I'm glad.

@myoung8 Thanks for mentioning karma-phantomjs-launcher! I was hoping karma would have exposed this functionality, but it makes sense to not have karma tie in too much with PhantomJS.

@myoung8 I'm not able to resize the viewport using that config. It seems to be ignored.

Config didn't work for me either, I'm still having issues with media-query dependent code due to being unable to alter the browser resolution.

For anyone who is coming here from Google and has this problem: I wrote a simple karma plugin called karma-viewport which enables testing of responsive features at ease, as long as karma runs inside an iframe (default).

guys, I figured out a solution... I'm running Karma + Jasmine + TypeScript against an Angular app...

consider the following directive (custom html attribute for those of you unfamiliar with Angular):

import { Directive, ElementRef } from '@angular/core';

@Directive({
  selector: '[fullHeight]',
})
export class FullHeightDirective {
  constructor(el: ElementRef) {
    this.resize(el);

    window.onresize = () => this.resize(el);
  }

  private resize (el: ElementRef): void {
    el.nativeElement.style['min-height'] = `${window.innerHeight}px`;
  }
}

notice the window.innerHeight property is setting the style of the current element

Now, for my test fixture:

    it('should set "min-height" style of element', () => {
        // Call 'dispatchEvent' so the window tracks the initial resize
        window.dispatchEvent(new Event('resize'));

        // I cannot set the `innerHeight`, but I can overwrite it with a new property
        (<any>window).innerHeight = 1024;
        window.dispatchEvent(new Event('resize'));   /* Then call the resize event again */
        expect(divEl.nativeElement.style['min-height']).toBe('1024px');

        // Then, set the innerHeight once more
        (<any>window).innerHeight = 700;
        window.dispatchEvent(new Event('resize'));
        expect(divEl.nativeElement.style['min-height']).toBe('700px');
    });
Was this page helpful?
0 / 5 - 0 ratings

Related issues

simonh1000 picture simonh1000  路  3Comments

schippie picture schippie  路  5Comments

VinishaDsouza picture VinishaDsouza  路  3Comments

danielsiwiec picture danielsiwiec  路  5Comments

TKTheTechie picture TKTheTechie  路  4Comments