Polyfill.io

Testing in the polyfill service

polyfill.io is tested in two ways: we have service tests which test the NodeJS server that bundles and serves the polyfills, and we have a polyfill test framework that tests the polyfills themselves.

This guide currently only covers testing polyfills.

Writing polyfill tests

Test suites are automatically loaded from a file named tests.js in any polyfill directory.

Polyfill service tests use Mocha and Expect, both chosen because they work in legacy browsers down to our baseline. The tests must assert the behaviour that the polyfill makes consistent across browsers, which is not necessarily the entire published spec.

For example, if part of a feature is not polyfillable in a particular browser, and yet the polyfill is still usable in that browser, omit tests for the part which cannot be polyfilled. This ensures that the polyfill is still targeted at that browser, and consumers are able to get an accurate understanding of which parts of the feature are covered by the polyfill. However, a comment in the test file listing aspects of the feature that are not supported is always appreciated.

The test suite in the tests.js file is wrapped automatically in a describe, so there's no need to include describes in your test file unless you want to (you might do so to divide the tests into more than one group).

Here is an example tests.js file:

it("Should create inherited object", function() {
	var parent = { foo: 'bar', obj: {} };
	var child = Object.create(parent);

	proclaim.deepEqual(typeof child, 'object');
	proclaim.notDeepEqual(parent, child);
	proclaim.deepEqual(child.foo, parent.foo);
	proclaim.deepEqual(child.obj, parent.obj);
});

it("Should create inherited object from a Native Object", function() {
	var parent = document;
	var child = Object.create(parent);

	proclaim.deepEqual(typeof child, 'object');
	proclaim.notDeepEqual(parent, child);
	proclaim.deepEqual(child.window, parent.window);
	proclaim.deepEqual(child.ELEMENT_NODE, parent.ELEMENT_NODE);
});

Running tests locally

You can run tests in three modes:

  • control: All features qualify to be tested, but no polyfills will be loaded (you are testing the browser's native implementation of the feature)
  • all: All features qualify to be tested, and polyfills will always be loaded (you're speculatively testing a polyfill to see if it works
  • targeted: Only those features with polyfills targeted for the current browser will be tested, and polyfills will be loaded conditionally (you're testing that combinations of polyfills and browsers that we believe to work actually do work)

The control and all modes are used to map the compatibility of polyfills, and build the compat.json file that we use to present the browser support matrix. The targeted mode is used to test that the current configuration works, and is therefore used for continuous integration tests on Travis CI.

Your polyfill should pass cleanly in targeted mode in all browsers. To run the entire CI test suite in a local browser, start the service (e.g. with grunt dev), and then load the test director in the browser you're testing:

http://127.0.0.1:3000/test/director?mode=targeted

To test just one feature, use the test runner:

http://127.0.0.1:3000/test/tests?feature=Array.from&mode=targeted

Running tests on Sauce Labs

If you do not have a local install of the browser you want to test, you can also run our tests using Sauce Labs.

The gruntfile contains tasks to run the tests on Sauce Labs, but these require API keys that are not public. If you have your own Sauce Labs account you can run the tests by setting the SAUCE_API_KEY and SAUCE_USER_NAME environment variables, and then run grunt ci:

grunt ci
Running "buildsources" task
Writing compiled polyfill sources to /Users/andrew.betts/sandboxes/local/polyfill-service/polyfills/__dist/...
+ Array.from
+ Array.isArray
...

You can also load the local test URLs described above directly on any remote browser testing service including Sauce or Browserstack, as long as the service provider has a mechanism for tunnelling outbound connections to your machine (otherwise 127.0.0.1 URLs will not work). Both Sauce and Browserstack have utilities to do this.