Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: LayoutTests/http/tests/w3c/resources/testharness.js

Issue 1209033011: Pull in the latest upstream testharness.js changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@bluetooth-temp
Patch Set: Rebase Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /*global self*/ 1 /*global self*/
2 /*jshint latedef: nofunc*/ 2 /*jshint latedef: nofunc*/
3 /* 3 /*
4 Distributed under both the W3C Test Suite License [1] and the W3C 4 Distributed under both the W3C Test Suite License [1] and the W3C
5 3-clause BSD License [2]. To contribute to a W3C Test Suite, see the 5 3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
6 policies and contribution forms [3]. 6 policies and contribution forms [3].
7 7
8 [1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license 8 [1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
9 [2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license 9 [2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
10 [3] http://www.w3.org/2004/10/27-testcases 10 [3] http://www.w3.org/2004/10/27-testcases
11 */ 11 */
12 12
13 /* Documentation is in docs/api.md */ 13 /* Documentation is in docs/api.md */
14 14
15 (function () 15 (function ()
16 { 16 {
17 var debug = false; 17 var debug = false;
18 // default timeout is 10 seconds, test can override if needed 18 // default timeout is 10 seconds, test can override if needed
19 var settings = { 19 var settings = {
20 output:true, 20 output:true,
21 harness_timeout:{ 21 harness_timeout:{
22 "normal":10000, 22 "normal":10000,
23 "long":60000 23 "long":60000
24 }, 24 },
25 test_timeout:null 25 test_timeout:null,
26 message_events: ["start", "test_state", "result", "completion"]
26 }; 27 };
27 28
28 var xhtml_ns = "http://www.w3.org/1999/xhtml"; 29 var xhtml_ns = "http://www.w3.org/1999/xhtml";
29 30
30 /* 31 /*
31 * TestEnvironment is an abstraction for the environment in which the test 32 * TestEnvironment is an abstraction for the environment in which the test
32 * harness is used. Each implementation of a test environment has to provide 33 * harness is used. Each implementation of a test environment has to provide
33 * the following interface: 34 * the following interface:
34 * 35 *
35 * interface TestEnvironment { 36 * interface TestEnvironment {
(...skipping 21 matching lines...) Expand all
57 * test results are displayed in a table. Any parent windows receive 58 * test results are displayed in a table. Any parent windows receive
58 * callbacks or messages via postMessage() when test events occur. See 59 * callbacks or messages via postMessage() when test events occur. See
59 * apisample11.html and apisample12.html. 60 * apisample11.html and apisample12.html.
60 */ 61 */
61 function WindowTestEnvironment() { 62 function WindowTestEnvironment() {
62 this.name_counter = 0; 63 this.name_counter = 0;
63 this.window_cache = null; 64 this.window_cache = null;
64 this.output_handler = null; 65 this.output_handler = null;
65 this.all_loaded = false; 66 this.all_loaded = false;
66 var this_obj = this; 67 var this_obj = this;
68 this.message_events = [];
69
70 this.message_functions = {
71 start: [add_start_callback, remove_start_callback,
72 function (properties) {
73 this_obj._dispatch("start_callback", [properties],
74 {type: "start", properties: propertie s});
75 }],
76
77 test_state: [add_test_state_callback, remove_test_state_callback,
78 function(test) {
79 this_obj._dispatch("test_state_callback", [test],
80 {type: "test_state",
81 test: test.structured_clone()}) ;
82 }],
83 result: [add_result_callback, remove_result_callback,
84 function (test) {
85 this_obj.output_handler.show_status();
86 this_obj._dispatch("result_callback", [test],
87 {type: "result",
88 test: test.structured_clone()});
89 }],
90 completion: [add_completion_callback, remove_completion_callback,
91 function (tests, harness_status) {
92 var cloned_tests = map(tests, function(test) {
93 return test.structured_clone();
94 });
95 this_obj._dispatch("completion_callback", [tests, h arness_status],
96 {type: "complete",
97 tests: cloned_tests,
98 status: harness_status.structur ed_clone()});
99 }]
100 }
101
67 on_event(window, 'load', function() { 102 on_event(window, 'load', function() {
68 this_obj.all_loaded = true; 103 this_obj.all_loaded = true;
69 }); 104 });
70 } 105 }
71 106
72 WindowTestEnvironment.prototype._dispatch = function(selector, callback_args , message_arg) { 107 WindowTestEnvironment.prototype._dispatch = function(selector, callback_args , message_arg) {
73 this._forEach_windows( 108 this._forEach_windows(
74 function(w, same_origin) { 109 function(w, same_origin) {
75 if (same_origin) { 110 if (same_origin) {
76 try { 111 try {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 function(a) { 178 function(a) {
144 callback.apply(null, a); 179 callback.apply(null, a);
145 }); 180 });
146 }; 181 };
147 182
148 WindowTestEnvironment.prototype.on_tests_ready = function() { 183 WindowTestEnvironment.prototype.on_tests_ready = function() {
149 var output = new Output(); 184 var output = new Output();
150 this.output_handler = output; 185 this.output_handler = output;
151 186
152 var this_obj = this; 187 var this_obj = this;
188
153 add_start_callback(function (properties) { 189 add_start_callback(function (properties) {
154 this_obj.output_handler.init(properties); 190 this_obj.output_handler.init(properties);
155 this_obj._dispatch("start_callback", [properties],
156 { type: "start", properties: properties });
157 }); 191 });
192
158 add_test_state_callback(function(test) { 193 add_test_state_callback(function(test) {
159 this_obj.output_handler.show_status(); 194 this_obj.output_handler.show_status();
160 this_obj._dispatch("test_state_callback", [test],
161 { type: "test_state", test: test.structured_clone () });
162 }); 195 });
196
163 add_result_callback(function (test) { 197 add_result_callback(function (test) {
164 this_obj.output_handler.show_status(); 198 this_obj.output_handler.show_status();
165 this_obj._dispatch("result_callback", [test],
166 { type: "result", test: test.structured_clone() } );
167 }); 199 });
200
168 add_completion_callback(function (tests, harness_status) { 201 add_completion_callback(function (tests, harness_status) {
169 this_obj.output_handler.show_results(tests, harness_status); 202 this_obj.output_handler.show_results(tests, harness_status);
170 var cloned_tests = map(tests, function(test) { return test.structure d_clone(); });
171 this_obj._dispatch("completion_callback", [tests, harness_status],
172 { type: "complete", tests: cloned_tests,
173 status: harness_status.structured_clone() });
174 }); 203 });
204 this.setup_messages(settings.message_events);
175 }; 205 };
176 206
207 WindowTestEnvironment.prototype.setup_messages = function(new_events) {
208 var this_obj = this;
209 forEach(settings.message_events, function(x) {
210 var current_dispatch = this_obj.message_events.indexOf(x) !== -1;
211 var new_dispatch = new_events.indexOf(x) !== -1;
212 if (!current_dispatch && new_dispatch) {
213 this_obj.message_functions[x][0](this_obj.message_functions[x][2 ]);
214 } else if (current_dispatch && !new_dispatch) {
215 this_obj.message_functions[x][1](this_obj.message_functions[x][2 ]);
216 }
217 });
218 this.message_events = new_events;
219 }
220
177 WindowTestEnvironment.prototype.next_default_test_name = function() { 221 WindowTestEnvironment.prototype.next_default_test_name = function() {
178 //Don't use document.title to work around an Opera bug in XHTML document s 222 //Don't use document.title to work around an Opera bug in XHTML document s
179 var title = document.getElementsByTagName("title")[0]; 223 var title = document.getElementsByTagName("title")[0];
180 var prefix = (title && title.firstChild && title.firstChild.data) || "Un titled"; 224 var prefix = (title && title.firstChild && title.firstChild.data) || "Un titled";
181 var suffix = this.name_counter > 0 ? " " + this.name_counter : ""; 225 var suffix = this.name_counter > 0 ? " " + this.name_counter : "";
182 this.name_counter++; 226 this.name_counter++;
183 return prefix + suffix; 227 return prefix + suffix;
184 }; 228 };
185 229
186 WindowTestEnvironment.prototype.on_new_harness_properties = function(propert ies) { 230 WindowTestEnvironment.prototype.on_new_harness_properties = function(propert ies) {
187 this.output_handler.setup(properties); 231 this.output_handler.setup(properties);
232 if (properties.hasOwnProperty("message_events")) {
233 this.setup_messages(properties.message_events);
234 }
188 }; 235 };
189 236
190 WindowTestEnvironment.prototype.add_on_loaded_callback = function(callback) { 237 WindowTestEnvironment.prototype.add_on_loaded_callback = function(callback) {
191 on_event(window, 'load', callback); 238 on_event(window, 'load', callback);
192 }; 239 };
193 240
194 WindowTestEnvironment.prototype.test_timeout = function() { 241 WindowTestEnvironment.prototype.test_timeout = function() {
195 var metas = document.getElementsByTagName("meta"); 242 var metas = document.getElementsByTagName("meta");
196 for (var i = 0; i < metas.length; i++) { 243 for (var i = 0; i < metas.length; i++) {
197 if (metas[i].name == "timeout") { 244 if (metas[i].name == "timeout") {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 * inside a service worker. 408 * inside a service worker.
362 */ 409 */
363 function ServiceWorkerTestEnvironment() { 410 function ServiceWorkerTestEnvironment() {
364 WorkerTestEnvironment.call(this); 411 WorkerTestEnvironment.call(this);
365 this.all_loaded = false; 412 this.all_loaded = false;
366 this.on_loaded_callback = null; 413 this.on_loaded_callback = null;
367 var this_obj = this; 414 var this_obj = this;
368 self.addEventListener("message", 415 self.addEventListener("message",
369 function(event) { 416 function(event) {
370 if (event.data.type && event.data.type === "connect") { 417 if (event.data.type && event.data.type === "connect") {
371 this_obj._add_message_port(event.ports[0]); 418 if (event.ports && event.ports[0]) {
372 event.ports[0].start(); 419 // If a MessageChannel was passed, then use it to
420 // send results back to the main window. This
421 // allows the tests to work even if the browser
422 // does not fully support MessageEvent.source in
423 // ServiceWorkers yet.
424 this_obj._add_message_port(event.ports[0]);
425 event.ports[0].start();
426 } else {
427 // If there is no MessageChannel, then attempt to
428 // use the MessageEvent.source to send results
429 // back to the main window.
430 this_obj._add_message_port(event.source);
431 }
373 } 432 }
374 }); 433 });
375 434
376 // The oninstall event is received after the service worker script and 435 // The oninstall event is received after the service worker script and
377 // all imported scripts have been fetched and executed. It's the 436 // all imported scripts have been fetched and executed. It's the
378 // equivalent of an onload event for a document. All tests should have 437 // equivalent of an onload event for a document. All tests should have
379 // been added by the time this event is received, thus it's not 438 // been added by the time this event is received, thus it's not
380 // necessary to wait until the onactivate event. 439 // necessary to wait until the onactivate event.
381 on_event(self, "install", 440 on_event(self, "install",
382 function(event) { 441 function(event) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 properties = properties ? properties : {}; 510 properties = properties ? properties : {};
452 var test_obj = new Test(test_name, properties); 511 var test_obj = new Test(test_name, properties);
453 if (func) { 512 if (func) {
454 test_obj.step(func, test_obj, test_obj); 513 test_obj.step(func, test_obj, test_obj);
455 } 514 }
456 return test_obj; 515 return test_obj;
457 } 516 }
458 517
459 function promise_test(func, name, properties) { 518 function promise_test(func, name, properties) {
460 var test = async_test(name, properties); 519 var test = async_test(name, properties);
461 Promise.resolve(test.step(func, test, test)) 520 // If there is no promise tests queue make one.
462 .then( 521 test.step(function() {
463 function() { 522 if (!tests.promise_tests) {
464 test.done(); 523 tests.promise_tests = Promise.resolve();
465 }) 524 }
466 .catch(test.step_func( 525 });
467 function(value) { 526 tests.promise_tests = tests.promise_tests.then(function() {
468 if (value instanceof AssertionError) { 527 return Promise.resolve(test.step(func, test, test))
469 throw value; 528 .then(
470 } 529 function() {
471 assert(false, "promise_test", null, 530 test.done();
472 "Unhandled rejection with value: ${value}", {value:va lue}); 531 })
473 })); 532 .catch(test.step_func(
533 function(value) {
534 if (value instanceof AssertionError) {
535 throw value;
536 }
537 assert(false, "promise_test", null,
538 "Unhandled rejection with value: ${value}", {valu e:value});
539 }));
540 });
474 } 541 }
475 542
476 function promise_rejects(test, expected, promise) { 543 function promise_rejects(test, expected, promise) {
477 return promise.then(test.unreached_func("Should have rejected.")).catch( function(e) { 544 return promise.then(test.unreached_func("Should have rejected.")).catch( function(e) {
478 assert_throws(expected, function() { throw e }); 545 assert_throws(expected, function() { throw e });
479 }); 546 });
480 } 547 }
481 548
482 /** 549 /**
483 * This constructor helper allows DOM events to be handled using Promises, 550 * This constructor helper allows DOM events to be handled using Promises,
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 }); 1496 });
1430 this.index = null; 1497 this.index = null;
1431 this.phase = this.phases.INITIAL; 1498 this.phase = this.phases.INITIAL;
1432 this.update_state_from(clone); 1499 this.update_state_from(clone);
1433 tests.push(this); 1500 tests.push(this);
1434 } 1501 }
1435 1502
1436 RemoteTest.prototype.structured_clone = function() { 1503 RemoteTest.prototype.structured_clone = function() {
1437 var clone = {}; 1504 var clone = {};
1438 Object.keys(this).forEach( 1505 Object.keys(this).forEach(
1439 function(key) { 1506 (function(key) {
1440 if (typeof(this[key]) === "object") { 1507 if (typeof(this[key]) === "object") {
1441 clone[key] = merge({}, this[key]); 1508 clone[key] = merge({}, this[key]);
1442 } else { 1509 } else {
1443 clone[key] = this[key]; 1510 clone[key] = this[key];
1444 } 1511 }
1445 }); 1512 }).bind(this));
1446 clone.phases = merge({}, this.phases); 1513 clone.phases = merge({}, this.phases);
1447 return clone; 1514 return clone;
1448 }; 1515 };
1449 1516
1450 RemoteTest.prototype.cleanup = function() {}; 1517 RemoteTest.prototype.cleanup = function() {};
1451 RemoteTest.prototype.phases = Test.prototype.phases; 1518 RemoteTest.prototype.phases = Test.prototype.phases;
1452 RemoteTest.prototype.update_state_from = function(clone) { 1519 RemoteTest.prototype.update_state_from = function(clone) {
1453 this.status = clone.status; 1520 this.status = clone.status;
1454 this.message = clone.message; 1521 this.message = clone.message;
1455 this.stack = clone.stack; 1522 this.stack = clone.stack;
(...skipping 13 matching lines...) Expand all
1469 function RemoteWorker(worker) { 1536 function RemoteWorker(worker) {
1470 this.running = true; 1537 this.running = true;
1471 this.tests = new Array(); 1538 this.tests = new Array();
1472 1539
1473 var this_obj = this; 1540 var this_obj = this;
1474 worker.onerror = function(error) { this_obj.worker_error(error); }; 1541 worker.onerror = function(error) { this_obj.worker_error(error); };
1475 1542
1476 var message_port; 1543 var message_port;
1477 1544
1478 if (is_service_worker(worker)) { 1545 if (is_service_worker(worker)) {
1479 // The ServiceWorker's implicit MessagePort is currently not 1546 if (window.MessageChannel) {
1480 // reliably accessible from the ServiceWorkerGlobalScope due to 1547 // The ServiceWorker's implicit MessagePort is currently not
1481 // Blink setting MessageEvent.source to null for messages sent via 1548 // reliably accessible from the ServiceWorkerGlobalScope due to
1482 // ServiceWorker.postMessage(). Until that's resolved, create an 1549 // Blink setting MessageEvent.source to null for messages sent
1483 // explicit MessageChannel and pass one end to the worker. 1550 // via ServiceWorker.postMessage(). Until that's resolved,
1484 var message_channel = new MessageChannel(); 1551 // create an explicit MessageChannel and pass one end to the
1485 message_port = message_channel.port1; 1552 // worker.
1486 message_port.start(); 1553 var message_channel = new MessageChannel();
1487 worker.postMessage({type: "connect"}, [message_channel.port2]); 1554 message_port = message_channel.port1;
1555 message_port.start();
1556 worker.postMessage({type: "connect"}, [message_channel.port2]);
1557 } else {
1558 // If MessageChannel is not available, then try the
1559 // ServiceWorker.postMessage() approach using MessageEvent.sourc e
1560 // on the other end.
1561 message_port = navigator.serviceWorker;
1562 worker.postMessage({type: "connect"});
1563 }
1488 } else if (is_shared_worker(worker)) { 1564 } else if (is_shared_worker(worker)) {
1489 message_port = worker.port; 1565 message_port = worker.port;
1490 } else { 1566 } else {
1491 message_port = worker; 1567 message_port = worker;
1492 } 1568 }
1493 1569
1494 // Keeping a reference to the worker until worker_done() is seen 1570 // Keeping a reference to the worker until worker_done() is seen
1495 // prevents the Worker object and its MessageChannel from going away 1571 // prevents the Worker object and its MessageChannel from going away
1496 // before all the messages are dispatched. 1572 // before all the messages are dispatched.
1497 this.worker = worker; 1573 this.worker = worker;
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 expose(timeout, 'timeout'); 1906 expose(timeout, 'timeout');
1831 1907
1832 function add_start_callback(callback) { 1908 function add_start_callback(callback) {
1833 tests.start_callbacks.push(callback); 1909 tests.start_callbacks.push(callback);
1834 } 1910 }
1835 1911
1836 function add_test_state_callback(callback) { 1912 function add_test_state_callback(callback) {
1837 tests.test_state_callbacks.push(callback); 1913 tests.test_state_callbacks.push(callback);
1838 } 1914 }
1839 1915
1840 function add_result_callback(callback) 1916 function add_result_callback(callback) {
1841 {
1842 tests.test_done_callbacks.push(callback); 1917 tests.test_done_callbacks.push(callback);
1843 } 1918 }
1844 1919
1845 function add_completion_callback(callback) 1920 function add_completion_callback(callback) {
1846 { 1921 tests.all_done_callbacks.push(callback);
1847 tests.all_done_callbacks.push(callback);
1848 } 1922 }
1849 1923
1850 expose(add_start_callback, 'add_start_callback'); 1924 expose(add_start_callback, 'add_start_callback');
1851 expose(add_test_state_callback, 'add_test_state_callback'); 1925 expose(add_test_state_callback, 'add_test_state_callback');
1852 expose(add_result_callback, 'add_result_callback'); 1926 expose(add_result_callback, 'add_result_callback');
1853 expose(add_completion_callback, 'add_completion_callback'); 1927 expose(add_completion_callback, 'add_completion_callback');
1854 1928
1929 function remove(array, item) {
1930 var index = array.indexOf(item);
1931 if (index > -1) {
1932 array.splice(index, 1);
1933 }
1934 }
1935
1936 function remove_start_callback(callback) {
1937 remove(tests.start_callbacks, callback);
1938 }
1939
1940 function remove_test_state_callback(callback) {
1941 remove(tests.test_state_callbacks, callback);
1942 }
1943
1944 function remove_result_callback(callback) {
1945 remove(tests.test_done_callbacks, callback);
1946 }
1947
1948 function remove_completion_callback(callback) {
1949 remove(tests.all_done_callbacks, callback);
1950 }
1951
1855 /* 1952 /*
1856 * Output listener 1953 * Output listener
1857 */ 1954 */
1858 1955
1859 function Output() { 1956 function Output() {
1860 this.output_document = document; 1957 this.output_document = document;
1861 this.output_node = null; 1958 this.output_node = null;
1862 this.enabled = settings.output; 1959 this.enabled = settings.output;
1863 this.phase = this.INITIAL; 1960 this.phase = this.INITIAL;
1864 } 1961 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 var log = this.output_node; 2049 var log = this.output_node;
1953 if (!log) { 2050 if (!log) {
1954 return; 2051 return;
1955 } 2052 }
1956 var output_document = this.output_document; 2053 var output_document = this.output_document;
1957 2054
1958 while (log.lastChild) { 2055 while (log.lastChild) {
1959 log.removeChild(log.lastChild); 2056 log.removeChild(log.lastChild);
1960 } 2057 }
1961 2058
1962 var script_prefix = null; 2059 var harness_url = get_harness_url();
1963 var scripts = document.getElementsByTagName("script"); 2060 if (harness_url !== null) {
1964 for (var i = 0; i < scripts.length; i++) {
1965 var src;
1966 if (scripts[i].src) {
1967 src = scripts[i].src;
1968 } else if (scripts[i].href) {
1969 //SVG case
1970 src = scripts[i].href.baseVal;
1971 }
1972
1973 var matches = src && src.match(/^(.*\/|)testharness\.js$/);
1974 if (matches) {
1975 script_prefix = matches[1];
1976 break;
1977 }
1978 }
1979
1980 if (script_prefix !== null) {
1981 var stylesheet = output_document.createElementNS(xhtml_ns, "link"); 2061 var stylesheet = output_document.createElementNS(xhtml_ns, "link");
1982 stylesheet.setAttribute("rel", "stylesheet"); 2062 stylesheet.setAttribute("rel", "stylesheet");
1983 stylesheet.setAttribute("href", script_prefix + "testharness.css"); 2063 stylesheet.setAttribute("href", harness_url + "testharness.css");
1984 var heads = output_document.getElementsByTagName("head"); 2064 var heads = output_document.getElementsByTagName("head");
1985 if (heads.length) { 2065 if (heads.length) {
1986 heads[0].appendChild(stylesheet); 2066 heads[0].appendChild(stylesheet);
1987 } 2067 }
1988 } 2068 }
1989 2069
1990 var status_text_harness = {}; 2070 var status_text_harness = {};
1991 status_text_harness[harness_status.OK] = "OK"; 2071 status_text_harness[harness_status.OK] = "OK";
1992 status_text_harness[harness_status.ERROR] = "Error"; 2072 status_text_harness[harness_status.ERROR] = "Error";
1993 status_text_harness[harness_status.TIMEOUT] = "Timeout"; 2073 status_text_harness[harness_status.TIMEOUT] = "Timeout";
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 2408
2329 function AssertionError(message) 2409 function AssertionError(message)
2330 { 2410 {
2331 this.message = message; 2411 this.message = message;
2332 this.stack = this.get_stack(); 2412 this.stack = this.get_stack();
2333 } 2413 }
2334 2414
2335 AssertionError.prototype = Object.create(Error.prototype); 2415 AssertionError.prototype = Object.create(Error.prototype);
2336 2416
2337 AssertionError.prototype.get_stack = function() { 2417 AssertionError.prototype.get_stack = function() {
2338 var lines = new Error().stack.split("\n"); 2418 var stack = new Error().stack;
2339 var rv = []; 2419 // IE11 does not initialize 'Error.stack' until the object is thrown.
2340 var re = /\/resources\/testharness\.js/; 2420 if (!stack) {
2421 try {
2422 throw new Error();
2423 } catch (e) {
2424 stack = e.stack;
2425 }
2426 }
2427
2428 var lines = stack.split("\n");
2429
2430 // Create a pattern to match stack frames originating within testharness .js. These include the
2431 // script URL, followed by the line/col (e.g., '/resources/testharness.j s:120:21').
2432 var re = new RegExp((get_script_url() || "\\btestharness.js") + ":\\d+:\ \d+");
2433
2434 // Some browsers include a preamble that specifies the type of the error object. Skip this by
2435 // advancing until we find the first stack frame originating from testha rness.js.
2341 var i = 0; 2436 var i = 0;
2342 // Fire remove any preamble that doesn't match the regexp 2437 while (!re.test(lines[i]) && i < lines.length) {
2343 while (!re.test(lines[i])) { 2438 i++;
2344 i++
2345 } 2439 }
2346 // Then remove top frames in testharness.js itself 2440
2347 while (re.test(lines[i])) { 2441 // Then skip the top frames originating from testharness.js to begin the stack at the test code.
2348 i++ 2442 while (re.test(lines[i]) && i < lines.length) {
2443 i++;
2349 } 2444 }
2445
2446 // Paranoid check that we didn't skip all frames. If so, return the ori ginal stack unmodified.
2447 if (i >= lines.length) {
2448 return stack;
2449 }
2450
2350 return lines.slice(i).join("\n"); 2451 return lines.slice(i).join("\n");
2351 } 2452 }
2352 2453
2353 function make_message(function_name, description, error, substitutions) 2454 function make_message(function_name, description, error, substitutions)
2354 { 2455 {
2355 for (var p in substitutions) { 2456 for (var p in substitutions) {
2356 if (substitutions.hasOwnProperty(p)) { 2457 if (substitutions.hasOwnProperty(p)) {
2357 substitutions[p] = format_value(substitutions[p]); 2458 substitutions[p] = format_value(substitutions[p]);
2358 } 2459 }
2359 } 2460 }
(...skipping 27 matching lines...) Expand all
2387 } 2488 }
2388 } 2489 }
2389 return rv; 2490 return rv;
2390 } 2491 }
2391 2492
2392 function extend(array, items) 2493 function extend(array, items)
2393 { 2494 {
2394 Array.prototype.push.apply(array, items); 2495 Array.prototype.push.apply(array, items);
2395 } 2496 }
2396 2497
2397 function forEach (array, callback, thisObj) 2498 function forEach(array, callback, thisObj)
2398 { 2499 {
2399 for (var i = 0; i < array.length; i++) { 2500 for (var i = 0; i < array.length; i++) {
2400 if (array.hasOwnProperty(i)) { 2501 if (array.hasOwnProperty(i)) {
2401 callback.call(thisObj, array[i], i, array); 2502 callback.call(thisObj, array[i], i, array);
2402 } 2503 }
2403 } 2504 }
2404 } 2505 }
2405 2506
2406 function merge(a,b) 2507 function merge(a,b)
2407 { 2508 {
(...skipping 23 matching lines...) Expand all
2431 2532
2432 function is_same_origin(w) { 2533 function is_same_origin(w) {
2433 try { 2534 try {
2434 'random_prop' in w; 2535 'random_prop' in w;
2435 return true; 2536 return true;
2436 } catch (e) { 2537 } catch (e) {
2437 return false; 2538 return false;
2438 } 2539 }
2439 } 2540 }
2440 2541
2542 /** Returns the 'src' URL of the first <script> tag in the page to include t he file 'testharness.js'. */
2543 function get_script_url()
2544 {
2545 if (!('document' in self)) {
2546 return undefined;
2547 }
2548
2549 var scripts = document.getElementsByTagName("script");
2550 for (var i = 0; i < scripts.length; i++) {
2551 var src;
2552 if (scripts[i].src) {
2553 src = scripts[i].src;
2554 } else if (scripts[i].href) {
2555 //SVG case
2556 src = scripts[i].href.baseVal;
2557 }
2558
2559 var matches = src && src.match(/^(.*\/|)testharness\.js$/);
2560 if (matches) {
2561 return src;
2562 }
2563 }
2564 return undefined;
2565 }
2566
2567 /** Returns the URL path at which the files for testharness.js are assumed t o reside (e.g., '/resources/').
2568 The path is derived from inspecting the 'src' of the <script> tag that i ncluded 'testharness.js'. */
2569 function get_harness_url()
2570 {
2571 var script_url = get_script_url();
2572
2573 // Exclude the 'testharness.js' file from the returned path, but '+ 1' t o include the trailing slash.
2574 return script_url ? script_url.slice(0, script_url.lastIndexOf('/') + 1) : undefined;
2575 }
2576
2441 function supports_post_message(w) 2577 function supports_post_message(w)
2442 { 2578 {
2443 var supports; 2579 var supports;
2444 var type; 2580 var type;
2445 // Given IE implements postMessage across nested iframes but not across 2581 // Given IE implements postMessage across nested iframes but not across
2446 // windows or tabs, you can't infer cross-origin communication from the presence 2582 // windows or tabs, you can't infer cross-origin communication from the presence
2447 // of postMessage on the current window object only. 2583 // of postMessage on the current window object only.
2448 // 2584 //
2449 // Touching the postMessage prop on a window can throw if the window is 2585 // Touching the postMessage prop on a window can throw if the window is
2450 // not from the same origin AND post message is not supported in that 2586 // not from the same origin AND post message is not supported in that
2451 // browser. So just doing an existence test here won't do, you also need 2587 // browser. So just doing an existence test here won't do, you also need
2452 // to wrap it in a try..cacth block. 2588 // to wrap it in a try..cacth block.
2453 try { 2589 try {
2454 type = typeof w.postMessage; 2590 type = typeof w.postMessage;
2455 if (type === "function") { 2591 if (type === "function") {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2495 tests.status.status = tests.status.ERROR; 2631 tests.status.status = tests.status.ERROR;
2496 tests.status.message = e.message; 2632 tests.status.message = e.message;
2497 tests.status.stack = e.stack; 2633 tests.status.stack = e.stack;
2498 } 2634 }
2499 }); 2635 });
2500 2636
2501 test_environment.on_tests_ready(); 2637 test_environment.on_tests_ready();
2502 2638
2503 })(); 2639 })();
2504 // vim: set expandtab shiftwidth=4 tabstop=4: 2640 // vim: set expandtab shiftwidth=4 tabstop=4:
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698