/*global self*/
/*jshint latedef: nofunc*/
/*
Distributed under both the W3C Test Suite License [1] and the W3C
3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
policies and contribution forms [3].

[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
[3] http://www.w3.org/2004/10/27-testcases
*/

/* Documentation: https://web-platform-tests.org/writing-tests/testharness-api.html
 * (../docs/_writing-tests/testharness-api.md) */

(function (global_scope)
{
    var debug = false;
    // default timeout is 10 seconds, test can override if needed
    var settings = {
        output:true,
        harness_timeout:{
            "normal":10000,
            "long":60000
        },
        test_timeout:null,
        message_events: ["start", "test_state", "result", "completion"]
    };

    var xhtml_ns = "http://www.w3.org/1999/xhtml";

    /*
     * TestEnvironment is an abstraction for the environment in which the test
     * harness is used. Each implementation of a test environment has to provide
     * the following interface:
     *
     * interface TestEnvironment {
     *   // Invoked after the global 'tests' object has been created and it's
     *   // safe to call add_*_callback() to register event handlers.
     *   void on_tests_ready();
     *
     *   // Invoked after setup() has been called to notify the test environment
     *   // of changes to the test harness properties.
     *   void on_new_harness_properties(object properties);
     *
     *   // Should return a new unique default test name.
     *   DOMString next_default_test_name();
     *
     *   // Should return the test harness timeout duration in milliseconds.
     *   float test_timeout();
     * };
     */

    /*
     * A test environment with a DOM. The global object is 'window'. By default
     * test results are displayed in a table. Any parent windows receive
     * callbacks or messages via postMessage() when test events occur. See
     * apisample11.html and apisample12.html.
     */
    function WindowTestEnvironment() {
        this.name_counter = 0;
        this.window_cache = null;
        this.output_handler = null;
        this.all_loaded = false;
        var this_obj = this;
        this.message_events = [];
        this.dispatched_messages = [];

        this.message_functions = {
            start: [add_start_callback, remove_start_callback,
                    function (properties) {
                        this_obj._dispatch("start_callback", [properties],
                                           {type: "start", properties: properties});
                    }],

            test_state: [add_test_state_callback, remove_test_state_callback,
                         function(test) {
                             this_obj._dispatch("test_state_callback", [test],
                                                {type: "test_state",
                                                 test: test.structured_clone()});
                         }],
            result: [add_result_callback, remove_result_callback,
                     function (test) {
                         this_obj.output_handler.show_status();
                         this_obj._dispatch("result_callback", [test],
                                            {type: "result",
                                             test: test.structured_clone()});
                     }],
            completion: [add_completion_callback, remove_completion_callback,
                         function (tests, harness_status) {
                             var cloned_tests = map(tests, function(test) {
                                 return test.structured_clone();
                             });
                             this_obj._dispatch("completion_callback", [tests, harness_status],
                                                {type: "complete",
                                                 tests: cloned_tests,
                                                 status: harness_status.structured_clone()});
                         }]
        }

        on_event(window, 'load', function() {
            this_obj.all_loaded = true;
        });

        on_event(window, 'message', function(event) {
            if (event.data && event.data.type === "getmessages" && event.source) {
                // A window can post "getmessages" to receive a duplicate of every
                // message posted by this environment so far. This allows subscribers
                // from fetch_tests_from_window to 'catch up' to the current state of
                // this environment.
                for (var i = 0; i < this_obj.dispatched_messages.length; ++i)
                {
                    event.source.postMessage(this_obj.dispatched_messages[i], "*");
                }
            }
        });
    }

    WindowTestEnvironment.prototype._dispatch = function(selector, callback_args, message_arg) {
        this.dispatched_messages.push(message_arg);
        this._forEach_windows(
                function(w, same_origin) {
                    if (same_origin) {
                        try {
                            var has_selector = selector in w;
                        } catch(e) {
                            // If document.domain was set at some point same_origin can be
                            // wrong and the above will fail.
                            has_selector = false;
                        }
                        if (has_selector) {
                            try {
                                w[selector].apply(undefined, callback_args);
                            } catch (e) {
                                if (debug) {
                                    throw e;
                                }
                            }
                        }
                    }
                    if (supports_post_message(w) && w !== self) {
                        w.postMessage(message_arg, "*");
                    }
                });
    };

    WindowTestEnvironment.prototype._forEach_windows = function(callback) {
        // Iterate over the windows [self ... top, opener]. The callback is passed
        // two objects, the first one is the window object itself, the second one
        // is a boolean indicating whether or not it's on the same origin as the
        // current window.
        var cache = this.window_cache;
        if (!cache) {
            cache = [[self, true]];
            var w = self;
            var i = 0;
            var so;
            while (w != w.parent) {
                w = w.parent;
                so = is_same_origin(w);
                cache.push([w, so]);
                i++;
            }
            w = window.opener;
            if (w) {
                cache.push([w, is_same_origin(w)]);
            }
            this.window_cache = cache;
        }

        forEach(cache,
                function(a) {
                    callback.apply(null, a);
                });
    };

    WindowTestEnvironment.prototype.on_tests_ready = function() {
        var output = new Output();
        this.output_handler = output;

        var this_obj = this;

        add_start_callback(function (properties) {
            this_obj.output_handler.init(properties);
        });

        add_test_state_callback(function(test) {
            this_obj.output_handler.show_status();
        });

        add_result_callback(function (test) {
            this_obj.output_handler.show_status();
        });

        add_completion_callback(function (tests, harness_status) {
            this_obj.output_handler.show_results(tests, harness_status);
        });
        this.setup_messages(settings.message_events);
    };

    WindowTestEnvironment.prototype.setup_messages = function(new_events) {
        var this_obj = this;
        forEach(settings.message_events, function(x) {
            var current_dispatch = this_obj.message_events.indexOf(x) !== -1;
            var new_dispatch = new_events.indexOf(x) !== -1;
            if (!current_dispatch && new_dispatch) {
                this_obj.message_functions[x][0](this_obj.message_functions[x][2]);
            } else if (current_dispatch && !new_dispatch) {
                this_obj.message_functions[x][1](this_obj.message_functions[x][2]);
            }
        });
        this.message_events = new_events;
    }

    WindowTestEnvironment.prototype.next_default_test_name = function() {
        var suffix = this.name_counter > 0 ? " " + this.name_counter : "";
        this.name_counter++;
        return get_title() + suffix;
    };

    WindowTestEnvironment.prototype.on_new_harness_properties = function(properties) {
        this.output_handler.setup(properties);
        if (properties.hasOwnProperty("message_events")) {
            this.setup_messages(properties.message_events);
        }
    };

    WindowTestEnvironment.prototype.add_on_loaded_callback = function(callback) {
        on_event(window, 'load', callback);
    };

    WindowTestEnvironment.prototype.test_timeout = function() {
        var metas = document.getElementsByTagName("meta");
        for (var i = 0; i < metas.length; i++) {
            if (metas[i].name == "timeout") {
                if (metas[i].content == "long") {
                    return settings.harness_timeout.long;
                }
                break;
            }
        }
        return settings.harness_timeout.normal;
    };

    /*
     * Base TestEnvironment implementation for a generic web worker.
     *
     * Workers accumulate test results. One or more clients can connect and
     * retrieve results from a worker at any time.
     *
     * WorkerTestEnvironment supports communicating with a client via a
     * MessagePort.  The mechanism for determining the appropriate MessagePort
     * for communicating with a client depends on the type of worker and is
     * implemented by the various specializations of WorkerTestEnvironment
     * below.
     *
     * A client document using testharness can use fetch_tests_from_worker() to
     * retrieve results from a worker. See apisample16.html.
     */
    function WorkerTestEnvironment() {
        this.name_counter = 0;
        this.all_loaded = true;
        this.message_list = [];
        this.message_ports = [];
    }

    WorkerTestEnvironment.prototype._dispatch = function(message) {
        this.message_list.push(message);
        for (var i = 0; i < this.message_ports.length; ++i)
        {
            this.message_ports[i].postMessage(message);
        }
    };

    // The only requirement is that port has a postMessage() method. It doesn't
    // have to be an instance of a MessagePort, and often isn't.
    WorkerTestEnvironment.prototype._add_message_port = function(port) {
        this.message_ports.push(port);
        for (var i = 0; i < this.message_list.length; ++i)
        {
            port.postMessage(this.message_list[i]);
        }
    };

    WorkerTestEnvironment.prototype.next_default_test_name = function() {
        var suffix = this.name_counter > 0 ? " " + this.name_counter : "";
        this.name_counter++;
        return get_title() + suffix;
    };

    WorkerTestEnvironment.prototype.on_new_harness_properties = function() {};

    WorkerTestEnvironment.prototype.on_tests_ready = function() {
        var this_obj = this;
        add_start_callback(
                function(properties) {
                    this_obj._dispatch({
                        type: "start",
                        properties: properties,
                    });
                });
        add_test_state_callback(
                function(test) {
                    this_obj._dispatch({
                        type: "test_state",
                        test: test.structured_clone()
                    });
                });
        add_result_callback(
                function(test) {
                    this_obj._dispatch({
                        type: "result",
                        test: test.structured_clone()
                    });
                });
        add_completion_callback(
                function(tests, harness_status) {
                    this_obj._dispatch({
                        type: "complete",
                        tests: map(tests,
                            function(test) {
                                return test.structured_clone();
                            }),
                        status: harness_status.structured_clone()
                    });
                });
    };

    WorkerTestEnvironment.prototype.add_on_loaded_callback = function() {};

    WorkerTestEnvironment.prototype.test_timeout = function() {
        // Tests running in a worker don't have a default timeout. I.e. all
        // worker tests behave as if settings.explicit_timeout is true.
        return null;
    };

    /*
     * Dedicated web workers.
     * https://html.spec.whatwg.org/multipage/workers.html#dedicatedworkerglobalscope
     *
     * This class is used as the test_environment when testharness is running
     * inside a dedicated worker.
     */
    function DedicatedWorkerTestEnvironment() {
        WorkerTestEnvironment.call(this);
        // self is an instance of DedicatedWorkerGlobalScope which exposes
        // a postMessage() method for communicating via the message channel
        // established when the worker is created.
        this._add_message_port(self);
    }
    DedicatedWorkerTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype);

    DedicatedWorkerTestEnvironment.prototype.on_tests_ready = function() {
        WorkerTestEnvironment.prototype.on_tests_ready.call(this);
        // In the absence of an onload notification, we a require dedicated
        // workers to explicitly signal when the tests are done.
        tests.wait_for_finish = true;
    };

    /*
     * Shared web workers.
     * https://html.spec.whatwg.org/multipage/workers.html#sharedworkerglobalscope
     *
     * This class is used as the test_environment when testharness is running
     * inside a shared web worker.
     */
    function SharedWorkerTestEnvironment() {
        WorkerTestEnvironment.call(this);
        var this_obj = this;
        // Shared workers receive message ports via the 'onconnect' event for
        // each connection.
        self.addEventListener("connect",
                function(message_event) {
                    this_obj._add_message_port(message_event.source);
                }, false);
    }
    SharedWorkerTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype);

    SharedWorkerTestEnvironment.prototype.on_tests_ready = function() {
        WorkerTestEnvironment.prototype.on_tests_ready.call(this);
        // In the absence of an onload notification, we a require shared
        // workers to explicitly signal when the tests are done.
        tests.wait_for_finish = true;
    };

    /*
     * Service workers.
     * http://www.w3.org/TR/service-workers/
     *
     * This class is used as the test_environment when testharness is running
     * inside a service worker.
     */
    function ServiceWorkerTestEnvironment() {
        WorkerTestEnvironment.call(this);
        this.all_loaded = false;
        this.on_loaded_callback = null;
        var this_obj = this;
        self.addEventListener("message",
                function(event) {
                    if (event.data && event.data.type && event.data.type === "connect") {
                        this_obj._add_message_port(event.source);
                    }
                }, false);

        // The oninstall event is received after the service worker script and
        // all imported scripts have been fetched and executed. It's the
        // equivalent of an onload event for a document. All tests should have
        // been added by the time this event is received, thus it's not
        // necessary to wait until the onactivate event. However, tests for
        // installed service workers need another event which is equivalent to
        // the onload event because oninstall is fired only on installation. The
        // onmessage event is used for that purpose since tests using
        // testharness.js should ask the result to its service worker by
        // PostMessage. If the onmessage event is triggered on the service
        // worker's context, that means the worker's script has been evaluated.
        on_event(self, "install", on_all_loaded);
        on_event(self, "message", on_all_loaded);
        function on_all_loaded() {
            if (this_obj.all_loaded)
                return;
            this_obj.all_loaded = true;
            if (this_obj.on_loaded_callback) {
              this_obj.on_loaded_callback();
            }
        }
    }

    ServiceWorkerTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype);

    ServiceWorkerTestEnvironment.prototype.add_on_loaded_callback = function(callback) {
        if (this.all_loaded) {
            callback();
        } else {
            this.on_loaded_callback = callback;
        }
    };

    /*
     * JavaScript shells.
     *
     * This class is used as the test_environment when testharness is running
     * inside a JavaScript shell.
     */
    function ShellTestEnvironment() {
        this.name_counter = 0;
        this.all_loaded = false;
        this.on_loaded_callback = null;
        Promise.resolve().then(function() {
            this.all_loaded = true
            if (this.on_loaded_callback) {
                this.on_loaded_callback();
            }
        }.bind(this));
        this.message_list = [];
        this.message_ports = [];
    }

    ShellTestEnvironment.prototype.next_default_test_name = function() {
        var suffix = this.name_counter > 0 ? " " + this.name_counter : "";
        this.name_counter++;
        return "Untitled" + suffix;
    };

    ShellTestEnvironment.prototype.on_new_harness_properties = function() {};

    ShellTestEnvironment.prototype.on_tests_ready = function() {};

    ShellTestEnvironment.prototype.add_on_loaded_callback = function(callback) {
        if (this.all_loaded) {
            callback();
        } else {
            this.on_loaded_callback = callback;
        }
    };

    ShellTestEnvironment.prototype.test_timeout = function() {
        // Tests running in a shell don't have a default timeout, so behave as
        // if settings.explicit_timeout is true.
        return null;
    };

    function create_test_environment() {
        if ('document' in global_scope) {
            return new WindowTestEnvironment();
        }
        if ('DedicatedWorkerGlobalScope' in global_scope &&
            global_scope instanceof DedicatedWorkerGlobalScope) {
            return new DedicatedWorkerTestEnvironment();
        }
        if ('SharedWorkerGlobalScope' in global_scope &&
            global_scope instanceof SharedWorkerGlobalScope) {
            return new SharedWorkerTestEnvironment();
        }
        if ('ServiceWorkerGlobalScope' in global_scope &&
            global_scope instanceof ServiceWorkerGlobalScope) {
            return new ServiceWorkerTestEnvironment();
        }
        if ('WorkerGlobalScope' in global_scope &&
            global_scope instanceof WorkerGlobalScope) {
            return new DedicatedWorkerTestEnvironment();
        }

        if (!('location' in global_scope)) {
            return new ShellTestEnvironment();
        }

        throw new Error("Unsupported test environment");
    }

    var test_environment = create_test_environment();

    function is_shared_worker(worker) {
        return 'SharedWorker' in global_scope && worker instanceof SharedWorker;
    }

    function is_service_worker(worker) {
        // The worker object may be from another execution context,
        // so do not use instanceof here.
        return 'ServiceWorker' in global_scope &&
            Object.prototype.toString.call(worker) == '[object ServiceWorker]';
    }

    var seen_func_name = Object.create(null);

    function get_test_name(func, name)
    {
        if (name) {
            return name;
        }

        if (func) {
            var func_code = func.toString();

            // Try and match with brackets, but fallback to matching without
            var arrow = func_code.match(/^\(\)\s*=>\s*(?:{(.*)}\s*|(.*))$/);

            // Check for JS line separators
            if (arrow !== null && !/[\u000A\u000D\u2028\u2029]/.test(func_code)) {
                var trimmed = (arrow[1] !== undefined ? arrow[1] : arrow[2]).trim();
                // drop trailing ; if there's no earlier ones
                trimmed = trimmed.replace(/^([^;]*)(;\s*)+$/, "$1");

                if (trimmed) {
                    let name = trimmed;
                    if (seen_func_name[trimmed]) {
                        // This subtest name already exists, so add a suffix.
                        name += " " + seen_func_name[trimmed];
                    } else {
                        seen_func_name[trimmed] = 0;
                    }
                    seen_func_name[trimmed] += 1;
                    return name;
                }
            }
        }

        return test_environment.next_default_test_name();
    }

    /*
     * API functions
     */
    function test(func, name, properties)
    {
        if (tests.promise_setup_called) {
            tests.status.status = tests.status.ERROR;
            tests.status.message = '`test` invoked after `promise_setup`';
            tests.complete();
        }
        var test_name = get_test_name(func, name);
        var test_obj = new Test(test_name, properties);
        var value = test_obj.step(func, test_obj, test_obj);

        if (value !== undefined) {
            var msg = 'Test named "' + test_name +
                '" passed a function to `test` that returned a value.';

            try {
                if (value && typeof value.then === 'function') {
                    msg += ' Consider using `promise_test` instead when ' +
                        'using Promises or async/await.';
                }
            } catch (err) {}

            tests.status.status = tests.status.ERROR;
            tests.status.message = msg;
        }

        if (test_obj.phase === test_obj.phases.STARTED) {
            test_obj.done();
        }
    }

    function async_test(func, name, properties)
    {
        if (tests.promise_setup_called) {
            tests.status.status = tests.status.ERROR;
            tests.status.message = '`async_test` invoked after `promise_setup`';
            tests.complete();
        }
        if (typeof func !== "function") {
            properties = name;
            name = func;
            func = null;
        }
        var test_name = get_test_name(func, name);
        var test_obj = new Test(test_name, properties);
        if (func) {
            var value = test_obj.step(func, test_obj, test_obj);

            // Test authors sometimes return values to async_test, expecting us
            // to handle the value somehow. Make doing so a harness error to be
            // clear this is invalid, and point authors to promise_test if it
            // may be appropriate.
            //
            // Note that we only perform this check on the initial function
            // passed to async_test, not on any later steps - we haven't seen a
            // consistent problem with those (and it's harder to check).
            if (value !== undefined) {
                var msg = 'Test named "' + test_name +
                    '" passed a function to `async_test` that returned a value.';

                try {
                    if (value && typeof value.then === 'function') {
                        msg += ' Consider using `promise_test` instead when ' +
                            'using Promises or async/await.';
                    }
                } catch (err) {}

                tests.set_status(tests.status.ERROR, msg);
                tests.complete();
            }
        }
        return test_obj;
    }

    function promise_test(func, name, properties) {
        if (typeof func !== "function") {
            properties = name;
            name = func;
            func = null;
        }
        var test_name = get_test_name(func, name);
        var test = new Test(test_name, properties);
        test._is_promise_test = true;

        // If there is no promise tests queue make one.
        if (!tests.promise_tests) {
            tests.promise_tests = Promise.resolve();
        }
        tests.promise_tests = tests.promise_tests.then(function() {
            return new Promise(function(resolve) {
                var promise = test.step(func, test, test);

                test.step(function() {
                    assert(!!promise, "promise_test", null,
                           "test body must return a 'thenable' object (received ${value})",
                           {value:promise});
                    assert(typeof promise.then === "function", "promise_test", null,
                           "test body must return a 'thenable' object (received an object with no `then` method)",
                           null);
                });

                // Test authors may use the `step` method within a
                // `promise_test` even though this reflects a mixture of
                // asynchronous control flow paradigms. The "done" callback
                // should be registered prior to the resolution of the
                // user-provided Promise to avoid timeouts in cases where the
                // Promise does not settle but a `step` function has thrown an
                // error.
                add_test_done_callback(test, resolve);

                Promise.resolve(promise)
                    .catch(test.step_func(
                        function(value) {
                            if (value instanceof AssertionError) {
                                throw value;
                            }
                            assert(false, "promise_test", null,
                                   "Unhandled rejection with value: ${value}", {value:value});
                        }))
                    .then(function() {
                        test.done();
                    });
                });
        });
    }

    /**
     * Make a copy of a Promise in the current realm.
     *
     * @param {Promise} promise the given promise that may be from a different
     *                          realm
     * @returns {Promise}
     *
     * An arbitrary promise provided by the caller may have originated in
     * another frame that have since navigated away, rendering the frame's
     * document inactive. Such a promise cannot be used with `await` or
     * Promise.resolve(), as microtasks associated with it may be prevented
     * from being run. See https://github.com/whatwg/html/issues/5319 for a
     * particular case.
     *
     * In functions we define here, there is an expectation from the caller
     * that the promise is from the current realm, that can always be used with
     * `await`, etc. We therefore create a new promise in this realm that
     * inherit the value and status from the given promise.
     */

    function bring_promise_to_current_realm(promise) {
        return new Promise(promise.then.bind(promise));
    }

    function promise_rejects_js(test, constructor, promise, description) {
        return bring_promise_to_current_realm(promise)
            .then(test.unreached_func("Should have rejected: " + description))
            .catch(function(e) {
                assert_throws_js_impl(constructor, function() { throw e },
                                      description, "promise_rejects_js");
            });
    }

    /**
     * Assert that a Promise is rejected with the right DOMException.
     *
     * @param test the test argument passed to promise_test
     * @param {number|string} type.  See documentation for assert_throws_dom.
     *
     * For the remaining arguments, there are two ways of calling
     * promise_rejects_dom:
     *
     * 1) If the DOMException is expected to come from the current global, the
     * third argument should be the promise expected to reject, and a fourth,
     * optional, argument is the assertion description.
     *
     * 2) If the DOMException is expected to come from some other global, the
     * third argument should be the DOMException constructor from that global,
     * the fourth argument the promise expected to reject, and the fifth,
     * optional, argument the assertion description.
     */

    function promise_rejects_dom(test, type, promiseOrConstructor, descriptionOrPromise, maybeDescription) {
        let constructor, promise, description;
        if (typeof promiseOrConstructor === "function" &&
            promiseOrConstructor.name === "DOMException") {
            constructor = promiseOrConstructor;
            promise = descriptionOrPromise;
            description = maybeDescription;
        } else {
            constructor = self.DOMException;
            promise = promiseOrConstructor;
            description = descriptionOrPromise;
            assert(maybeDescription === undefined,
                   "Too many args pased to no-constructor version of promise_rejects_dom");
        }
        return bring_promise_to_current_realm(promise)
            .then(test.unreached_func("Should have rejected: " + description))
            .catch(function(e) {
                assert_throws_dom_impl(type, function() { throw e }, description,
                                       "promise_rejects_dom", constructor);
            });
    }

    function promise_rejects_exactly(test, exception, promise, description) {
        return bring_promise_to_current_realm(promise)
            .then(test.unreached_func("Should have rejected: " + description))
            .catch(function(e) {
                assert_throws_exactly_impl(exception, function() { throw e },
                                           description, "promise_rejects_exactly");
            });
    }

    /**
     * This constructor helper allows DOM events to be handled using Promises,
     * which can make it a lot easier to test a very specific series of events,
     * including ensuring that unexpected events are not fired at any point.
     */
    function EventWatcher(test, watchedNode, eventTypes, timeoutPromise)
    {
        if (typeof eventTypes == 'string') {
            eventTypes = [eventTypes];
        }

        var waitingFor = null;

        // This is null unless we are recording all events, in which case it
        // will be an Array object.
        var recordedEvents = null;

        var eventHandler = test.step_func(function(evt) {
            assert_true(!!waitingFor,
                        'Not expecting event, but got ' + evt.type + ' event');
            assert_equals(evt.type, waitingFor.types[0],
                          'Expected ' + waitingFor.types[0] + ' event, but got ' +
                          evt.type + ' event instead');

            if (Array.isArray(recordedEvents)) {
                recordedEvents.push(evt);
            }

            if (waitingFor.types.length > 1) {
                // Pop first event from array
                waitingFor.types.shift();
                return;
            }
            // We need to null out waitingFor before calling the resolve function
            // since the Promise's resolve handlers may call wait_for() which will
            // need to set waitingFor.
            var resolveFunc = waitingFor.resolve;
            waitingFor = null;
            // Likewise, we should reset the state of recordedEvents.
            var result = recordedEvents || evt;
            recordedEvents = null;
            resolveFunc(result);
        });

        for (var i = 0; i < eventTypes.length; i++) {
            watchedNode.addEventListener(eventTypes[i], eventHandler, false);
        }

        /**
         * Returns a Promise that will resolve after the specified event or
         * series of events has occurred.
         *
         * @param options An optional options object. If the 'record' property
         *                on this object has the value 'all', when the Promise
         *                returned by this function is resolved,  *all* Event
         *                objects that were waited for will be returned as an
         *                array.
         *
         * For example,
         *
         * ```js
         * const watcher = new EventWatcher(t, div, [ 'animationstart',
         *                                            'animationiteration',
         *                                            'animationend' ]);
         * return watcher.wait_for([ 'animationstart', 'animationend' ],
         *                         { record: 'all' }).then(evts => {
         *   assert_equals(evts[0].elapsedTime, 0.0);
         *   assert_equals(evts[1].elapsedTime, 2.0);
         * });
         * ```
         */
        this.wait_for = function(types, options) {
            if (waitingFor) {
                return Promise.reject('Already waiting for an event or events');
            }
            if (typeof types == 'string') {
                types = [types];
            }
            if (options && options.record && options.record === 'all') {
                recordedEvents = [];
            }
            return new Promise(function(resolve, reject) {
                var timeout = test.step_func(function() {
                    // If the timeout fires after the events have been received
                    // or during a subsequent call to wait_for, ignore it.
                    if (!waitingFor || waitingFor.resolve !== resolve)
                        return;

                    // This should always fail, otherwise we should have
                    // resolved the promise.
                    assert_true(waitingFor.types.length == 0,
                                'Timed out waiting for ' + waitingFor.types.join(', '));
                    var result = recordedEvents;
                    recordedEvents = null;
                    var resolveFunc = waitingFor.resolve;
                    waitingFor = null;
                    resolveFunc(result);
                });

                if (timeoutPromise) {
                    timeoutPromise().then(timeout);
                }

                waitingFor = {
                    types: types,
                    resolve: resolve,
                    reject: reject
                };
            });
        };

        function stop_watching() {
            for (var i = 0; i < eventTypes.length; i++) {
                watchedNode.removeEventListener(eventTypes[i], eventHandler, false);
            }
        };

        test._add_cleanup(stop_watching);

        return this;
    }
    expose(EventWatcher, 'EventWatcher');

    function setup(func_or_properties, maybe_properties)
    {
        var func = null;
        var properties = {};
        if (arguments.length === 2) {
            func = func_or_properties;
            properties = maybe_properties;
        } else if (func_or_properties instanceof Function) {
            func = func_or_properties;
        } else {
            properties = func_or_properties;
        }
        tests.setup(func, properties);
        test_environment.on_new_harness_properties(properties);
    }

    function promise_setup(func, maybe_properties)
    {
        if (typeof func !== "function") {
            tests.set_status(tests.status.ERROR,
                             "promise_test invoked without a function");
            tests.complete();
            return;
        }
        tests.promise_setup_called = true;

        if (!tests.promise_tests) {
            tests.promise_tests = Promise.resolve();
        }

        tests.promise_tests = tests.promise_tests
            .then(function()
                  {
                      var properties = maybe_properties || {};
                      var result;

                      tests.setup(null, properties);
                      result = func();
                      test_environment.on_new_harness_properties(properties);

                      if (!result || typeof result.then !== "function") {
                          throw "Non-thenable returned by function passed to `promise_setup`";
                      }
                      return result;
                  })
            .catch(function(e)
                   {
                       tests.set_status(tests.status.ERROR,
                                        String(e),
                                        e && e.stack);
                       tests.complete();
                   });
    }

    function done() {
        if (tests.tests.length === 0) {
            // `done` is invoked after handling uncaught exceptions, so if the
            // harness status is already set, the corresponding message is more
            // descriptive than the generic message defined here.
            if (tests.status.status === null) {
                tests.status.status = tests.status.ERROR;
                tests.status.message = "done() was called without first defining any tests";
            }

            tests.complete();
            return;
        }
        if (tests.file_is_test) {
            // file is test files never have asynchronous cleanup logic,
            // meaning the fully-synchronous `done` function can be used here.
            tests.tests[0].done();
        }
        tests.end_wait();
    }

    function generate_tests(func, args, properties) {
        forEach(args, function(x, i)
                {
                    var name = x[0];
                    test(function()
                         {
                             func.apply(this, x.slice(1));
                         },
                         name,
                         Array.isArray(properties) ? properties[i] : properties);
                });
    }

    /*
     * Register a function as a DOM event listener to the given object for the
     * event bubbling phase.
     *
     * This function was deprecated in November of 2019.
     */
    function on_event(object, event, callback)
    {
        object.addEventListener(event, callback, false);
    }

    function step_timeout(f, t) {
        var outer_this = this;
        var args = Array.prototype.slice.call(arguments, 2);
        return setTimeout(function() {
            f.apply(outer_this, args);
        }, t * tests.timeout_multiplier);
    }

    expose(test, 'test');
    expose(async_test, 'async_test');
    expose(promise_test, 'promise_test');
    expose(promise_rejects_js, 'promise_rejects_js');
    expose(promise_rejects_dom, 'promise_rejects_dom');
    expose(promise_rejects_exactly, 'promise_rejects_exactly');
    expose(generate_tests, 'generate_tests');
    expose(setup, 'setup');
    expose(promise_setup, 'promise_setup');
    expose(done, 'done');
    expose(on_event, 'on_event');
    expose(step_timeout, 'step_timeout');

    /*
     * Return a string truncated to the given length, with ... added at the end
     * if it was longer.
     */
    function truncate(s, len)
    {
        if (s.length > len) {
            return s.substring(0, len - 3) + "...";
        }
        return s;
    }

    /*
     * Return true if object is probably a Node object.
     */
    function is_node(object)
    {
        // I use duck-typing instead of instanceof, because
        // instanceof doesn't work if the node is from another window (like an
        // iframe's contentWindow):
        // http://www.w3.org/Bugs/Public/show_bug.cgi?id=12295
        try {
            var has_node_properties = ("nodeType" in object &&
                                       "nodeName" in object &&
                                       "nodeValue" in object &&
                                       "childNodes" in object);
        } catch (e) {
            // We're probably cross-origin, which means we aren't a node
            return false;
        }

        if (has_node_properties) {
            try {
                object.nodeType;
            } catch (e) {
                // The object is probably Node.prototype or another prototype
                // object that inherits from it, and not a Node instance.
                return false;
            }
            return true;
        }
        return false;
    }

    var replacements = {
        "0": "0",
        "1": "x01",
        "2": "x02",
        "3": "x03",
        "4": "x04",
        "5": "x05",
        "6": "x06",
        "7": "x07",
        "8": "b",
        "9": "t",
        "10": "n",
        "11": "v",
        "12": "f",
        "13": "r",
        "14": "x0e",
        "15": "x0f",
        "16": "x10",
        "17": "x11",
        "18": "x12",
        "19": "x13",
        "20": "x14",
        "21": "x15",
        "22": "x16",
        "23": "x17",
        "24": "x18",
        "25": "x19",
        "26": "x1a",
        "27": "x1b",
        "28": "x1c",
        "29": "x1d",
        "30": "x1e",
        "31": "x1f",
        "0xfffd": "ufffd",
        "0xfffe": "ufffe",
        "0xffff": "uffff",
    };

    /*
     * Convert a value to a nice, human-readable string
     */
    function format_value(val, seen)
    {
        if (!seen) {
            seen = [];
        }
        if (typeof val === "object" && val !== null) {
            if (seen.indexOf(val) >= 0) {
                return "[...]";
            }
            seen.push(val);
        }
        if (Array.isArray(val)) {
            let output = "[";
            if (val.beginEllipsis !== undefined) {
                output += "…, ";
            }
            output += val.map(function(x) {return format_value(x, seen);}).join(", ");
            if (val.endEllipsis !== undefined) {
                output += ", …";
            }
            return output + "]";
        }

        switch (typeof val) {
        case "string":
            val = val.replace(/\\/g, "\\\\");
            for (var p in replacements) {
                var replace = "\\" + replacements[p];
                val = val.replace(RegExp(String.fromCharCode(p), "g"), replace);
            }
            return '"' + val.replace(/"/g, '\\"') + '"';
        case "boolean":
        case "undefined":
            return String(val);
        case "number":
            // In JavaScript, -0 === 0 and String(-0) == "0", so we have to
            // special-case.
            if (val === -0 && 1/val === -Infinity) {
                return "-0";
            }
            return String(val);
        case "object":
            if (val === null) {
                return "null";
            }

            // Special-case Node objects, since those come up a lot in my tests.  I
            // ignore namespaces.
            if (is_node(val)) {
                switch (val.nodeType) {
                case Node.ELEMENT_NODE:
                    var ret = "<" + val.localName;
                    for (var i = 0; i < val.attributes.length; i++) {
                        ret += " " + val.attributes[i].name + '="' + val.attributes[i].value + '"';
                    }
                    ret += ">" + val.innerHTML + "</" + val.localName + ">";
                    return "Element node " + truncate(ret, 60);
                case Node.TEXT_NODE:
                    return 'Text node "' + truncate(val.data, 60) + '"';
                case Node.PROCESSING_INSTRUCTION_NODE:
                    return "ProcessingInstruction node with target " + format_value(truncate(val.target, 60)) + " and data " + format_value(truncate(val.data, 60));
                case Node.COMMENT_NODE:
                    return "Comment node <!--" + truncate(val.data, 60) + "-->";
                case Node.DOCUMENT_NODE:
                    return "Document node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children");
                case Node.DOCUMENT_TYPE_NODE:
                    return "DocumentType node";
                case Node.DOCUMENT_FRAGMENT_NODE:
                    return "DocumentFragment node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children");
                default:
                    return "Node object of unknown type";
                }
            }

        /* falls through */
        default:
            try {
                return typeof val + ' "' + truncate(String(val), 1000) + '"';
            } catch(e) {
                return ("[stringifying object threw " + String(e) +
                        " with type " + String(typeof e) + "]");
            }
        }
    }
    expose(format_value, "format_value");

    /*
     * Assertions
     */

    function assert_true(actual, description)
    {
        assert(actual === true, "assert_true", description,
                                "expected true got ${actual}", {actual:actual});
    }
    expose(assert_true, "assert_true");

    function assert_false(actual, description)
    {
        assert(actual === false, "assert_false", description,
                                 "expected false got ${actual}", {actual:actual});
    }
    expose(assert_false, "assert_false");

    function same_value(x, y) {
        if (y !== y) {
            //NaN case
            return x !== x;
        }
        if (x === 0 && y === 0) {
            //Distinguish +0 and -0
            return 1/x === 1/y;
        }
        return x === y;
    }

    function assert_equals(actual, expected, description)
    {
         /*
          * Test if two primitives are equal or two objects
          * are the same object
          */
        if (typeof actual != typeof expected) {
            assert(false, "assert_equals", description,
                          "expected (" + typeof expected + ") ${expected} but got (" + typeof actual + ") ${actual}",
                          {expected:expected, actual:actual});
            return;
        }
        assert(same_value(actual, expected), "assert_equals", description,
                                             "expected ${expected} but got ${actual}",
                                             {expected:expected, actual:actual});
    }
    expose(assert_equals, "assert_equals");

    function assert_not_equals(actual, expected, description)
    {
         /*
          * Test if two primitives are unequal or two objects
          * are different objects
          */
        assert(!same_value(actual, expected), "assert_not_equals", description,
                                              "got disallowed value ${actual}",
                                              {actual:actual});
    }
    expose(assert_not_equals, "assert_not_equals");

    function assert_in_array(actual, expected, description)
    {
        assert(expected.indexOf(actual) != -1, "assert_in_array", description,
                                               "value ${actual} not in array ${expected}",
                                               {actual:actual, expected:expected});
    }
    expose(assert_in_array, "assert_in_array");

    // This function was deprecated in July of 2015.
    // See https://github.com/web-platform-tests/wpt/issues/2033
    function assert_object_equals(actual, expected, description)
    {
         assert(typeof actual === "object" && actual !== null, "assert_object_equals", description,
                                                               "value is ${actual}, expected object",
                                                               {actual: actual});
         //This needs to be improved a great deal
         function check_equal(actual, expected, stack)
         {
             stack.push(actual);

             var p;
             for (p in actual) {
                 assert(expected.hasOwnProperty(p), "assert_object_equals", description,
                                                    "unexpected property ${p}", {p:p});

                 if (typeof actual[p] === "object" && actual[p] !== null) {
                     if (stack.indexOf(actual[p]) === -1) {
                         check_equal(actual[p], expected[p], stack);
                     }
                 } else {
                     assert(same_value(actual[p], expected[p]), "assert_object_equals", description,
                                                       "property ${p} expected ${expected} got ${actual}",
                                                       {p:p, expected:expected[p], actual:actual[p]});
                 }
             }
             for (p in expected) {
                 assert(actual.hasOwnProperty(p),
                        "assert_object_equals", description,
                        "expected property ${p} missing", {p:p});
             }
             stack.pop();
         }
         check_equal(actual, expected, []);
    }
    expose(assert_object_equals, "assert_object_equals");

    function assert_array_equals(actual, expected, description)
    {
        const max_array_length = 20;
        function shorten_array(arr, offset = 0) {
            // Make ", …" only show up when it would likely reduce the length, not accounting for
            // fonts.
            if (arr.length < max_array_length + 2) {
                return arr;
            }
            // By default we want half the elements after the offset and half before
            // But if that takes us past the end of the array, we have more before, and
            // if it takes us before the start we have more after.
            const length_after_offset = Math.floor(max_array_length / 2);
            let upper_bound = Math.min(length_after_offset + offset, arr.length);
            const lower_bound = Math.max(upper_bound - max_array_length, 0);

            if (lower_bound === 0) {
                upper_bound = max_array_length;
            }

            const output = arr.slice(lower_bound, upper_bound);
            if (lower_bound > 0) {
                output.beginEllipsis = true;
            }
            if (upper_bound < arr.length) {
                output.endEllipsis = true;
            }
            return output;
        }

        assert(typeof actual === "object" && actual !== null && "length" in actual,
               "assert_array_equals", description,
               "value is ${actual}, expected array",
               {actual:actual});
        assert(actual.length === expected.length,
               "assert_array_equals", description,
               "lengths differ, expected array ${expected} length ${expectedLength}, got ${actual} length ${actualLength}",
               {expected:shorten_array(expected, expected.length - 1), expectedLength:expected.length,
                actual:shorten_array(actual, actual.length - 1), actualLength:actual.length
               });

        for (var i = 0; i < actual.length; i++) {
            assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i),
                   "assert_array_equals", description,
                   "expected property ${i} to be ${expected} but was ${actual} (expected array ${arrayExpected} got ${arrayActual})",
                   {i:i, expected:expected.hasOwnProperty(i) ? "present" : "missing",
                    actual:actual.hasOwnProperty(i) ? "present" : "missing",
                    arrayExpected:shorten_array(expected, i), arrayActual:shorten_array(actual, i)});
            assert(same_value(expected[i], actual[i]),
                   "assert_array_equals", description,
                   "expected property ${i} to be ${expected} but got ${actual} (expected array ${arrayExpected} got ${arrayActual})",
                   {i:i, expected:expected[i], actual:actual[i],
                    arrayExpected:shorten_array(expected, i), arrayActual:shorten_array(actual, i)});
        }
    }
    expose(assert_array_equals, "assert_array_equals");

    function assert_array_approx_equals(actual, expected, epsilon, description)
    {
        /*
         * Test if two primitive arrays are equal within +/- epsilon
         */
        assert(actual.length === expected.length,
               "assert_array_approx_equals", description,
               "lengths differ, expected ${expected} got ${actual}",
               {expected:expected.length, actual:actual.length});

        for (var i = 0; i < actual.length; i++) {
            assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i),
                   "assert_array_approx_equals", description,
                   "property ${i}, property expected to be ${expected} but was ${actual}",
                   {i:i, expected:expected.hasOwnProperty(i) ? "present" : "missing",
                    actual:actual.hasOwnProperty(i) ? "present" : "missing"});
            assert(typeof actual[i] === "number",
                   "assert_array_approx_equals", description,
                   "property ${i}, expected a number but got a ${type_actual}",
                   {i:i, type_actual:typeof actual[i]});
            assert(Math.abs(actual[i] - expected[i]) <= epsilon,
                   "assert_array_approx_equals", description,
                   "property ${i}, expected ${expected} +/- ${epsilon}, expected ${expected} but got ${actual}",
                   {i:i, expected:expected[i], actual:actual[i], epsilon:epsilon});
        }
    }
    expose(assert_array_approx_equals, "assert_array_approx_equals");

    function assert_approx_equals(actual, expected, epsilon, description)
    {
        /*
         * Test if two primitive numbers are equal within +/- epsilon
         */
        assert(typeof actual === "number",
               "assert_approx_equals", description,
               "expected a number but got a ${type_actual}",
               {type_actual:typeof actual});

        // The epsilon math below does not place nice with NaN and Infinity
        // But in this case Infinity = Infinity and NaN = NaN
        if (isFinite(actual) || isFinite(expected)) {
            assert(Math.abs(actual - expected) <= epsilon,
                   "assert_approx_equals", description,
                   "expected ${expected} +/- ${epsilon} but got ${actual}",
                   {expected:expected, actual:actual, epsilon:epsilon});
        } else {
            assert_equals(actual, expected);
        }
    }
    expose(assert_approx_equals, "assert_approx_equals");

    function assert_less_than(actual, expected, description)
    {
        /*
         * Test if a primitive number is less than another
         */
        assert(typeof actual === "number",
               "assert_less_than", description,
               "expected a number but got a ${type_actual}",
               {type_actual:typeof actual});

        assert(actual < expected,
               "assert_less_than", description,
               "expected a number less than ${expected} but got ${actual}",
               {expected:expected, actual:actual});
    }
    expose(assert_less_than, "assert_less_than");

    function assert_greater_than(actual, expected, description)
    {
        /*
         * Test if a primitive number is greater than another
         */
        assert(typeof actual === "number",
               "assert_greater_than", description,
               "expected a number but got a ${type_actual}",
               {type_actual:typeof actual});

        assert(actual > expected,
               "assert_greater_than", description,
               "expected a number greater than ${expected} but got ${actual}",
               {expected:expected, actual:actual});
    }
    expose(assert_greater_than, "assert_greater_than");

    function assert_between_exclusive(actual, lower, upper, description)
    {
        /*
         * Test if a primitive number is between two others
         */
        assert(typeof actual === "number",
               "assert_between_exclusive", description,
               "expected a number but got a ${type_actual}",
               {type_actual:typeof actual});

        assert(actual > lower && actual < upper,
               "assert_between_exclusive", description,
               "expected a number greater than ${lower} " +
               "and less than ${upper} but got ${actual}",
               {lower:lower, upper:upper, actual:actual});
    }
    expose(assert_between_exclusive, "assert_between_exclusive");

    function assert_less_than_equal(actual, expected, description)
    {
        /*
         * Test if a primitive number is less than or equal to another
         */
        assert(typeof actual === "number",
               "assert_less_than_equal", description,
               "expected a number but got a ${type_actual}",
               {type_actual:typeof actual});

        assert(actual <= expected,
               "assert_less_than_equal", description,
               "expected a number less than or equal to ${expected} but got ${actual}",
               {expected:expected, actual:actual});
    }
    expose(assert_less_than_equal, "assert_less_than_equal");

    function assert_greater_than_equal(actual, expected, description)
    {
        /*
         * Test if a primitive number is greater than or equal to another
         */
        assert(typeof actual === "number",
               "assert_greater_than_equal", description,
               "expected a number but got a ${type_actual}",
               {type_actual:typeof actual});

        assert(actual >= expected,
               "assert_greater_than_equal", description,
               "expected a number greater than or equal to ${expected} but got ${actual}",
               {expected:expected, actual:actual});
    }
    expose(assert_greater_than_equal, "assert_greater_than_equal");

    function assert_between_inclusive(actual, lower, upper, description)
    {
        /*
         * Test if a primitive number is between to two others or equal to either of them
         */
        assert(typeof actual === "number",
               "assert_between_inclusive", description,
               "expected a number but got a ${type_actual}",
               {type_actual:typeof actual});

        assert(actual >= lower && actual <= upper,
               "assert_between_inclusive", description,
               "expected a number greater than or equal to ${lower} " +
               "and less than or equal to ${upper} but got ${actual}",
               {lower:lower, upper:upper, actual:actual});
    }
    expose(assert_between_inclusive, "assert_between_inclusive");

    function assert_regexp_match(actual, expected, description) {
        /*
         * Test if a string (actual) matches a regexp (expected)
         */
        assert(expected.test(actual),
               "assert_regexp_match", description,
               "expected ${expected} but got ${actual}",
               {expected:expected, actual:actual});
    }
    expose(assert_regexp_match, "assert_regexp_match");

    function assert_class_string(object, class_string, description) {
        var actual = {}.toString.call(object);
        var expected = "[object " + class_string + "]";
        assert(same_value(actual, expected), "assert_class_string", description,
                                             "expected ${expected} but got ${actual}",
                                             {expected:expected, actual:actual});
    }
    expose(assert_class_string, "assert_class_string");


    function assert_own_property(object, property_name, description) {
        assert(object.hasOwnProperty(property_name),
               "assert_own_property", description,
               "expected property ${p} missing", {p:property_name});
    }
    expose(assert_own_property, "assert_own_property");

    function assert_not_own_property(object, property_name, description) {
        assert(!object.hasOwnProperty(property_name),
               "assert_not_own_property", description,
               "unexpected property ${p} is found on object", {p:property_name});
    }
    expose(assert_not_own_property, "assert_not_own_property");

    function _assert_inherits(name) {
        return function (object, property_name, description)
        {
            assert(typeof object === "object" || typeof object === "function" ||
                   // Or has [[IsHTMLDDA]] slot
                   String(object) === "[object HTMLAllCollection]",
                   name, description,
                   "provided value is not an object");

            assert("hasOwnProperty" in object,
                   name, description,
                   "provided value is an object but has no hasOwnProperty method");

            assert(!object.hasOwnProperty(property_name),
                   name, description,
                   "property ${p} found on object expected in prototype chain",
                   {p:property_name});

            assert(property_name in object,
                   name, description,
                   "property ${p} not found in prototype chain",
                   {p:property_name});
        };
    }
    expose(_assert_inherits("assert_inherits"), "assert_inherits");
    expose(_assert_inherits("assert_idl_attribute"), "assert_idl_attribute");

    function assert_readonly(object, property_name, description)
    {
         var initial_value = object[property_name];
         try {
             //Note that this can have side effects in the case where
             //the property has PutForwards
             object[property_name] = initial_value + "a"; //XXX use some other value here?
             assert(same_value(object[property_name], initial_value),
                    "assert_readonly", description,
                    "changing property ${p} succeeded",
                    {p:property_name});
         } finally {
             object[property_name] = initial_value;
         }
    }
    expose(assert_readonly, "assert_readonly");

    /**
     * Assert a JS Error with the expected constructor is thrown.
     *
     * @param {object} constructor The expected exception constructor.
     * @param {Function} func Function which should throw.
     * @param {string} description Error description for the case that the error is not thrown.
     */
    function assert_throws_js(constructor, func, description)
    {
        assert_throws_js_impl(constructor, func, description,
                              "assert_throws_js");
    }
    expose(assert_throws_js, "assert_throws_js");

    /**
     * Like assert_throws_js but allows specifying the assertion type
     * (assert_throws_js or promise_rejects_js, in practice).
     */
    function assert_throws_js_impl(constructor, func, description,
                                   assertion_type)
    {
        try {
            func.call(this);
            assert(false, assertion_type, description,
                   "${func} did not throw", {func:func});
        } catch (e) {
            if (e instanceof AssertionError) {
                throw e;
            }

            // Basic sanity-checks on the thrown exception.
            assert(typeof e === "object",
                   assertion_type, description,
                   "${func} threw ${e} with type ${type}, not an object",
                   {func:func, e:e, type:typeof e});

            assert(e !== null,
                   assertion_type, description,
                   "${func} threw null, not an object",
                   {func:func});

            // Basic sanity-check on the passed-in constructor
            assert(typeof constructor == "function",
                   assertion_type, description,
                   "${constructor} is not a constructor",
                   {constructor:constructor});
            var obj = constructor;
            while (obj) {
                if (typeof obj === "function" &&
                    obj.name === "Error") {
                    break;
                }
                obj = Object.getPrototypeOf(obj);
            }
            assert(obj != null,
                   assertion_type, description,
                   "${constructor} is not an Error subtype",
                   {constructor:constructor});

            // And checking that our exception is reasonable
            assert(e.constructor === constructor &&
                   e.name === constructor.name,
                   assertion_type, description,
                   "${func} threw ${actual} (${actual_name}) expected instance of ${expected} (${expected_name})",
                   {func:func, actual:e, actual_name:e.name,
                    expected:constructor,
                    expected_name:constructor.name});
        }
    }

    /**
     * Assert a DOMException with the expected type is thrown.
     *
     * @param {number|string} type The expected exception name or code.  See the
     *        table of names and codes at
     *        https://heycam.github.io/webidl/#dfn-error-names-table
     *        If a number is passed it should be one of the numeric code values
     *        in that table (e.g. 3, 4, etc).  If a string is passed it can
     *        either be an exception name (e.g. "HierarchyRequestError",
     *        "WrongDocumentError") or the name of the corresponding error code
     *        (e.g. "HIERARCHY_REQUEST_ERR", "WRONG_DOCUMENT_ERR").
     *
     * For the remaining arguments, there are two ways of calling
     * promise_rejects_dom:
     *
     * 1) If the DOMException is expected to come from the current global, the
     * second argument should be the function expected to throw and a third,
     * optional, argument is the assertion description.
     *
     * 2) If the DOMException is expected to come from some other global, the
     * second argument should be the DOMException constructor from that global,
     * the third argument the function expected to throw, and the fourth, optional,
     * argument the assertion description.
     */
    function assert_throws_dom(type, funcOrConstructor, descriptionOrFunc, maybeDescription)
    {
        let constructor, func, description;
        if (funcOrConstructor.name === "DOMException") {
            constructor = funcOrConstructor;
            func = descriptionOrFunc;
            description = maybeDescription;
        } else {
            constructor = self.DOMException;
            func = funcOrConstructor;
            description = descriptionOrFunc;
            assert(maybeDescription === undefined,
                   "Too many args pased to no-constructor version of assert_throws_dom");
        }
        assert_throws_dom_impl(type, func, description, "assert_throws_dom", constructor)
    }
    expose(assert_throws_dom, "assert_throws_dom");

    /**
     * Similar to assert_throws_dom but allows specifying the assertion type
     * (assert_throws_dom or promise_rejects_dom, in practice).  The
     * "constructor" argument must be the DOMException constructor from the
     * global we expect the exception to come from.
     */
    function assert_throws_dom_impl(type, func, description, assertion_type, constructor)
    {
        try {
            func.call(this);
            assert(false, assertion_type, description,
                   "${func} did not throw", {func:func});
        } catch (e) {
            if (e instanceof AssertionError) {
                throw e;
            }

            // Basic sanity-checks on the thrown exception.
            assert(typeof e === "object",
                   assertion_type, description,
                   "${func} threw ${e} with type ${type}, not an object",
                   {func:func, e:e, type:typeof e});

            assert(e !== null,
                   assertion_type, description,
                   "${func} threw null, not an object",
                   {func:func});

            // Sanity-check our type
            assert(typeof type == "number" ||
                   typeof type == "string",
                   assertion_type, description,
                   "${type} is not a number or string",
                   {type:type});

            var codename_name_map = {
                INDEX_SIZE_ERR: 'IndexSizeError',
                HIERARCHY_REQUEST_ERR: 'HierarchyRequestError',
                WRONG_DOCUMENT_ERR: 'WrongDocumentError',
                INVALID_CHARACTER_ERR: 'InvalidCharacterError',
                NO_MODIFICATION_ALLOWED_ERR: 'NoModificationAllowedError',
                NOT_FOUND_ERR: 'NotFoundError',
                NOT_SUPPORTED_ERR: 'NotSupportedError',
                INUSE_ATTRIBUTE_ERR: 'InUseAttributeError',
                INVALID_STATE_ERR: 'InvalidStateError',
                SYNTAX_ERR: 'SyntaxError',
                INVALID_MODIFICATION_ERR: 'InvalidModificationError',
                NAMESPACE_ERR: 'NamespaceError',
                INVALID_ACCESS_ERR: 'InvalidAccessError',
                TYPE_MISMATCH_ERR: 'TypeMismatchError',
                SECURITY_ERR: 'SecurityError',
                NETWORK_ERR: 'NetworkError',
                ABORT_ERR: 'AbortError',
                URL_MISMATCH_ERR: 'URLMismatchError',
                QUOTA_EXCEEDED_ERR: 'QuotaExceededError',
                TIMEOUT_ERR: 'TimeoutError',
                INVALID_NODE_TYPE_ERR: 'InvalidNodeTypeError',
                DATA_CLONE_ERR: 'DataCloneError'
            };

            var name_code_map = {
                IndexSizeError: 1,
                HierarchyRequestError: 3,
                WrongDocumentError: 4,
                InvalidCharacterError: 5,
                NoModificationAllowedError: 7,
                NotFoundError: 8,
                NotSupportedError: 9,
                InUseAttributeError: 10,
                InvalidStateError: 11,
                SyntaxError: 12,
                InvalidModificationError: 13,
                NamespaceError: 14,
                InvalidAccessError: 15,
                TypeMismatchError: 17,
                SecurityError: 18,
                NetworkError: 19,
                AbortError: 20,
                URLMismatchError: 21,
                QuotaExceededError: 22,
                TimeoutError: 23,
                InvalidNodeTypeError: 24,
                DataCloneError: 25,

                EncodingError: 0,
                NotReadableError: 0,
                UnknownError: 0,
                ConstraintError: 0,
                DataError: 0,
                TransactionInactiveError: 0,
                ReadOnlyError: 0,
                VersionError: 0,
                OperationError: 0,
                NotAllowedError: 0
            };

            var code_name_map = {};
            for (var key in name_code_map) {
                if (name_code_map[key] > 0) {
                    code_name_map[name_code_map[key]] = key;
                }
            }

            var required_props = {};
            var name;

            if (typeof type === "number") {
                if (type === 0) {
                    throw new AssertionError('Test bug: ambiguous DOMException code 0 passed to assert_throws_dom()');
                } else if (!(type in code_name_map)) {
                    throw new AssertionError('Test bug: unrecognized DOMException code "' + type + '" passed to assert_throws_dom()');
                }
                name = code_name_map[type];
                required_props.code = type;
            } else if (typeof type === "string") {
                name = type in codename_name_map ? codename_name_map[type] : type;
                if (!(name in name_code_map)) {
                    throw new AssertionError('Test bug: unrecognized DOMException code name or name "' + type + '" passed to assert_throws_dom()');
                }

                required_props.code = name_code_map[name];
            }

            if (required_props.code === 0 ||
               ("name" in e &&
                e.name !== e.name.toUpperCase() &&
                e.name !== "DOMException")) {
                // New style exception: also test the name property.
                required_props.name = name;
            }

            for (var prop in required_props) {
                assert(prop in e && e[prop] == required_props[prop],
                       assertion_type, description,
                       "${func} threw ${e} that is not a DOMException " + type + ": property ${prop} is equal to ${actual}, expected ${expected}",
                       {func:func, e:e, prop:prop, actual:e[prop], expected:required_props[prop]});
            }

            // Check that the exception is from the right global.  This check is last
            // so more specific, and more informative, checks on the properties can
            // happen in case a totally incorrect exception is thrown.
            assert(e.constructor === constructor,
                   assertion_type, description,
                   "${func} threw an exception from the wrong global",
                   {func});

        }
    }

    /**
     * Assert the provided value is thrown.
     *
     * @param {value} exception The expected exception.
     * @param {Function} func Function which should throw.
     * @param {string} description Error description for the case that the error is not thrown.
     */
    function assert_throws_exactly(exception, func, description)
    {
        assert_throws_exactly_impl(exception, func, description,
                                   "assert_throws_exactly");
    }
    expose(assert_throws_exactly, "assert_throws_exactly");

    /**
     * Like assert_throws_exactly but allows specifying the assertion type
     * (assert_throws_exactly or promise_rejects_exactly, in practice).
     */
    function assert_throws_exactly_impl(exception, func, description,
                                        assertion_type)
    {
        try {
            func.call(this);
            assert(false, assertion_type, description,
                   "${func} did not throw", {func:func});
        } catch (e) {
            if (e instanceof AssertionError) {
                throw e;
            }

            assert(same_value(e, exception), assertion_type, description,
                   "${func} threw ${e} but we expected it to throw ${exception}",
                   {func:func, e:e, exception:exception});
        }
    }

    function assert_unreached(description) {
         assert(false, "assert_unreached", description,
                "Reached unreachable code");
    }
    expose(assert_unreached, "assert_unreached");

    function assert_any(assert_func, actual, expected_array)
    {
        var args = [].slice.call(arguments, 3);
        var errors = [];
        var passed = false;
        forEach(expected_array,
                function(expected)
                {
                    try {
                        assert_func.apply(this, [actual, expected].concat(args));
                        passed = true;
                    } catch (e) {
                        errors.push(e.message);
                    }
                });
        if (!passed) {
            throw new AssertionError(errors.join("\n\n"));
        }
    }
    expose(assert_any, "assert_any");

    /**
     * Assert that a feature is implemented, based on a 'truthy' condition.
     *
     * This function should be used to early-exit from tests in which there is
     * no point continuing without support for a non-optional spec or spec
     * feature. For example:
     *
     *     assert_implements(window.Foo, 'Foo is not supported');
     *
     * @param {object} condition The truthy value to test
     * @param {string} description Error description for the case that the condition is not truthy.
     */
    function assert_implements(condition, description) {
        assert(!!condition, "assert_implements", description);
    }
    expose(assert_implements, "assert_implements")

    /**
     * Assert that an optional feature is implemented, based on a 'truthy' condition.
     *
     * This function should be used to early-exit from tests in which there is
     * no point continuing without support for an explicitly optional spec or
     * spec feature. For example:
     *
     *     assert_implements_optional(video.canPlayType("video/webm"),
     *                                "webm video playback not supported");
     *
     * @param {object} condition The truthy value to test
     * @param {string} description Error description for the case that the condition is not truthy.
     */
    function assert_implements_optional(condition, description) {
        if (!condition) {
            throw new OptionalFeatureUnsupportedError(description);
        }
    }
    expose(assert_implements_optional, "assert_implements_optional")

    function Test(name, properties)
    {
        if (tests.file_is_test && tests.tests.length) {
            throw new Error("Tried to create a test with file_is_test");
        }
        this.name = name;

        this.phase = (tests.is_aborted || tests.phase === tests.phases.COMPLETE) ?
            this.phases.COMPLETE : this.phases.INITIAL;

        this.status = this.NOTRUN;
        this.timeout_id = null;
        this.index = null;

        this.properties = properties || {};
        this.timeout_length = settings.test_timeout;
        if (this.timeout_length !== null) {
            this.timeout_length *= tests.timeout_multiplier;
        }

        this.message = null;
        this.stack = null;

        this.steps = [];
        this._is_promise_test = false;

        this.cleanup_callbacks = [];
        this._user_defined_cleanup_count = 0;
        this._done_callbacks = [];

        // Tests declared following harness completion are likely an indication
        // of a programming error, but they cannot be reported
        // deterministically.
        if (tests.phase === tests.phases.COMPLETE) {
            return;
        }

        tests.push(this);
    }

    Test.statuses = {
        PASS:0,
        FAIL:1,
        TIMEOUT:2,
        NOTRUN:3,
        PRECONDITION_FAILED:4
    };

    Test.prototype = merge({}, Test.statuses);

    Test.prototype.phases = {
        INITIAL:0,
        STARTED:1,
        HAS_RESULT:2,
        CLEANING:3,
        COMPLETE:4
    };

    Test.prototype.structured_clone = function()
    {
        if (!this._structured_clone) {
            var msg = this.message;
            msg = msg ? String(msg) : msg;
            this._structured_clone = merge({
                name:String(this.name),
                properties:merge({}, this.properties),
                phases:merge({}, this.phases)
            }, Test.statuses);
        }
        this._structured_clone.status = this.status;
        this._structured_clone.message = this.message;
        this._structured_clone.stack = this.stack;
        this._structured_clone.index = this.index;
        this._structured_clone.phase = this.phase;
        return this._structured_clone;
    };

    Test.prototype.step = function(func, this_obj)
    {
        if (this.phase > this.phases.STARTED) {
            return;
        }
        this.phase = this.phases.STARTED;
        //If we don't get a result before the harness times out that will be a test timeout
        this.set_status(this.TIMEOUT, "Test timed out");

        tests.started = true;
        tests.notify_test_state(this);

        if (this.timeout_id === null) {
            this.set_timeout();
        }

        this.steps.push(func);

        if (arguments.length === 1) {
            this_obj = this;
        }

        try {
            return func.apply(this_obj, Array.prototype.slice.call(arguments, 2));
        } catch (e) {
            if (this.phase >= this.phases.HAS_RESULT) {
                return;
            }
            var status = e instanceof OptionalFeatureUnsupportedError ? this.PRECONDITION_FAILED : this.FAIL;
            var message = String((typeof e === "object" && e !== null) ? e.message : e);
            var stack = e.stack ? e.stack : null;

            this.set_status(status, message, stack);
            this.phase = this.phases.HAS_RESULT;
            this.done();
        }
    };

    Test.prototype.step_func = function(func, this_obj)
    {
        var test_this = this;

        if (arguments.length === 1) {
            this_obj = test_this;
        }

        return function()
        {
            return test_this.step.apply(test_this, [func, this_obj].concat(
                Array.prototype.slice.call(arguments)));
        };
    };

    Test.prototype.step_func_done = function(func, this_obj)
    {
        var test_this = this;

        if (arguments.length === 1) {
            this_obj = test_this;
        }

        return function()
        {
            if (func) {
                test_this.step.apply(test_this, [func, this_obj].concat(
                    Array.prototype.slice.call(arguments)));
            }
            test_this.done();
        };
    };

    Test.prototype.unreached_func = function(description)
    {
        return this.step_func(function() {
            assert_unreached(description);
        });
    };

    Test.prototype.step_timeout = function(f, timeout) {
        var test_this = this;
        var args = Array.prototype.slice.call(arguments, 2);
        return setTimeout(this.step_func(function() {
            return f.apply(test_this, args);
        }), timeout * tests.timeout_multiplier);
    };

    Test.prototype.step_wait_func = function(cond, func, description,
                                             timeout=3000, interval=100) {
        /**
         * Poll for a function to return true, and call a callback
         * function once it does, or assert if a timeout is
         * reached. This is preferred over a simple step_timeout
         * whenever possible since it allows the timeout to be longer
         * to reduce intermittents without compromising test execution
         * speed when the condition is quickly met.
         *
         * @param {Function} cond A function taking no arguments and
         *                        returning a boolean. The callback is called
         *                        when this function returns true.
         * @param {Function} func A function taking no arguments to call once
         *                        the condition is met.
         * @param {string} description Error message to add to assert in case of
         *                             failure.
         * @param {number} timeout Timeout in ms. This is multiplied by the global
         *                         timeout_multiplier
         * @param {number} interval Polling interval in ms
         *
         **/

        var timeout_full = timeout * tests.timeout_multiplier;
        var remaining = Math.ceil(timeout_full / interval);
        var test_this = this;

        var wait_for_inner = test_this.step_func(() => {
            if (cond()) {
                func();
            } else {
                if(remaining === 0) {
                    assert(false, "step_wait_func", description,
                           "Timed out waiting on condition");
                }
                remaining--;
                setTimeout(wait_for_inner, interval);
            }
        });

        wait_for_inner();
    };

    Test.prototype.step_wait_func_done = function(cond, func, description,
                                                  timeout=3000, interval=100) {
        /**
         * Poll for a function to return true, and invoke a callback
         * followed by this.done() once it does, or assert if a timeout
         * is reached. This is preferred over a simple step_timeout
         * whenever possible since it allows the timeout to be longer
         * to reduce intermittents without compromising test execution speed
         * when the condition is quickly met.
         *
         * @param {Function} cond A function taking no arguments and
         *                        returning a boolean. The callback is called
         *                        when this function returns true.
         * @param {Function} func A function taking no arguments to call once
         *                        the condition is met.
         * @param {string} description Error message to add to assert in case of
         *                             failure.
         * @param {number} timeout Timeout in ms. This is multiplied by the global
         *                         timeout_multiplier
         * @param {number} interval Polling interval in ms
         *
         **/

         this.step_wait_func(cond, () => {
            if (func) {
                func();
            }
            this.done();
         }, description, timeout, interval);
    }

    Test.prototype.step_wait = function(cond, description, timeout=3000, interval=100) {
        /**
         * Poll for a function to return true, and resolve a promise
         * once it does, or assert if a timeout is reached. This is
         * preferred over a simple step_timeout whenever possible
         * since it allows the timeout to be longer to reduce
         * intermittents without compromising test execution speed
         * when the condition is quickly met.
         *
         * @param {Function} cond A function taking no arguments and
         *                        returning a boolean.
         * @param {string} description Error message to add to assert in case of
         *                             failure.
         * @param {number} timeout Timeout in ms. This is multiplied by the global
         *                         timeout_multiplier
         * @param {number} interval Polling interval in ms
         * @returns {Promise} Promise resolved once cond is met.
         *
         **/

        return new Promise(resolve => {
            this.step_wait_func(cond, resolve, description, timeout, interval);
        });
    }

    /*
     * Private method for registering cleanup functions. `testharness.js`
     * internals should use this method instead of the public `add_cleanup`
     * method in order to hide implementation details from the harness status
     * message in the case errors.
     */
    Test.prototype._add_cleanup = function(callback) {
        this.cleanup_callbacks.push(callback);
    };

    /*
     * Schedule a function to be run after the test result is known, regardless
     * of passing or failing state. The behavior of this function will not
     * influence the result of the test, but if an exception is thrown, the
     * test harness will report an error.
     */
    Test.prototype.add_cleanup = function(callback) {
        this._user_defined_cleanup_count += 1;
        this._add_cleanup(callback);
    };

    Test.prototype.set_timeout = function()
    {
        if (this.timeout_length !== null) {
            var this_obj = this;
            this.timeout_id = setTimeout(function()
                                         {
                                             this_obj.timeout();
                                         }, this.timeout_length);
        }
    };

    Test.prototype.set_status = function(status, message, stack)
    {
        this.status = status;
        this.message = message;
        this.stack = stack ? stack : null;
    };

    Test.prototype.timeout = function()
    {
        this.timeout_id = null;
        this.set_status(this.TIMEOUT, "Test timed out");
        this.phase = this.phases.HAS_RESULT;
        this.done();
    };

    Test.prototype.force_timeout = Test.prototype.timeout;

    /**
     * Update the test status, initiate "cleanup" functions, and signal test
     * completion.
     */
    Test.prototype.done = function()
    {
        if (this.phase >= this.phases.CLEANING) {
            return;
        }

        if (this.phase <= this.phases.STARTED) {
            this.set_status(this.PASS, null);
        }

        if (global_scope.clearTimeout) {
            clearTimeout(this.timeout_id);
        }

        this.cleanup();
    };

    function add_test_done_callback(test, callback)
    {
        if (test.phase === test.phases.COMPLETE) {
            callback();
            return;
        }

        test._done_callbacks.push(callback);
    }

    /*
     * Invoke all specified cleanup functions. If one or more produce an error,
     * the context is in an unpredictable state, so all further testing should
     * be cancelled.
     */
    Test.prototype.cleanup = function() {
        var error_count = 0;
        var bad_value_count = 0;
        function on_error() {
            error_count += 1;
            // Abort tests immediately so that tests declared within subsequent
            // cleanup functions are not run.
            tests.abort();
        }
        var this_obj = this;
        var results = [];

        this.phase = this.phases.CLEANING;

        forEach(this.cleanup_callbacks,
                function(cleanup_callback) {
                    var result;

                    try {
                        result = cleanup_callback();
                    } catch (e) {
                        on_error();
                        return;
                    }

                    if (!is_valid_cleanup_result(this_obj, result)) {
                        bad_value_count += 1;
                        // Abort tests immediately so that tests declared
                        // within subsequent cleanup functions are not run.
                        tests.abort();
                    }

                    results.push(result);
                });

        if (!this._is_promise_test) {
            cleanup_done(this_obj, error_count, bad_value_count);
        } else {
            all_async(results,
                      function(result, done) {
                          if (result && typeof result.then === "function") {
                              result
                                  .then(null, on_error)
                                  .then(done);
                          } else {
                              done();
                          }
                      },
                      function() {
                          cleanup_done(this_obj, error_count, bad_value_count);
                      });
        }
    };

    /**
     * Determine if the return value of a cleanup function is valid for a given
     * test. Any test may return the value `undefined`. Tests created with
     * `promise_test` may alternatively return "thenable" object values.
     */
    function is_valid_cleanup_result(test, result) {
        if (result === undefined) {
            return true;
        }

        if (test._is_promise_test) {
            return result && typeof result.then === "function";
        }

        return false;
    }

    function cleanup_done(test, error_count, bad_value_count) {
        if (error_count || bad_value_count) {
            var total = test._user_defined_cleanup_count;

            tests.status.status = tests.status.ERROR;
            tests.status.message = "Test named '" + test.name +
                "' specified " + total +
                " 'cleanup' function" + (total > 1 ? "s" : "");

            if (error_count) {
                tests.status.message += ", and " + error_count + " failed";
            }

            if (bad_value_count) {
                var type = test._is_promise_test ?
                   "non-thenable" : "non-undefined";
                tests.status.message += ", and " + bad_value_count +
                    " returned a " + type + " value";
            }

            tests.status.message += ".";

            tests.status.stack = null;
        }

        test.phase = test.phases.COMPLETE;
        tests.result(test);
        forEach(test._done_callbacks,
                function(callback) {
                    callback();
                });
        test._done_callbacks.length = 0;
    }

    /*
     * A RemoteTest object mirrors a Test object on a remote worker. The
     * associated RemoteWorker updates the RemoteTest object in response to
     * received events. In turn, the RemoteTest object replicates these events
     * on the local document. This allows listeners (test result reporting
     * etc..) to transparently handle local and remote events.
     */
    function RemoteTest(clone) {
        var this_obj = this;
        Object.keys(clone).forEach(
                function(key) {
                    this_obj[key] = clone[key];
                });
        this.index = null;
        this.phase = this.phases.INITIAL;
        this.update_state_from(clone);
        this._done_callbacks = [];
        tests.push(this);
    }

    RemoteTest.prototype.structured_clone = function() {
        var clone = {};
        Object.keys(this).forEach(
                (function(key) {
                    var value = this[key];
                    // `RemoteTest` instances are responsible for managing
                    // their own "done" callback functions, so those functions
                    // are not relevant in other execution contexts. Because of
                    // this (and because Function values cannot be serialized
                    // for cross-realm transmittance), the property should not
                    // be considered when cloning instances.
                    if (key === '_done_callbacks' ) {
                        return;
                    }

                    if (typeof value === "object" && value !== null) {
                        clone[key] = merge({}, value);
                    } else {
                        clone[key] = value;
                    }
                }).bind(this));
        clone.phases = merge({}, this.phases);
        return clone;
    };

    /**
     * `RemoteTest` instances are objects which represent tests running in
     * another realm. They do not define "cleanup" functions (if necessary,
     * such functions are defined on the associated `Test` instance within the
     * external realm). However, `RemoteTests` may have "done" callbacks (e.g.
     * as attached by the `Tests` instance responsible for tracking the overall
     * test status in the parent realm). The `cleanup` method delegates to
     * `done` in order to ensure that such callbacks are invoked following the
     * completion of the `RemoteTest`.
     */
    RemoteTest.prototype.cleanup = function() {
        this.done();
    };
    RemoteTest.prototype.phases = Test.prototype.phases;
    RemoteTest.prototype.update_state_from = function(clone) {
        this.status = clone.status;
        this.message = clone.message;
        this.stack = clone.stack;
        if (this.phase === this.phases.INITIAL) {
            this.phase = this.phases.STARTED;
        }
    };
    RemoteTest.prototype.done = function() {
        this.phase = this.phases.COMPLETE;

        forEach(this._done_callbacks,
                function(callback) {
                    callback();
                });
    }

    /*
     * A RemoteContext listens for test events from a remote test context, such
     * as another window or a worker. These events are then used to construct
     * and maintain RemoteTest objects that mirror the tests running in the
     * remote context.
     *
     * An optional third parameter can be used as a predicate to filter incoming
     * MessageEvents.
     */
    function RemoteContext(remote, message_target, message_filter) {
        this.running = true;
        this.started = false;
        this.tests = new Array();
        this.early_exception = null;

        var this_obj = this;
        // If remote context is cross origin assigning to onerror is not
        // possible, so silently catch those errors.
        try {
          remote.onerror = function(error) { this_obj.remote_error(error); };
        } catch (e) {
          // Ignore.
        }

        // Keeping a reference to the remote object and the message handler until
        // remote_done() is seen prevents the remote object and its message channel
        // from going away before all the messages are dispatched.
        this.remote = remote;
        this.message_target = message_target;
        this.message_handler = function(message) {
            var passesFilter = !message_filter || message_filter(message);
            // The reference to the `running` property in the following
            // condition is unnecessary because that value is only set to
            // `false` after the `message_handler` function has been
            // unsubscribed.
            // TODO: Simplify the condition by removing the reference.
            if (this_obj.running && message.data && passesFilter &&
                (message.data.type in this_obj.message_handlers)) {
                this_obj.message_handlers[message.data.type].call(this_obj, message.data);
            }
        };

        if (self.Promise) {
            this.done = new Promise(function(resolve) {
                this_obj.doneResolve = resolve;
            });
        }

        this.message_target.addEventListener("message", this.message_handler);
    }

    RemoteContext.prototype.remote_error = function(error) {
        if (error.preventDefault) {
            error.preventDefault();
        }

        // Defer interpretation of errors until the testing protocol has
        // started and the remote test's `allow_uncaught_exception` property
        // is available.
        if (!this.started) {
            this.early_exception = error;
        } else if (!this.allow_uncaught_exception) {
            this.report_uncaught(error);
        }
    };

    RemoteContext.prototype.report_uncaught = function(error) {
        var message = error.message || String(error);
        var filename = (error.filename ? " " + error.filename: "");
        // FIXME: Display remote error states separately from main document
        // error state.
        tests.set_status(tests.status.ERROR,
                         "Error in remote" + filename + ": " + message,
                         error.stack);
    };

    RemoteContext.prototype.start = function(data) {
        this.started = true;
        this.allow_uncaught_exception = data.properties.allow_uncaught_exception;

        if (this.early_exception && !this.allow_uncaught_exception) {
            this.report_uncaught(this.early_exception);
        }
    };

    RemoteContext.prototype.test_state = function(data) {
        var remote_test = this.tests[data.test.index];
        if (!remote_test) {
            remote_test = new RemoteTest(data.test);
            this.tests[data.test.index] = remote_test;
        }
        remote_test.update_state_from(data.test);
        tests.notify_test_state(remote_test);
    };

    RemoteContext.prototype.test_done = function(data) {
        var remote_test = this.tests[data.test.index];
        remote_test.update_state_from(data.test);
        remote_test.done();
        tests.result(remote_test);
    };

    RemoteContext.prototype.remote_done = function(data) {
        if (tests.status.status === null &&
            data.status.status !== data.status.OK) {
            tests.set_status(data.status.status, data.status.message, data.status.sack);
        }

        this.message_target.removeEventListener("message", this.message_handler);
        this.running = false;

        // If remote context is cross origin assigning to onerror is not
        // possible, so silently catch those errors.
        try {
          this.remote.onerror = null;
        } catch (e) {
          // Ignore.
        }

        this.remote = null;
        this.message_target = null;
        if (this.doneResolve) {
            this.doneResolve();
        }

        if (tests.all_done()) {
            tests.complete();
        }
    };

    RemoteContext.prototype.message_handlers = {
        start: RemoteContext.prototype.start,
        test_state: RemoteContext.prototype.test_state,
        result: RemoteContext.prototype.test_done,
        complete: RemoteContext.prototype.remote_done
    };

    /*
     * Harness
     */

    function TestsStatus()
    {
        this.status = null;
        this.message = null;
        this.stack = null;
    }

    TestsStatus.statuses = {
        OK:0,
        ERROR:1,
        TIMEOUT:2,
        PRECONDITION_FAILED:3
    };

    TestsStatus.prototype = merge({}, TestsStatus.statuses);

    TestsStatus.prototype.structured_clone = function()
    {
        if (!this._structured_clone) {
            var msg = this.message;
            msg = msg ? String(msg) : msg;
            this._structured_clone = merge({
                status:this.status,
                message:msg,
                stack:this.stack
            }, TestsStatus.statuses);
        }
        return this._structured_clone;
    };

    function Tests()
    {
        this.tests = [];
        this.num_pending = 0;

        this.phases = {
            INITIAL:0,
            SETUP:1,
            HAVE_TESTS:2,
            HAVE_RESULTS:3,
            COMPLETE:4
        };
        this.phase = this.phases.INITIAL;

        this.properties = {};

        this.wait_for_finish = false;
        this.processing_callbacks = false;

        this.allow_uncaught_exception = false;

        this.file_is_test = false;
        // This value is lazily initialized in order to avoid introducing a
        // dependency on ECMAScript 2015 Promises to all tests.
        this.promise_tests = null;
        this.promise_setup_called = false;

        this.timeout_multiplier = 1;
        this.timeout_length = test_environment.test_timeout();
        this.timeout_id = null;

        this.start_callbacks = [];
        this.test_state_callbacks = [];
        this.test_done_callbacks = [];
        this.all_done_callbacks = [];

        this.hide_test_state = false;
        this.pending_remotes = [];

        this.status = new TestsStatus();

        var this_obj = this;

        test_environment.add_on_loaded_callback(function() {
            if (this_obj.all_done()) {
                this_obj.complete();
            }
        });

        this.set_timeout();
    }

    Tests.prototype.setup = function(func, properties)
    {
        if (this.phase >= this.phases.HAVE_RESULTS) {
            return;
        }

        if (this.phase < this.phases.SETUP) {
            this.phase = this.phases.SETUP;
        }

        this.properties = properties;

        for (var p in properties) {
            if (properties.hasOwnProperty(p)) {
                var value = properties[p];
                if (p == "allow_uncaught_exception") {
                    this.allow_uncaught_exception = value;
                } else if (p == "explicit_done" && value) {
                    this.wait_for_finish = true;
                } else if (p == "explicit_timeout" && value) {
                    this.timeout_length = null;
                    if (this.timeout_id)
                    {
                        clearTimeout(this.timeout_id);
                    }
                } else if (p == "single_test" && value) {
                    this.set_file_is_test();
                } else if (p == "timeout_multiplier") {
                    this.timeout_multiplier = value;
                    if (this.timeout_length) {
                         this.timeout_length *= this.timeout_multiplier;
                    }
                } else if (p == "hide_test_state") {
                    this.hide_test_state = value;
                }
            }
        }

        if (func) {
            try {
                func();
            } catch (e) {
                this.status.status = e instanceof OptionalFeatureUnsupportedError ? this.status.PRECONDITION_FAILED : this.status.ERROR;
                this.status.message = String(e);
                this.status.stack = e.stack ? e.stack : null;
                this.complete();
            }
        }
        this.set_timeout();
    };

    Tests.prototype.set_file_is_test = function() {
        if (this.tests.length > 0) {
            throw new Error("Tried to set file as test after creating a test");
        }
        this.wait_for_finish = true;
        this.file_is_test = true;
        // Create the test, which will add it to the list of tests
        async_test();
    };

    Tests.prototype.set_status = function(status, message, stack)
    {
        this.status.status = status;
        this.status.message = message;
        this.status.stack = stack ? stack : null;
    };

    Tests.prototype.set_timeout = function() {
        if (global_scope.clearTimeout) {
            var this_obj = this;
            clearTimeout(this.timeout_id);
            if (this.timeout_length !== null) {
                this.timeout_id = setTimeout(function() {
                                                 this_obj.timeout();
                                             }, this.timeout_length);
            }
        }
    };

    Tests.prototype.timeout = function() {
        var test_in_cleanup = null;

        if (this.status.status === null) {
            forEach(this.tests,
                    function(test) {
                        // No more than one test is expected to be in the
                        // "CLEANUP" phase at any time
                        if (test.phase === test.phases.CLEANING) {
                            test_in_cleanup = test;
                        }

                        test.phase = test.phases.COMPLETE;
                    });

            // Timeouts that occur while a test is in the "cleanup" phase
            // indicate that some global state was not properly reverted. This
            // invalidates the overall test execution, so the timeout should be
            // reported as an error and cancel the execution of any remaining
            // tests.
            if (test_in_cleanup) {
                this.status.status = this.status.ERROR;
                this.status.message = "Timeout while running cleanup for " +
                    "test named \"" + test_in_cleanup.name + "\".";
                tests.status.stack = null;
            } else {
                this.status.status = this.status.TIMEOUT;
            }
        }

        this.complete();
    };

    Tests.prototype.end_wait = function()
    {
        this.wait_for_finish = false;
        if (this.all_done()) {
            this.complete();
        }
    };

    Tests.prototype.push = function(test)
    {
        if (this.phase < this.phases.HAVE_TESTS) {
            this.start();
        }
        this.num_pending++;
        test.index = this.tests.push(test);
        this.notify_test_state(test);
    };

    Tests.prototype.notify_test_state = function(test) {
        var this_obj = this;
        forEach(this.test_state_callbacks,
                function(callback) {
                    callback(test, this_obj);
                });
    };

    Tests.prototype.all_done = function() {
        return this.tests.length > 0 && test_environment.all_loaded &&
                (this.num_pending === 0 || this.is_aborted) && !this.wait_for_finish &&
                !this.processing_callbacks &&
                !this.pending_remotes.some(function(w) { return w.running; });
    };

    Tests.prototype.start = function() {
        this.phase = this.phases.HAVE_TESTS;
        this.notify_start();
    };

    Tests.prototype.notify_start = function() {
        var this_obj = this;
        forEach (this.start_callbacks,
                 function(callback)
                 {
                     callback(this_obj.properties);
                 });
    };

    Tests.prototype.result = function(test)
    {
        // If the harness has already transitioned beyond the `HAVE_RESULTS`
        // phase, subsequent tests should not cause it to revert.
        if (this.phase <= this.phases.HAVE_RESULTS) {
            this.phase = this.phases.HAVE_RESULTS;
        }
        this.num_pending--;
        this.notify_result(test);
    };

    Tests.prototype.notify_result = function(test) {
        var this_obj = this;
        this.processing_callbacks = true;
        forEach(this.test_done_callbacks,
                function(callback)
                {
                    callback(test, this_obj);
                });
        this.processing_callbacks = false;
        if (this_obj.all_done()) {
            this_obj.complete();
        }
    };

    Tests.prototype.complete = function() {
        if (this.phase === this.phases.COMPLETE) {
            return;
        }
        var this_obj = this;
        var all_complete = function() {
            this_obj.phase = this_obj.phases.COMPLETE;
            this_obj.notify_complete();
        };
        var incomplete = filter(this.tests,
                                function(test) {
                                    return test.phase < test.phases.COMPLETE;
                                });

        /**
         * To preserve legacy behavior, overall test completion must be
         * signaled synchronously.
         */
        if (incomplete.length === 0) {
            all_complete();
            return;
        }

        all_async(incomplete,
                  function(test, testDone)
                  {
                      if (test.phase === test.phases.INITIAL) {
                          test.phase = test.phases.COMPLETE;
                          testDone();
                      } else {
                          add_test_done_callback(test, testDone);
                          test.cleanup();
                      }
                  },
                  all_complete);
    };

    /**
     * Update the harness status to reflect an unrecoverable harness error that
     * should cancel all further testing. Update all previously-defined tests
     * which have not yet started to indicate that they will not be executed.
     */
    Tests.prototype.abort = function() {
        this.status.status = this.status.ERROR;
        this.is_aborted = true;

        forEach(this.tests,
                function(test) {
                    if (test.phase === test.phases.INITIAL) {
                        test.phase = test.phases.COMPLETE;
                    }
                });
    };

    /*
     * Determine if any tests share the same `name` property. Return an array
     * containing the names of any such duplicates.
     */
    Tests.prototype.find_duplicates = function() {
        var names = Object.create(null);
        var duplicates = [];

        forEach (this.tests,
                 function(test)
                 {
                     if (test.name in names && duplicates.indexOf(test.name) === -1) {
                        duplicates.push(test.name);
                     }
                     names[test.name] = true;
                 });

        return duplicates;
    };

    function code_unit_str(char) {
        return 'U+' + char.charCodeAt(0).toString(16);
    }

    function sanitize_unpaired_surrogates(str) {
        return str.replace(
            /([\ud800-\udbff]+)(?![\udc00-\udfff])|(^|[^\ud800-\udbff])([\udc00-\udfff]+)/g,
            function(_, low, prefix, high) {
                var output = prefix || "";  // prefix may be undefined
                var string = low || high;  // only one of these alternates can match
                for (var i = 0; i < string.length; i++) {
                    output += code_unit_str(string[i]);
                }
                return output;
            });
    }

    function sanitize_all_unpaired_surrogates(tests) {
        forEach (tests,
                 function (test)
                 {
                     var sanitized = sanitize_unpaired_surrogates(test.name);

                     if (test.name !== sanitized) {
                         test.name = sanitized;
                         delete test._structured_clone;
                     }
                 });
    }

    Tests.prototype.notify_complete = function() {
        var this_obj = this;
        var duplicates;

        if (this.status.status === null) {
            duplicates = this.find_duplicates();

            // Some transports adhere to UTF-8's restriction on unpaired
            // surrogates. Sanitize the titles so that the results can be
            // consistently sent via all transports.
            sanitize_all_unpaired_surrogates(this.tests);

            // Test names are presumed to be unique within test files--this
            // allows consumers to use them for identification purposes.
            // Duplicated names violate this expectation and should therefore
            // be reported as an error.
            if (duplicates.length) {
                this.status.status = this.status.ERROR;
                this.status.message =
                   duplicates.length + ' duplicate test name' +
                   (duplicates.length > 1 ? 's' : '') + ': "' +
                   duplicates.join('", "') + '"';
            } else {
                this.status.status = this.status.OK;
            }
        }

        forEach (this.all_done_callbacks,
                 function(callback)
                 {
                     callback(this_obj.tests, this_obj.status);
                 });
    };

    /*
     * Constructs a RemoteContext that tracks tests from a specific worker.
     */
    Tests.prototype.create_remote_worker = function(worker) {
        var message_port;

        if (is_service_worker(worker)) {
            message_port = navigator.serviceWorker;
            worker.postMessage({type: "connect"});
        } else if (is_shared_worker(worker)) {
            message_port = worker.port;
            message_port.start();
        } else {
            message_port = worker;
        }

        return new RemoteContext(worker, message_port);
    };

    /*
     * Constructs a RemoteContext that tracks tests from a specific window.
     */
    Tests.prototype.create_remote_window = function(remote) {
        remote.postMessage({type: "getmessages"}, "*");
        return new RemoteContext(
            remote,
            window,
            function(msg) {
                return msg.source === remote;
            }
        );
    };

    Tests.prototype.fetch_tests_from_worker = function(worker) {
        if (this.phase >= this.phases.COMPLETE) {
            return;
        }

        var remoteContext = this.create_remote_worker(worker);
        this.pending_remotes.push(remoteContext);
        return remoteContext.done;
    };

    function fetch_tests_from_worker(port) {
        return tests.fetch_tests_from_worker(port);
    }
    expose(fetch_tests_from_worker, 'fetch_tests_from_worker');

    Tests.prototype.fetch_tests_from_window = function(remote) {
        if (this.phase >= this.phases.COMPLETE) {
            return;
        }

        this.pending_remotes.push(this.create_remote_window(remote));
    };

    function fetch_tests_from_window(window) {
        tests.fetch_tests_from_window(window);
    }
    expose(fetch_tests_from_window, 'fetch_tests_from_window');

    function timeout() {
        if (tests.timeout_length === null) {
            tests.timeout();
        }
    }
    expose(timeout, 'timeout');

    function add_start_callback(callback) {
        tests.start_callbacks.push(callback);
    }

    function add_test_state_callback(callback) {
        tests.test_state_callbacks.push(callback);
    }

    function add_result_callback(callback) {
        tests.test_done_callbacks.push(callback);
    }

    function add_completion_callback(callback) {
        tests.all_done_callbacks.push(callback);
    }

    expose(add_start_callback, 'add_start_callback');
    expose(add_test_state_callback, 'add_test_state_callback');
    expose(add_result_callback, 'add_result_callback');
    expose(add_completion_callback, 'add_completion_callback');

    function remove(array, item) {
        var index = array.indexOf(item);
        if (index > -1) {
            array.splice(index, 1);
        }
    }

    function remove_start_callback(callback) {
        remove(tests.start_callbacks, callback);
    }

    function remove_test_state_callback(callback) {
        remove(tests.test_state_callbacks, callback);
    }

    function remove_result_callback(callback) {
        remove(tests.test_done_callbacks, callback);
    }

    function remove_completion_callback(callback) {
       remove(tests.all_done_callbacks, callback);
    }

    /*
     * Output listener
    */

    function Output() {
        this.output_document = document;
        this.output_node = null;
        this.enabled = settings.output;
        this.phase = this.INITIAL;
    }

    Output.prototype.INITIAL = 0;
    Output.prototype.STARTED = 1;
    Output.prototype.HAVE_RESULTS = 2;
    Output.prototype.COMPLETE = 3;

    Output.prototype.setup = function(properties) {
        if (this.phase > this.INITIAL) {
            return;
        }

        //If output is disabled in testharnessreport.js the test shouldn't be
        //able to override that
        this.enabled = this.enabled && (properties.hasOwnProperty("output") ?
                                        properties.output : settings.output);
    };

    Output.prototype.init = function(properties) {
        if (this.phase >= this.STARTED) {
            return;
        }
        if (properties.output_document) {
            this.output_document = properties.output_document;
        } else {
            this.output_document = document;
        }
        this.phase = this.STARTED;
    };

    Output.prototype.resolve_log = function() {
        var output_document;
        if (this.output_node) {
            return;
        }
        if (typeof this.output_document === "function") {
            output_document = this.output_document.apply(undefined);
        } else {
            output_document = this.output_document;
        }
        if (!output_document) {
            return;
        }
        var node = output_document.getElementById("log");
        if (!node) {
            if (output_document.readyState === "loading") {
                return;
            }
            node = output_document.createElementNS("http://www.w3.org/1999/xhtml", "div");
            node.id = "log";
            if (output_document.body) {
                output_document.body.appendChild(node);
            } else {
                var root = output_document.documentElement;
                var is_html = (root &&
                               root.namespaceURI == "http://www.w3.org/1999/xhtml" &&
                               root.localName == "html");
                var is_svg = (output_document.defaultView &&
                              "SVGSVGElement" in output_document.defaultView &&
                              root instanceof output_document.defaultView.SVGSVGElement);
                if (is_svg) {
                    var foreignObject = output_document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
                    foreignObject.setAttribute("width", "100%");
                    foreignObject.setAttribute("height", "100%");
                    root.appendChild(foreignObject);
                    foreignObject.appendChild(node);
                } else if (is_html) {
                    root.appendChild(output_document.createElementNS("http://www.w3.org/1999/xhtml", "body"))
                        .appendChild(node);
                } else {
                    root.appendChild(node);
                }
            }
        }
        this.output_document = output_document;
        this.output_node = node;
    };

    Output.prototype.show_status = function() {
        if (this.phase < this.STARTED) {
            this.init();
        }
        if (!this.enabled || this.phase === this.COMPLETE) {
            return;
        }
        this.resolve_log();
        if (this.phase < this.HAVE_RESULTS) {
            this.phase = this.HAVE_RESULTS;
        }
        var done_count = tests.tests.length - tests.num_pending;
        if (this.output_node && !tests.hide_test_state) {
            if (done_count < 100 ||
                (done_count < 1000 && done_count % 100 === 0) ||
                done_count % 1000 === 0) {
                this.output_node.textContent = "Running, " +
                    done_count + " complete, " +
                    tests.num_pending + " remain";
            }
        }
    };

    Output.prototype.show_results = function (tests, harness_status) {
        if (this.phase >= this.COMPLETE) {
            return;
        }
        if (!this.enabled) {
            return;
        }
        if (!this.output_node) {
            this.resolve_log();
        }
        this.phase = this.COMPLETE;

        var log = this.output_node;
        if (!log) {
            return;
        }
        var output_document = this.output_document;

        while (log.lastChild) {
            log.removeChild(log.lastChild);
        }

        var stylesheet = output_document.createElementNS(xhtml_ns, "style");
        stylesheet.textContent = stylesheetContent;
        var heads = output_document.getElementsByTagName("head");
        if (heads.length) {
            heads[0].appendChild(stylesheet);
        }

        var status_text_harness = {};
        status_text_harness[harness_status.OK] = "OK";
        status_text_harness[harness_status.ERROR] = "Error";
        status_text_harness[harness_status.TIMEOUT] = "Timeout";
        status_text_harness[harness_status.PRECONDITION_FAILED] = "Optional Feature Unsupported";

        var status_text = {};
        status_text[Test.prototype.PASS] = "Pass";
        status_text[Test.prototype.FAIL] = "Fail";
        status_text[Test.prototype.TIMEOUT] = "Timeout";
        status_text[Test.prototype.NOTRUN] = "Not Run";
        status_text[Test.prototype.PRECONDITION_FAILED] = "Optional Feature Unsupported";

        var status_number = {};
        forEach(tests,
                function(test) {
                    var status = status_text[test.status];
                    if (status_number.hasOwnProperty(status)) {
                        status_number[status] += 1;
                    } else {
                        status_number[status] = 1;
                    }
                });

        function status_class(status)
        {
            return status.replace(/\s/g, '').toLowerCase();
        }

        var summary_template = ["section", {"id":"summary"},
                                ["h2", {}, "Summary"],
                                function()
                                {

                                    var status = status_text_harness[harness_status.status];
                                    var rv = [["section", {},
                                               ["p", {},
                                                "Harness status: ",
                                                ["span", {"class":status_class(status)},
                                                 status
                                                ],
                                               ]
                                              ]];

                                    if (harness_status.status === harness_status.ERROR) {
                                        rv[0].push(["pre", {}, harness_status.message]);
                                        if (harness_status.stack) {
                                            rv[0].push(["pre", {}, harness_status.stack]);
                                        }
                                    }
                                    return rv;
                                },
                                ["p", {}, "Found ${num_tests} tests"],
                                function() {
                                    var rv = [["div", {}]];
                                    var i = 0;
                                    while (status_text.hasOwnProperty(i)) {
                                        if (status_number.hasOwnProperty(status_text[i])) {
                                            var status = status_text[i];
                                            rv[0].push(["div", {"class":status_class(status)},
                                                        ["label", {},
                                                         ["input", {type:"checkbox", checked:"checked"}],
                                                         status_number[status] + " " + status]]);
                                        }
                                        i++;
                                    }
                                    return rv;
                                },
                               ];

        log.appendChild(render(summary_template, {num_tests:tests.length}, output_document));

        forEach(output_document.querySelectorAll("section#summary label"),
                function(element)
                {
                    on_event(element, "click",
                             function(e)
                             {
                                 if (output_document.getElementById("results") === null) {
                                     e.preventDefault();
                                     return;
                                 }
                                 var result_class = element.parentNode.getAttribute("class");
                                 var style_element = output_document.querySelector("style#hide-" + result_class);
                                 var input_element = element.querySelector("input");
                                 if (!style_element && !input_element.checked) {
                                     style_element = output_document.createElementNS(xhtml_ns, "style");
                                     style_element.id = "hide-" + result_class;
                                     style_element.textContent = "table#results > tbody > tr."+result_class+"{display:none}";
                                     output_document.body.appendChild(style_element);
                                 } else if (style_element && input_element.checked) {
                                     style_element.parentNode.removeChild(style_element);
                                 }
                             });
                });

        // This use of innerHTML plus manual escaping is not recommended in
        // general, but is necessary here for performance.  Using textContent
        // on each individual <td> adds tens of seconds of execution time for
        // large test suites (tens of thousands of tests).
        function escape_html(s)
        {
            return s.replace(/\&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/"/g, "&quot;")
                .replace(/'/g, "&#39;");
        }

        function has_assertions()
        {
            for (var i = 0; i < tests.length; i++) {
                if (tests[i].properties.hasOwnProperty("assert")) {
                    return true;
                }
            }
            return false;
        }

        function get_assertion(test)
        {
            if (test.properties.hasOwnProperty("assert")) {
                if (Array.isArray(test.properties.assert)) {
                    return test.properties.assert.join(' ');
                }
                return test.properties.assert;
            }
            return '';
        }

        log.appendChild(document.createElementNS(xhtml_ns, "section"));
        var assertions = has_assertions();
        var html = "<h2>Details</h2><table id='results' " + (assertions ? "class='assertions'" : "" ) + ">" +
            "<thead><tr><th>Result</th><th>Test Name</th>" +
            (assertions ? "<th>Assertion</th>" : "") +
            "<th>Message</th></tr></thead>" +
            "<tbody>";
        for (var i = 0; i < tests.length; i++) {
            html += '<tr class="' +
                escape_html(status_class(status_text[tests[i].status])) +
                '"><td>' +
                escape_html(status_text[tests[i].status]) +
                "</td><td>" +
                escape_html(tests[i].name) +
                "</td><td>" +
                (assertions ? escape_html(get_assertion(tests[i])) + "</td><td>" : "") +
                escape_html(tests[i].message ? tests[i].message : " ") +
                (tests[i].stack ? "<pre>" +
                 escape_html(tests[i].stack) +
                 "</pre>": "") +
                "</td></tr>";
        }
        html += "</tbody></table>";
        try {
            log.lastChild.innerHTML = html;
        } catch (e) {
            log.appendChild(document.createElementNS(xhtml_ns, "p"))
               .textContent = "Setting innerHTML for the log threw an exception.";
            log.appendChild(document.createElementNS(xhtml_ns, "pre"))
               .textContent = html;
        }
    };

    /*
     * Template code
     *
     * A template is just a JavaScript structure. An element is represented as:
     *
     * [tag_name, {attr_name:attr_value}, child1, child2]
     *
     * the children can either be strings (which act like text nodes), other templates or
     * functions (see below)
     *
     * A text node is represented as
     *
     * ["{text}", value]
     *
     * String values have a simple substitution syntax; ${foo} represents a variable foo.
     *
     * It is possible to embed logic in templates by using a function in a place where a
     * node would usually go. The function must either return part of a template or null.
     *
     * In cases where a set of nodes are required as output rather than a single node
     * with children it is possible to just use a list
     * [node1, node2, node3]
     *
     * Usage:
     *
     * render(template, substitutions) - take a template and an object mapping
     * variable names to parameters and return either a DOM node or a list of DOM nodes
     *
     * substitute(template, substitutions) - take a template and variable mapping object,
     * make the variable substitutions and return the substituted template
     *
     */

    function is_single_node(template)
    {
        return typeof template[0] === "string";
    }

    function substitute(template, substitutions)
    {
        if (typeof template === "function") {
            var replacement = template(substitutions);
            if (!replacement) {
                return null;
            }

            return substitute(replacement, substitutions);
        }

        if (is_single_node(template)) {
            return substitute_single(template, substitutions);
        }

        return filter(map(template, function(x) {
                              return substitute(x, substitutions);
                          }), function(x) {return x !== null;});
    }

    function substitute_single(template, substitutions)
    {
        var substitution_re = /\$\{([^ }]*)\}/g;

        function do_substitution(input) {
            var components = input.split(substitution_re);
            var rv = [];
            for (var i = 0; i < components.length; i += 2) {
                rv.push(components[i]);
                if (components[i + 1]) {
                    rv.push(String(substitutions[components[i + 1]]));
                }
            }
            return rv;
        }

        function substitute_attrs(attrs, rv)
        {
            rv[1] = {};
            for (var name in template[1]) {
                if (attrs.hasOwnProperty(name)) {
                    var new_name = do_substitution(name).join("");
                    var new_value = do_substitution(attrs[name]).join("");
                    rv[1][new_name] = new_value;
                }
            }
        }

        function substitute_children(children, rv)
        {
            for (var i = 0; i < children.length; i++) {
                if (children[i] instanceof Object) {
                    var replacement = substitute(children[i], substitutions);
                    if (replacement !== null) {
                        if (is_single_node(replacement)) {
                            rv.push(replacement);
                        } else {
                            extend(rv, replacement);
                        }
                    }
                } else {
                    extend(rv, do_substitution(String(children[i])));
                }
            }
            return rv;
        }

        var rv = [];
        rv.push(do_substitution(String(template[0])).join(""));

        if (template[0] === "{text}") {
            substitute_children(template.slice(1), rv);
        } else {
            substitute_attrs(template[1], rv);
            substitute_children(template.slice(2), rv);
        }

        return rv;
    }

    function make_dom_single(template, doc)
    {
        var output_document = doc || document;
        var element;
        if (template[0] === "{text}") {
            element = output_document.createTextNode("");
            for (var i = 1; i < template.length; i++) {
                element.data += template[i];
            }
        } else {
            element = output_document.createElementNS(xhtml_ns, template[0]);
            for (var name in template[1]) {
                if (template[1].hasOwnProperty(name)) {
                    element.setAttribute(name, template[1][name]);
                }
            }
            for (var i = 2; i < template.length; i++) {
                if (template[i] instanceof Object) {
                    var sub_element = make_dom(template[i]);
                    element.appendChild(sub_element);
                } else {
                    var text_node = output_document.createTextNode(template[i]);
                    element.appendChild(text_node);
                }
            }
        }

        return element;
    }

    function make_dom(template, substitutions, output_document)
    {
        if (is_single_node(template)) {
            return make_dom_single(template, output_document);
        }

        return map(template, function(x) {
                       return make_dom_single(x, output_document);
                   });
    }

    function render(template, substitutions, output_document)
    {
        return make_dom(substitute(template, substitutions), output_document);
    }

    /*
     * Utility functions
     */
    function assert(expected_true, function_name, description, error, substitutions)
    {
        if (expected_true !== true) {
            var msg = make_message(function_name, description,
                                   error, substitutions);
            throw new AssertionError(msg);
        }
    }

    function AssertionError(message)
    {
        if (typeof message == "string") {
            message = sanitize_unpaired_surrogates(message);
        }
        this.message = message;
        this.stack = this.get_stack();
    }
    expose(AssertionError, "AssertionError");

    AssertionError.prototype = Object.create(Error.prototype);

    AssertionError.prototype.get_stack = function() {
        var stack = new Error().stack;
        // IE11 does not initialize 'Error.stack' until the object is thrown.
        if (!stack) {
            try {
                throw new Error();
            } catch (e) {
                stack = e.stack;
            }
        }

        // 'Error.stack' is not supported in all browsers/versions
        if (!stack) {
            return "(Stack trace unavailable)";
        }

        var lines = stack.split("\n");

        // Create a pattern to match stack frames originating within testharness.js.  These include the
        // script URL, followed by the line/col (e.g., '/resources/testharness.js:120:21').
        // Escape the URL per http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
        // in case it contains RegExp characters.
        var script_url = get_script_url();
        var re_text = script_url ? script_url.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') : "\\btestharness.js";
        var re = new RegExp(re_text + ":\\d+:\\d+");

        // Some browsers include a preamble that specifies the type of the error object.  Skip this by
        // advancing until we find the first stack frame originating from testharness.js.
        var i = 0;
        while (!re.test(lines[i]) && i < lines.length) {
            i++;
        }

        // Then skip the top frames originating from testharness.js to begin the stack at the test code.
        while (re.test(lines[i]) && i < lines.length) {
            i++;
        }

        // Paranoid check that we didn't skip all frames.  If so, return the original stack unmodified.
        if (i >= lines.length) {
            return stack;
        }

        return lines.slice(i).join("\n");
    }

    function OptionalFeatureUnsupportedError(message)
    {
        AssertionError.call(this, message);
    }
    OptionalFeatureUnsupportedError.prototype = Object.create(AssertionError.prototype);
    expose(OptionalFeatureUnsupportedError, "OptionalFeatureUnsupportedError");

    function make_message(function_name, description, error, substitutions)
    {
        for (var p in substitutions) {
            if (substitutions.hasOwnProperty(p)) {
                substitutions[p] = format_value(substitutions[p]);
            }
        }
        var node_form = substitute(["{text}", "${function_name}: ${description}" + error],
                                   merge({function_name:function_name,
                                          description:(description?description + " ":"")},
                                          substitutions));
        return node_form.slice(1).join("");
    }

    function filter(array, callable, thisObj) {
        var rv = [];
        for (var i = 0; i < array.length; i++) {
            if (array.hasOwnProperty(i)) {
                var pass = callable.call(thisObj, array[i], i, array);
                if (pass) {
                    rv.push(array[i]);
                }
            }
        }
        return rv;
    }

    function map(array, callable, thisObj)
    {
        var rv = [];
        rv.length = array.length;
        for (var i = 0; i < array.length; i++) {
            if (array.hasOwnProperty(i)) {
                rv[i] = callable.call(thisObj, array[i], i, array);
            }
        }
        return rv;
    }

    function extend(array, items)
    {
        Array.prototype.push.apply(array, items);
    }

    function forEach(array, callback, thisObj)
    {
        for (var i = 0; i < array.length; i++) {
            if (array.hasOwnProperty(i)) {
                callback.call(thisObj, array[i], i, array);
            }
        }
    }

    /**
     * Immediately invoke a "iteratee" function with a series of values in
     * parallel and invoke a final "done" function when all of the "iteratee"
     * invocations have signaled completion.
     *
     * If all callbacks complete synchronously (or if no callbacks are
     * specified), the `done_callback` will be invoked synchronously. It is the
     * responsibility of the caller to ensure asynchronicity in cases where
     * that is desired.
     *
     * @param {array} value Zero or more values to use in the invocation of
     *                      `iter_callback`
     * @param {function} iter_callback A function that will be invoked once for
     *                                 each of the provided `values`. Two
     *                                 arguments will be available in each
     *                                 invocation: the value from `values` and
     *                                 a function that must be invoked to
     *                                 signal completion
     * @param {function} done_callback A function that will be invoked after
     *                                 all operations initiated by the
     *                                 `iter_callback` function have signaled
     *                                 completion
     */
    function all_async(values, iter_callback, done_callback)
    {
        var remaining = values.length;

        if (remaining === 0) {
            done_callback();
        }

        forEach(values,
                function(element) {
                    var invoked = false;
                    var elDone = function() {
                        if (invoked) {
                            return;
                        }

                        invoked = true;
                        remaining -= 1;

                        if (remaining === 0) {
                            done_callback();
                        }
                    };

                    iter_callback(element, elDone);
                });
    }

    function merge(a,b)
    {
        var rv = {};
        var p;
        for (p in a) {
            rv[p] = a[p];
        }
        for (p in b) {
            rv[p] = b[p];
        }
        return rv;
    }

    function expose(object, name)
    {
        var components = name.split(".");
        var target = global_scope;
        for (var i = 0; i < components.length - 1; i++) {
            if (!(components[i] in target)) {
                target[components[i]] = {};
            }
            target = target[components[i]];
        }
        target[components[components.length - 1]] = object;
    }

    function is_same_origin(w) {
        try {
            'random_prop' in w;
            return true;
        } catch (e) {
            return false;
        }
    }

    /** Returns the 'src' URL of the first <script> tag in the page to include the file 'testharness.js'. */
    function get_script_url()
    {
        if (!('document' in global_scope)) {
            return undefined;
        }

        var scripts = document.getElementsByTagName("script");
        for (var i = 0; i < scripts.length; i++) {
            var src;
            if (scripts[i].src) {
                src = scripts[i].src;
            } else if (scripts[i].href) {
                //SVG case
                src = scripts[i].href.baseVal;
            }

            var matches = src && src.match(/^(.*\/|)testharness\.js$/);
            if (matches) {
                return src;
            }
        }
        return undefined;
    }

    /** Returns the <title> or filename or "Untitled" */
    function get_title()
    {
        if ('document' in global_scope) {
            //Don't use document.title to work around an Opera/Presto bug in XHTML documents
            var title = document.getElementsByTagName("title")[0];
            if (title && title.firstChild && title.firstChild.data) {
                return title.firstChild.data;
            }
        }
        if ('META_TITLE' in global_scope && META_TITLE) {
            return META_TITLE;
        }
        if ('location' in global_scope) {
            return location.pathname.substring(location.pathname.lastIndexOf('/') + 1, location.pathname.indexOf('.'));
        }
        return "Untitled";
    }

    function supports_post_message(w)
    {
        var supports;
        var type;
        // Given IE implements postMessage across nested iframes but not across
        // windows or tabs, you can't infer cross-origin communication from the presence
        // of postMessage on the current window object only.
        //
        // Touching the postMessage prop on a window can throw if the window is
        // not from the same origin AND post message is not supported in that
        // browser. So just doing an existence test here won't do, you also need
        // to wrap it in a try..catch block.
        try {
            type = typeof w.postMessage;
            if (type === "function") {
                supports = true;
            }

            // IE8 supports postMessage, but implements it as a host object which
            // returns "object" as its `typeof`.
            else if (type === "object") {
                supports = true;
            }

            // This is the case where postMessage isn't supported AND accessing a
            // window property across origins does NOT throw (e.g. old Safari browser).
            else {
                supports = false;
            }
        } catch (e) {
            // This is the case where postMessage isn't supported AND accessing a
            // window property across origins throws (e.g. old Firefox browser).
            supports = false;
        }
        return supports;
    }

    /**
     * Setup globals
     */

    var tests = new Tests();

    if (global_scope.addEventListener) {
        var error_handler = function(error, message, stack) {
            var optional_unsupported = error instanceof OptionalFeatureUnsupportedError;
            if (tests.file_is_test) {
                var test = tests.tests[0];
                if (test.phase >= test.phases.HAS_RESULT) {
                    return;
                }
                var status = optional_unsupported ? test.PRECONDITION_FAILED : test.FAIL;
                test.set_status(status, message, stack);
                test.phase = test.phases.HAS_RESULT;
            } else if (!tests.allow_uncaught_exception) {
                var status = optional_unsupported ? tests.status.PRECONDITION_FAILED : tests.status.ERROR;
                tests.status.status = status;
                tests.status.message = message;
                tests.status.stack = stack;
            }

            // Do not transition to the "complete" phase if the test has been
            // configured to allow uncaught exceptions. This gives the test an
            // opportunity to define subtests based on the exception reporting
            // behavior.
            if (!tests.allow_uncaught_exception) {
                done();
            }
        };

        addEventListener("error", function(e) {
            var message = e.message;
            var stack;
            if (e.error && e.error.stack) {
                stack = e.error.stack;
            } else {
                stack = e.filename + ":" + e.lineno + ":" + e.colno;
            }
            error_handler(e.error, message, stack);
        }, false);

        addEventListener("unhandledrejection", function(e) {
            var message;
            if (e.reason && e.reason.message) {
                message = "Unhandled rejection: " + e.reason.message;
            } else {
                message = "Unhandled rejection";
            }
            var stack;
            if (e.reason && e.reason.stack) {
                stack = e.reason.stack;
            }
            error_handler(e.reason, message, stack);
        }, false);
    }

    test_environment.on_tests_ready();

    /**
     * Stylesheet
     */
     var stylesheetContent = "\
html {\
    font-family:DejaVu Sans, Bitstream Vera Sans, Arial, Sans;\
}\
\
#log .warning,\
#log .warning a {\
  color: black;\
  background: yellow;\
}\
\
#log .error,\
#log .error a {\
  color: white;\
  background: red;\
}\
\
section#summary {\
    margin-bottom:1em;\
}\
\
table#results {\
    border-collapse:collapse;\
    table-layout:fixed;\
    width:100%;\
}\
\
table#results th:first-child,\
table#results td:first-child {\
    width:8em;\
}\
\
table#results th:last-child,\
table#results td:last-child {\
    width:50%;\
}\
\
table#results.assertions th:last-child,\
table#results.assertions td:last-child {\
    width:35%;\
}\
\
table#results th {\
    padding:0;\
    padding-bottom:0.5em;\
    border-bottom:medium solid black;\
}\
\
table#results td {\
    padding:1em;\
    padding-bottom:0.5em;\
    border-bottom:thin solid black;\
}\
\
tr.pass > td:first-child {\
    color:green;\
}\
\
tr.fail > td:first-child {\
    color:red;\
}\
\
tr.timeout > td:first-child {\
    color:red;\
}\
\
tr.notrun > td:first-child {\
    color:blue;\
}\
\
tr.optionalunsupported > td:first-child {\
    color:blue;\
}\
\
.pass > td:first-child, .fail > td:first-child, .timeout > td:first-child, .notrun > td:first-child, .optionalunsupported > td:first-child {\
    font-variant:small-caps;\
}\
\
table#results span {\
    display:block;\
}\
\
table#results span.expected {\
    font-family:DejaVu Sans Mono, Bitstream Vera Sans Mono, Monospace;\
    white-space:pre;\
}\
\
table#results span.actual {\
    font-family:DejaVu Sans Mono, Bitstream Vera Sans Mono, Monospace;\
    white-space:pre;\
}\
\
span.ok {\
    color:green;\
}\
\
tr.error {\
    color:red;\
}\
\
span.timeout {\
    color:red;\
}\
\
span.ok, span.timeout, span.error {\
    font-variant:small-caps;\
}\
";

})(self);
// vim: set expandtab shiftwidth=4 tabstop=4:
