angular/angular-cli

Karma with jsdom+custom shims/polyfills should create the right environment for the tests

Open

#17547 opened on Apr 25, 2020

View on GitHub
 (0 comments) (0 reactions) (0 assignees)TypeScript (26,585 stars) (11,999 forks)batch import
area: @angular-devkit/build-angulardevkit/build-angular:karmahelp wanted

Description

🐞 Bug report

Command (mark with an x)

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • xi18n
  • run
  • config
  • help
  • version
  • doc

Is this a regression?

Description

const dom = new JSDOM(`<p>Hello</p>`, {
  beforeParse(window) {
    window.document.childNodes.length === 0;
    window.someCoolAPI = () => { /* ... */ };
  }
});

Luckely the karma-json-launcher offers the posibility to configure the jsdom instance throught karma.conf.js file:

// karma.conf.js
const jsdom = require("jsdom");
 
module.exports = function(config) {
  config.set({
    browsers: ['jsdom'],
    jsdomLauncher: {
      jsdom: {
        beforeParse(window) {
          window.someCoolAPI = () => { /* ... */ };
        }
      }
    }
  });
};

The karma plugin creates the jsdom instance correctly with the passed options, and it tries to parse the url where karma is running. But unfortunalety the someCoolAPI is not present in test context inside window property and test fails with a ReferenceError: someCoolAPI is not defined

On the other hand, when you try to manually create your own jsdom instance (same way karma-json-launcher does), with someCoolAPI polyfill, and parse any html document which use that API inside it works, jsdom parses the document and the scripst are executed correctly, so that makes me think is not a jsdom or karma-jsdom-launcher problem. Can be an issue with the CLI, or Karma itself?

🔬 Minimal Reproduction

$ ng new foo
$ cd foo
$ npm install karma-jsdom-launcher jsdom
  1. Configure angular.json file as @badeball indicates here due to #11561 and #13580
  2. Configure karma.config.js file as karma-jsdom-launcher docs indicates:
// karma.config.js
...
plugins: [
  ....
  require('karma-jsdom-launcher'),
  ....
],
...
browsers: ['jsdom'],
jsdomLauncher: {
  jsdom: {
    beforeParse(window) {
        window.someCoolAPI = () => { /* ... */ };
     }
  }
},
...
  1. Create app.component.ts that uses that someCoolAPI in some way.
@Component({...})
export class AppComponent {
  constructor() {
    window.someCoolAPI();  //the test will fail here because someCoolAPI is not defined
  }
}
ng test

🔥 Exception or Error

🌍 Your Environment

Contributor guide