2 * worker-test-harness should be considered a temporary polyfill around
3 * testharness.js for supporting Service Worker based tests. It should not be
4 * necessary once the test harness is able to drive worker based tests natively.
5 * See https://github.com/w3c/testharness.js/pull/82 for status of effort to
6 * update upstream testharness.js. Once the upstreaming is complete, tests that
7 * reference worker-test-harness should be updated to directly import
11 // The following are necessary to appease attempts by testharness to access the
13 self.document = {getElementsByTagName: function() { return []; }};
17 // An onload event handler is used to indicate to the testharness that the
18 // document has finished loading. At this point the test suite would be
19 // considered complete if there are no more pending tests and the test isn't
20 // marked as requring an explicit done() call.
22 // Since ServiceWorkers don't have an onload event, we monkey-patch
23 // addEventListener to rewire the event to be fired at oninstall which is
24 // functionally equivalent to onload.
26 var previous_addEventListener = self.addEventListener;
27 self.addEventListener = function() {
28 if (arguments.length > 0 && arguments[0] == 'load') {
29 arguments[0] = 'install';
31 previous_addEventListener.apply(this, arguments);
35 importScripts('/resources/testharness.js');
38 // This prevents the worker from attempting to display test results using the
40 setup({output: false});
42 // Once the test are considered complete, this logic packages up all the
43 // results into a promise resolution so that it can be passed back to the
44 // client document when it connects.
45 var completion_promise = new Promise(function(resolve, reject) {
46 add_completion_callback(function(tests, harness_status) {
48 tests: tests.map(function(test) {
49 return test.structured_clone();
51 status: harness_status.structured_clone()
57 // The 'fetch_results' message is sent by the client document to signal that
58 // it is now ready to receive test results. It also includes a MessagePort
59 // which the worker should use to communicate.
60 self.addEventListener('message', function(ev) {
61 var message = ev.data;
62 if (message.type == 'fetch_results') {
63 var port = ev.ports[0];
64 completion_promise.then(function(results) {
68 status: results.status
70 port.postMessage(message);
76 // 'promise_test' is a new kind of testharness test that handles some
77 // boilerplate for testing with promises.
78 function promise_test(func, name, properties) {
79 properties = properties || {};
80 var test = async_test(name, properties);
81 Promise.resolve(test.step(func, test, test))
82 .then(function() { test.done(); })
83 .catch(test.step_func(function(value) {
88 // Returns a promise that fulfills after the provided |promise| is fulfilled.
89 // The |test| succeeds only if |promise| rejects with an exception matching
90 // |code|. Accepted values for |code| follow those accepted for assert_throws().
91 // The optional |description| describes the test being performed.
93 // assert_promise_rejects(
94 // new Promise(...), // something that should throw an exception.
96 // 'Should throw NotFoundError.');
98 // assert_promise_rejects(
101 // 'Should throw TypeError');
102 function assert_promise_rejects(promise, code, description) {
105 throw 'assert_promise_rejects: ' + description + ' Promise did not throw.';
108 if (code !== undefined) {
109 assert_throws(code, function() { throw e; }, description);