js/src/tests/browser.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 var gPageCompleted;
michael@0 7 var GLOBAL = this + '';
michael@0 8
michael@0 9 // Variables local to jstests harness.
michael@0 10 var jstestsTestPassesUnlessItThrows = false;
michael@0 11 var jstestsRestoreFunction;
michael@0 12 var jstestsOptions;
michael@0 13
michael@0 14 /*
michael@0 15 * Signals to this script that the current test case should be considered to
michael@0 16 * have passed if it doesn't throw an exception.
michael@0 17 *
michael@0 18 * Overrides the same-named function in shell.js.
michael@0 19 */
michael@0 20 function testPassesUnlessItThrows() {
michael@0 21 jstestsTestPassesUnlessItThrows = true;
michael@0 22 }
michael@0 23
michael@0 24 /*
michael@0 25 * Requests to load the given JavaScript file before the file containing the
michael@0 26 * test case.
michael@0 27 */
michael@0 28 function include(file) {
michael@0 29 outputscripttag(file, {language: "type", mimetype: "text/javascript"});
michael@0 30 }
michael@0 31
michael@0 32 /*
michael@0 33 * Sets a restore function which restores the standard built-in ECMAScript
michael@0 34 * properties after a destructive test case, and which will be called after
michael@0 35 * the test case terminates.
michael@0 36 */
michael@0 37 function setRestoreFunction(restore) {
michael@0 38 jstestsRestoreFunction = restore;
michael@0 39 }
michael@0 40
michael@0 41 function htmlesc(str) {
michael@0 42 if (str == '<')
michael@0 43 return '&lt;';
michael@0 44 if (str == '>')
michael@0 45 return '&gt;';
michael@0 46 if (str == '&')
michael@0 47 return '&amp;';
michael@0 48 return str;
michael@0 49 }
michael@0 50
michael@0 51 function DocumentWrite(s)
michael@0 52 {
michael@0 53 try
michael@0 54 {
michael@0 55 var msgDiv = document.createElement('div');
michael@0 56 msgDiv.innerHTML = s;
michael@0 57 document.body.appendChild(msgDiv);
michael@0 58 msgDiv = null;
michael@0 59 }
michael@0 60 catch(excp)
michael@0 61 {
michael@0 62 document.write(s + '<br>\n');
michael@0 63 }
michael@0 64 }
michael@0 65
michael@0 66 function print() {
michael@0 67 var s = '';
michael@0 68 var a;
michael@0 69 for (var i = 0; i < arguments.length; i++)
michael@0 70 {
michael@0 71 a = arguments[i];
michael@0 72 s += String(a) + ' ';
michael@0 73 }
michael@0 74
michael@0 75 if (typeof dump == 'function')
michael@0 76 {
michael@0 77 dump( s + '\n');
michael@0 78 }
michael@0 79
michael@0 80 s = s.replace(/[<>&]/g, htmlesc);
michael@0 81
michael@0 82 DocumentWrite(s);
michael@0 83 }
michael@0 84
michael@0 85 function writeHeaderToLog( string ) {
michael@0 86 string = String(string);
michael@0 87
michael@0 88 if (typeof dump == 'function')
michael@0 89 {
michael@0 90 dump( string + '\n');
michael@0 91 }
michael@0 92
michael@0 93 string = string.replace(/[<>&]/g, htmlesc);
michael@0 94
michael@0 95 DocumentWrite( "<h2>" + string + "</h2>" );
michael@0 96 }
michael@0 97
michael@0 98 function writeFormattedResult( expect, actual, string, passed ) {
michael@0 99 string = String(string);
michael@0 100
michael@0 101 if (typeof dump == 'function')
michael@0 102 {
michael@0 103 dump( string + '\n');
michael@0 104 }
michael@0 105
michael@0 106 string = string.replace(/[<>&]/g, htmlesc);
michael@0 107
michael@0 108 var s = "<tt>"+ string ;
michael@0 109 s += "<b>" ;
michael@0 110 s += ( passed ) ? "<font color=#009900> &nbsp;" + PASSED
michael@0 111 : "<font color=#aa0000>&nbsp;" + FAILED + expect;
michael@0 112
michael@0 113 DocumentWrite( s + "</font></b></tt><br>" );
michael@0 114 return passed;
michael@0 115 }
michael@0 116
michael@0 117 window.onerror = function (msg, page, line)
michael@0 118 {
michael@0 119 jstestsTestPassesUnlessItThrows = false;
michael@0 120
michael@0 121 // Restore options in case a test case used this common variable name.
michael@0 122 options = jstestsOptions;
michael@0 123
michael@0 124 // Restore the ECMAScript environment after potentially destructive tests.
michael@0 125 if (typeof jstestsRestoreFunction === "function") {
michael@0 126 jstestsRestoreFunction();
michael@0 127 }
michael@0 128
michael@0 129 optionsPush();
michael@0 130
michael@0 131 if (typeof DESCRIPTION == 'undefined')
michael@0 132 {
michael@0 133 DESCRIPTION = 'Unknown';
michael@0 134 }
michael@0 135 if (typeof EXPECTED == 'undefined')
michael@0 136 {
michael@0 137 EXPECTED = 'Unknown';
michael@0 138 }
michael@0 139
michael@0 140 var testcase = new TestCase("unknown-test-name", DESCRIPTION, EXPECTED, "error");
michael@0 141
michael@0 142 if (document.location.href.indexOf('-n.js') != -1)
michael@0 143 {
michael@0 144 // negative test
michael@0 145 testcase.passed = true;
michael@0 146 }
michael@0 147
michael@0 148 testcase.reason = page + ':' + line + ': ' + msg;
michael@0 149
michael@0 150 reportFailure(msg);
michael@0 151
michael@0 152 optionsReset();
michael@0 153 };
michael@0 154
michael@0 155 function gc()
michael@0 156 {
michael@0 157 try
michael@0 158 {
michael@0 159 SpecialPowers.forceGC();
michael@0 160 }
michael@0 161 catch(ex)
michael@0 162 {
michael@0 163 print('gc: ' + ex);
michael@0 164 }
michael@0 165 }
michael@0 166
michael@0 167 function jsdgc()
michael@0 168 {
michael@0 169 try
michael@0 170 {
michael@0 171 var jsdIDebuggerService = SpecialPowers.Ci.jsdIDebuggerService;
michael@0 172 var service = SpecialPowers.Cc['@mozilla.org/js/jsd/debugger-service;1'].
michael@0 173 getService(jsdIDebuggerService);
michael@0 174 service.GC();
michael@0 175 }
michael@0 176 catch(ex)
michael@0 177 {
michael@0 178 print('jsdgc: ' + ex);
michael@0 179 }
michael@0 180 }
michael@0 181
michael@0 182 function quit()
michael@0 183 {
michael@0 184 }
michael@0 185
michael@0 186 function options(aOptionName)
michael@0 187 {
michael@0 188 // return value of options() is a comma delimited list
michael@0 189 // of the previously set values
michael@0 190
michael@0 191 var value = '';
michael@0 192 for (var optionName in options.currvalues)
michael@0 193 {
michael@0 194 value += optionName + ',';
michael@0 195 }
michael@0 196 if (value)
michael@0 197 {
michael@0 198 value = value.substring(0, value.length-1);
michael@0 199 }
michael@0 200
michael@0 201 if (aOptionName) {
michael@0 202 if (!(aOptionName in SpecialPowers.Cu)) {
michael@0 203 // This test is trying to flip an unsupported option, so it's
michael@0 204 // likely no longer testing what it was supposed to. Fail it
michael@0 205 // hard.
michael@0 206 throw "Unsupported JSContext option '"+ aOptionName +"'";
michael@0 207 }
michael@0 208
michael@0 209 if (options.currvalues.hasOwnProperty(aOptionName))
michael@0 210 // option is set, toggle it to unset
michael@0 211 delete options.currvalues[aOptionName];
michael@0 212 else
michael@0 213 // option is not set, toggle it to set
michael@0 214 options.currvalues[aOptionName] = true;
michael@0 215
michael@0 216 SpecialPowers.Cu[aOptionName] =
michael@0 217 options.currvalues.hasOwnProperty(aOptionName);
michael@0 218 }
michael@0 219
michael@0 220 return value;
michael@0 221 }
michael@0 222
michael@0 223 // Keep a reference to options around so that we can restore it after running
michael@0 224 // a test case, which may have used this common name for one of its own
michael@0 225 // variables.
michael@0 226 jstestsOptions = options;
michael@0 227
michael@0 228 function optionsInit() {
michael@0 229
michael@0 230 // hash containing the set options.
michael@0 231 options.currvalues = {
michael@0 232 strict: true,
michael@0 233 werror: true,
michael@0 234 strict_mode: true
michael@0 235 };
michael@0 236
michael@0 237 // record initial values to support resetting
michael@0 238 // options to their initial values
michael@0 239 options.initvalues = {};
michael@0 240
michael@0 241 // record values in a stack to support pushing
michael@0 242 // and popping options
michael@0 243 options.stackvalues = [];
michael@0 244
michael@0 245 for (var optionName in options.currvalues)
michael@0 246 {
michael@0 247 var propName = optionName;
michael@0 248
michael@0 249 if (!(propName in SpecialPowers.Cu))
michael@0 250 {
michael@0 251 throw "options.currvalues is out of sync with Components.utils";
michael@0 252 }
michael@0 253 if (!SpecialPowers.Cu[propName])
michael@0 254 {
michael@0 255 delete options.currvalues[optionName];
michael@0 256 }
michael@0 257 else
michael@0 258 {
michael@0 259 options.initvalues[optionName] = true;
michael@0 260 }
michael@0 261 }
michael@0 262 }
michael@0 263
michael@0 264 function gczeal(z)
michael@0 265 {
michael@0 266 SpecialPowers.setGCZeal(z);
michael@0 267 }
michael@0 268
michael@0 269 function jit(on)
michael@0 270 {
michael@0 271 }
michael@0 272
michael@0 273 function jsTestDriverBrowserInit()
michael@0 274 {
michael@0 275
michael@0 276 if (typeof dump != 'function')
michael@0 277 {
michael@0 278 dump = print;
michael@0 279 }
michael@0 280
michael@0 281 optionsInit();
michael@0 282 optionsClear();
michael@0 283
michael@0 284 if (document.location.search.indexOf('?') != 0)
michael@0 285 {
michael@0 286 // not called with a query string
michael@0 287 return;
michael@0 288 }
michael@0 289
michael@0 290 var properties = {};
michael@0 291 var fields = document.location.search.slice(1).split(';');
michael@0 292 for (var ifield = 0; ifield < fields.length; ifield++)
michael@0 293 {
michael@0 294 var propertycaptures = /^([^=]+)=(.*)$/.exec(fields[ifield]);
michael@0 295 if (!propertycaptures)
michael@0 296 {
michael@0 297 properties[fields[ifield]] = true;
michael@0 298 }
michael@0 299 else
michael@0 300 {
michael@0 301 properties[propertycaptures[1]] = decodeURIComponent(propertycaptures[2]);
michael@0 302 if (propertycaptures[1] == 'language')
michael@0 303 {
michael@0 304 // language=(type|language);mimetype
michael@0 305 properties.mimetype = fields[ifield+1];
michael@0 306 }
michael@0 307 }
michael@0 308 }
michael@0 309
michael@0 310 if (properties.language != 'type')
michael@0 311 {
michael@0 312 try
michael@0 313 {
michael@0 314 properties.version = /javascript([.0-9]+)/.exec(properties.mimetype)[1];
michael@0 315 }
michael@0 316 catch(ex)
michael@0 317 {
michael@0 318 }
michael@0 319 }
michael@0 320
michael@0 321 if (!properties.version && navigator.userAgent.indexOf('Gecko/') != -1)
michael@0 322 {
michael@0 323 // If the version is not specified, and the browser is Gecko,
michael@0 324 // use the default version corresponding to the shell's version(0).
michael@0 325 // See https://bugzilla.mozilla.org/show_bug.cgi?id=522760#c11
michael@0 326 // Otherwise adjust the version to match the suite version for 1.6,
michael@0 327 // and later due to the use of for-each, let, yield, etc.
michael@0 328 //
michael@0 329 // Note that js1_8, js1_8_1, and js1_8_5 are treated identically in
michael@0 330 // the browser.
michael@0 331 if (properties.test.match(/^js1_6/))
michael@0 332 {
michael@0 333 properties.version = '1.6';
michael@0 334 }
michael@0 335 else if (properties.test.match(/^js1_7/))
michael@0 336 {
michael@0 337 properties.version = '1.7';
michael@0 338 }
michael@0 339 else if (properties.test.match(/^js1_8/))
michael@0 340 {
michael@0 341 properties.version = '1.8';
michael@0 342 }
michael@0 343 }
michael@0 344
michael@0 345 // default to language=type;text/javascript. required for
michael@0 346 // reftest style manifests.
michael@0 347 if (!properties.language)
michael@0 348 {
michael@0 349 properties.language = 'type';
michael@0 350 properties.mimetype = 'text/javascript';
michael@0 351 }
michael@0 352
michael@0 353 gTestPath = properties.test;
michael@0 354
michael@0 355 if (properties.gczeal)
michael@0 356 {
michael@0 357 gczeal(Number(properties.gczeal));
michael@0 358 }
michael@0 359
michael@0 360 /*
michael@0 361 * since the default setting of jit changed from false to true
michael@0 362 * in http://hg.mozilla.org/tracemonkey/rev/685e00e68be9
michael@0 363 * bisections which depend upon jit settings can be thrown off.
michael@0 364 * default jit(false) when not running jsreftests to make bisections
michael@0 365 * depending upon jit settings consistent over time. This is not needed
michael@0 366 * in shell tests as the default jit setting has not changed there.
michael@0 367 */
michael@0 368
michael@0 369 if (properties.jit || !document.location.href.match(/jsreftest.html/))
michael@0 370 jit(properties.jit);
michael@0 371
michael@0 372 var testpathparts = properties.test.split(/\//);
michael@0 373
michael@0 374 if (testpathparts.length < 3)
michael@0 375 {
michael@0 376 // must have at least suitepath/subsuite/testcase.js
michael@0 377 return;
michael@0 378 }
michael@0 379
michael@0 380 document.write('<title>' + properties.test + '<\/title>');
michael@0 381
michael@0 382 // XXX bc - the first document.written script is ignored if the protocol
michael@0 383 // is file:. insert an empty script tag, to work around it.
michael@0 384 document.write('<script></script>');
michael@0 385
michael@0 386 // Output script tags for shell.js, then browser.js, at each level of the
michael@0 387 // test path hierarchy.
michael@0 388 var prepath = "";
michael@0 389 var i = 0;
michael@0 390 for (end = testpathparts.length - 1; i < end; i++) {
michael@0 391 prepath += testpathparts[i] + "/";
michael@0 392 outputscripttag(prepath + "shell.js", properties);
michael@0 393 outputscripttag(prepath + "browser.js", properties);
michael@0 394 }
michael@0 395
michael@0 396 // Output the test script itself.
michael@0 397 outputscripttag(prepath + testpathparts[i], properties);
michael@0 398
michael@0 399 // Finally output the driver-end script to advance to the next test.
michael@0 400 outputscripttag('js-test-driver-end.js', properties);
michael@0 401 return;
michael@0 402 }
michael@0 403
michael@0 404 function outputscripttag(src, properties)
michael@0 405 {
michael@0 406 if (!src)
michael@0 407 {
michael@0 408 return;
michael@0 409 }
michael@0 410
michael@0 411 var s = '<script src="' + src + '" charset="utf-8" ';
michael@0 412
michael@0 413 if (properties.language != 'type')
michael@0 414 {
michael@0 415 s += 'language="javascript';
michael@0 416 if (properties.version)
michael@0 417 {
michael@0 418 s += properties.version;
michael@0 419 }
michael@0 420 }
michael@0 421 else
michael@0 422 {
michael@0 423 s += 'type="' + properties.mimetype;
michael@0 424 if (properties.version)
michael@0 425 {
michael@0 426 s += ';version=' + properties.version;
michael@0 427 }
michael@0 428 }
michael@0 429 s += '"><\/script>';
michael@0 430
michael@0 431 document.write(s);
michael@0 432 }
michael@0 433
michael@0 434 function jsTestDriverEnd()
michael@0 435 {
michael@0 436 // gDelayTestDriverEnd is used to
michael@0 437 // delay collection of the test result and
michael@0 438 // signal to Spider so that tests can continue
michael@0 439 // to run after page load has fired. They are
michael@0 440 // responsible for setting gDelayTestDriverEnd = true
michael@0 441 // then when completed, setting gDelayTestDriverEnd = false
michael@0 442 // then calling jsTestDriverEnd()
michael@0 443
michael@0 444 if (gDelayTestDriverEnd)
michael@0 445 {
michael@0 446 return;
michael@0 447 }
michael@0 448
michael@0 449 window.onerror = null;
michael@0 450
michael@0 451 // Restore options in case a test case used this common variable name.
michael@0 452 options = jstestsOptions;
michael@0 453
michael@0 454 // Restore the ECMAScript environment after potentially destructive tests.
michael@0 455 if (typeof jstestsRestoreFunction === "function") {
michael@0 456 jstestsRestoreFunction();
michael@0 457 }
michael@0 458
michael@0 459 if (jstestsTestPassesUnlessItThrows) {
michael@0 460 var testcase = new TestCase("unknown-test-name", "", true, true);
michael@0 461 print(PASSED);
michael@0 462 jstestsTestPassesUnlessItThrows = false;
michael@0 463 }
michael@0 464
michael@0 465 try
michael@0 466 {
michael@0 467 optionsReset();
michael@0 468 }
michael@0 469 catch(ex)
michael@0 470 {
michael@0 471 dump('jsTestDriverEnd ' + ex);
michael@0 472 }
michael@0 473
michael@0 474 if (window.opener && window.opener.runNextTest)
michael@0 475 {
michael@0 476 if (window.opener.reportCallBack)
michael@0 477 {
michael@0 478 window.opener.reportCallBack(window.opener.gWindow);
michael@0 479 }
michael@0 480 setTimeout('window.opener.runNextTest()', 250);
michael@0 481 }
michael@0 482 else
michael@0 483 {
michael@0 484 for (var i = 0; i < gTestcases.length; i++)
michael@0 485 {
michael@0 486 gTestcases[i].dump();
michael@0 487 }
michael@0 488
michael@0 489 // tell reftest the test is complete.
michael@0 490 document.documentElement.className = '';
michael@0 491 // tell Spider page is complete
michael@0 492 gPageCompleted = true;
michael@0 493 }
michael@0 494 }
michael@0 495
michael@0 496 //var dlog = (function (s) { print('debug: ' + s); });
michael@0 497 var dlog = (function (s) {});
michael@0 498
michael@0 499 // dialog closer from http://bclary.com/projects/spider/spider/chrome/content/spider/dialog-closer.js
michael@0 500
michael@0 501 var gDialogCloser;
michael@0 502 var gDialogCloserObserver;
michael@0 503
michael@0 504 function registerDialogCloser()
michael@0 505 {
michael@0 506 gDialogCloser = SpecialPowers.
michael@0 507 Cc['@mozilla.org/embedcomp/window-watcher;1'].
michael@0 508 getService(SpecialPowers.Ci.nsIWindowWatcher);
michael@0 509
michael@0 510 gDialogCloserObserver = {observe: dialogCloser_observe};
michael@0 511
michael@0 512 gDialogCloser.registerNotification(gDialogCloserObserver);
michael@0 513 }
michael@0 514
michael@0 515 function unregisterDialogCloser()
michael@0 516 {
michael@0 517 gczeal(0);
michael@0 518
michael@0 519 if (!gDialogCloserObserver || !gDialogCloser)
michael@0 520 {
michael@0 521 return;
michael@0 522 }
michael@0 523
michael@0 524 gDialogCloser.unregisterNotification(gDialogCloserObserver);
michael@0 525
michael@0 526 gDialogCloserObserver = null;
michael@0 527 gDialogCloser = null;
michael@0 528 }
michael@0 529
michael@0 530 // use an array to handle the case where multiple dialogs
michael@0 531 // appear at one time
michael@0 532 var gDialogCloserSubjects = [];
michael@0 533
michael@0 534 function dialogCloser_observe(subject, topic, data)
michael@0 535 {
michael@0 536 if (subject instanceof ChromeWindow && topic == 'domwindowopened' )
michael@0 537 {
michael@0 538 gDialogCloserSubjects.push(subject);
michael@0 539 // timeout of 0 needed when running under reftest framework.
michael@0 540 subject.setTimeout(closeDialog, 0);
michael@0 541 }
michael@0 542 }
michael@0 543
michael@0 544 function closeDialog()
michael@0 545 {
michael@0 546 var subject;
michael@0 547
michael@0 548 while ( (subject = gDialogCloserSubjects.pop()) != null)
michael@0 549 {
michael@0 550 if (subject.document instanceof XULDocument &&
michael@0 551 subject.document.documentURI == 'chrome://global/content/commonDialog.xul')
michael@0 552 {
michael@0 553 subject.close();
michael@0 554 }
michael@0 555 else
michael@0 556 {
michael@0 557 // alerts inside of reftest framework are not XULDocument dialogs.
michael@0 558 subject.close();
michael@0 559 }
michael@0 560 }
michael@0 561 }
michael@0 562
michael@0 563 registerDialogCloser();
michael@0 564 window.addEventListener('unload', unregisterDialogCloser, true);
michael@0 565
michael@0 566 jsTestDriverBrowserInit();

mercurial