зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1602668 - Enables xorigin iframe mode for mochitest-plain. r=kmag
Differential Revision: https://phabricator.services.mozilla.com/D70360
This commit is contained in:
Родитель
f58c7a2553
Коммит
b4821a1c8e
|
@ -66,6 +66,7 @@ http://127.0.0.1:80 privileged
|
|||
http://127.0.0.1:8888 privileged
|
||||
http://test:80 privileged
|
||||
http://mochi.test:8888 privileged
|
||||
http://mochi.xorigin-test:8888 privileged
|
||||
http://test1.mochi.test:8888
|
||||
http://sub1.test1.mochi.test:8888
|
||||
http://sub2.xn--lt-uia.mochi.test:8888
|
||||
|
|
|
@ -34,6 +34,9 @@ function parseTestManifest(testManifest, params, callback) {
|
|||
};
|
||||
} else {
|
||||
let name = params.testPrefix + path;
|
||||
if (params.xOriginTests && obj.scheme == "https") {
|
||||
name = params.httpsBaseUrl + path;
|
||||
}
|
||||
paths.push({
|
||||
test: {
|
||||
url: name,
|
||||
|
|
|
@ -418,6 +418,12 @@ class MochitestArguments(ArgumentContainer):
|
|||
"default": False,
|
||||
"help": "Run tests with fission (site isolation) enabled.",
|
||||
}],
|
||||
[["--enable-xorigin-tests"],
|
||||
{"action": "store_true",
|
||||
"default": False,
|
||||
"dest": "xOriginTests",
|
||||
"help": "Run tests in a cross origin iframe.",
|
||||
}],
|
||||
[["--store-chrome-manifest"],
|
||||
{"action": "store",
|
||||
"help": "Destination path to write a copy of any chrome manifest "
|
||||
|
|
|
@ -199,7 +199,7 @@ class MessageLogger(object):
|
|||
def _fix_test_name(self, message):
|
||||
"""Normalize a logged test path to match the relative path from the sourcedir.
|
||||
"""
|
||||
if 'test' in message:
|
||||
if message.get('test') is not None:
|
||||
test = message['test']
|
||||
for prefix in MessageLogger.TEST_PATH_PREFIXES:
|
||||
if test.startswith(prefix):
|
||||
|
@ -307,7 +307,6 @@ class MessageLogger(object):
|
|||
|
||||
if message['action'] == 'test_start':
|
||||
self.is_test_running = True
|
||||
|
||||
if self.restore_buffering:
|
||||
self.restore_buffering = False
|
||||
self.buffering = True
|
||||
|
@ -1086,6 +1085,11 @@ class MochitestDesktop(object):
|
|||
self.urlOpts.append("jscovDirPrefix=%s" % options.jscov_dir_prefix)
|
||||
if options.cleanupCrashes:
|
||||
self.urlOpts.append("cleanupCrashes=true")
|
||||
if "MOZ_XORIGIN_MOCHITEST" in env and \
|
||||
env["MOZ_XORIGIN_MOCHITEST"] == "1":
|
||||
options.xOriginTests = True
|
||||
if options.xOriginTests:
|
||||
self.urlOpts.append("xOriginTests=true")
|
||||
|
||||
def normflavor(self, flavor):
|
||||
"""
|
||||
|
@ -1129,6 +1133,8 @@ class MochitestDesktop(object):
|
|||
def buildTestURL(self, options, scheme='http'):
|
||||
if scheme == 'https':
|
||||
testHost = "https://example.com:443"
|
||||
elif options.xOriginTests:
|
||||
testHost = "http://mochi.xorigin-test:8888"
|
||||
else:
|
||||
testHost = "http://mochi.test:8888"
|
||||
testURL = "/".join([testHost, self.TEST_PATH])
|
||||
|
@ -2647,6 +2653,7 @@ toolbar#nav-bar {
|
|||
'network.process.enabled', False),
|
||||
"verify": options.verify,
|
||||
"webrender": options.enable_webrender,
|
||||
"xorigin": options.xOriginTests,
|
||||
})
|
||||
|
||||
self.setTestRoot(options)
|
||||
|
@ -2918,6 +2925,8 @@ toolbar#nav-bar {
|
|||
self.log.info("runtests.py | Running with e10s: {}".format(options.e10s))
|
||||
self.log.info("runtests.py | Running with fission: {}".format(
|
||||
mozinfo.info.get('fission', False)))
|
||||
self.log.info("runtests.py | Running with cross-origin iframes: {}".format(
|
||||
mozinfo.info.get('xorigin', False)))
|
||||
self.log.info("runtests.py | Running with serviceworker_e10s: {}".format(
|
||||
mozinfo.info.get('serviceworker_e10s', False)))
|
||||
self.log.info("runtests.py | Running with socketprocess_e10s: {}".format(
|
||||
|
|
|
@ -25,6 +25,21 @@
|
|||
var SimpleTest = {};
|
||||
var parentRunner = null;
|
||||
|
||||
// Using a try/catch rather than SpecialPowers.Cu.isRemoteProxy() because
|
||||
// it doesn't cover the case where an iframe is xorigin but fission is
|
||||
// not enabled.
|
||||
let isSameOrigin = function(w) {
|
||||
try {
|
||||
w.top.TestRunner;
|
||||
} catch (e) {
|
||||
if (e instanceof DOMException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
let isXOrigin = !isSameOrigin(window);
|
||||
|
||||
// In normal test runs, the window that has a TestRunner in its parent is
|
||||
// the primary window. In single test runs, if there is no parent and there
|
||||
// is no opener then it is the primary window.
|
||||
|
@ -32,7 +47,9 @@ var isSingleTestRun =
|
|||
parent == window &&
|
||||
!(opener || (window.arguments && window.arguments[0].SimpleTest));
|
||||
try {
|
||||
var isPrimaryTestWindow = !!parent.TestRunner || isSingleTestRun;
|
||||
var isPrimaryTestWindow =
|
||||
(isXOrigin && parent != window && parent == top) ||
|
||||
(!isXOrigin && (!!parent.TestRunner || isSingleTestRun));
|
||||
} catch (e) {
|
||||
dump(
|
||||
"TEST-UNEXPECTED-FAIL, Exception caught: " +
|
||||
|
@ -46,6 +63,87 @@ try {
|
|||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
let xOriginRunner = {
|
||||
init(harnessWindow) {
|
||||
this.harnessWindow = harnessWindow;
|
||||
let url = new URL(document.URL);
|
||||
this.testFile = url.pathname;
|
||||
this.showTestReport = url.searchParams.get("showTestReport") == "true";
|
||||
this.expected = url.searchParams.get("expected");
|
||||
},
|
||||
callHarnessMethod(applyOn, command, ...params) {
|
||||
this.harnessWindow.postMessage(
|
||||
{
|
||||
harnessType: "SimpleTest",
|
||||
applyOn,
|
||||
command,
|
||||
params,
|
||||
},
|
||||
"*"
|
||||
);
|
||||
},
|
||||
getParameterInfo() {
|
||||
let url = new URL(document.URL);
|
||||
return {
|
||||
currentTestURL: url.searchParams.get("currentTestURL"),
|
||||
testRoot: url.searchParams.get("testRoot"),
|
||||
};
|
||||
},
|
||||
addFailedTest(test) {
|
||||
this.callHarnessMethod("runner", "addFailedTest", test);
|
||||
},
|
||||
expectAssertions(min, max) {
|
||||
this.callHarnessMethod("runner", "expectAssertions", min, max);
|
||||
},
|
||||
requestLongerTimeout(factor) {
|
||||
this.harnessWindow.postMessage(
|
||||
{
|
||||
harnessType: "SimpleTest",
|
||||
command: "requestLongerTimeout",
|
||||
applyOn: "runner",
|
||||
params: [factor],
|
||||
},
|
||||
"*"
|
||||
);
|
||||
},
|
||||
testFinished(tests) {
|
||||
this.callHarnessMethod("runner", "testFinished", tests);
|
||||
},
|
||||
structuredLogger: {
|
||||
info(msg) {
|
||||
xOriginRunner.callHarnessMethod("logger", "structuredLogger.info", msg);
|
||||
},
|
||||
error(msg) {
|
||||
xOriginRunner.callHarnessMethod("logger", "structuredLogger.error", msg);
|
||||
},
|
||||
activateBuffering() {
|
||||
xOriginRunner.callHarnessMethod(
|
||||
"logger",
|
||||
"structuredLogger.activateBuffering"
|
||||
);
|
||||
},
|
||||
deactivateBuffering() {
|
||||
xOriginRunner.callHarnessMethod(
|
||||
"logger",
|
||||
"structuredLogger.deactivateBuffering"
|
||||
);
|
||||
},
|
||||
testStatus(url, subtest, status, expected, diagnostic, stack) {
|
||||
xOriginRunner.callHarnessMethod(
|
||||
"logger",
|
||||
"structuredLogger.testStatus",
|
||||
url,
|
||||
subtest,
|
||||
status,
|
||||
expected,
|
||||
diagnostic,
|
||||
stack
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Finds the TestRunner for this test run and the SpecialPowers object (in
|
||||
// case it is not defined) from a parent/opener window.
|
||||
//
|
||||
|
@ -57,20 +155,31 @@ try {
|
|||
function ancestor(w) {
|
||||
return w.parent != w
|
||||
? w.parent
|
||||
: w.opener || (w.arguments && w.arguments[0]);
|
||||
: w.opener ||
|
||||
(!isXOrigin &&
|
||||
w.arguments &&
|
||||
SpecialPowers.wrap(Window).isInstance(w.arguments[0]) &&
|
||||
w.arguments[0]);
|
||||
}
|
||||
|
||||
var w = ancestor(window);
|
||||
while (w && (!parentRunner || !window.SpecialPowers)) {
|
||||
while (w && !parentRunner) {
|
||||
isXOrigin = !isSameOrigin(w);
|
||||
|
||||
if (isXOrigin) {
|
||||
if (w.parent != w) {
|
||||
w = w.top;
|
||||
}
|
||||
xOriginRunner.init(w);
|
||||
parentRunner = xOriginRunner;
|
||||
}
|
||||
|
||||
if (!parentRunner) {
|
||||
parentRunner = w.TestRunner;
|
||||
if (!parentRunner && w.wrappedJSObject) {
|
||||
parentRunner = w.wrappedJSObject.TestRunner;
|
||||
}
|
||||
}
|
||||
if (!window.SpecialPowers) {
|
||||
window.SpecialPowers = w.SpecialPowers;
|
||||
}
|
||||
w = ancestor(w);
|
||||
}
|
||||
|
||||
|
@ -273,17 +382,18 @@ function recordIfMatchesFailurePattern(name, diag) {
|
|||
}
|
||||
|
||||
SimpleTest.setExpected = function() {
|
||||
if (parent.TestRunner) {
|
||||
if (!Array.isArray(parent.TestRunner.expected)) {
|
||||
SimpleTest.expected = parent.TestRunner.expected;
|
||||
} else {
|
||||
// Assertions are checked by the runner.
|
||||
SimpleTest.expected = parent.TestRunner.expected.filter(
|
||||
([pat]) => pat != "ASSERTION"
|
||||
);
|
||||
SimpleTest.num_failed = new Array(SimpleTest.expected.length);
|
||||
SimpleTest.num_failed.fill(0);
|
||||
}
|
||||
if (!parentRunner) {
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(parentRunner.expected)) {
|
||||
SimpleTest.expected = parentRunner.expected;
|
||||
} else {
|
||||
// Assertions are checked by the runner.
|
||||
SimpleTest.expected = parentRunner.expected.filter(
|
||||
([pat]) => pat != "ASSERTION"
|
||||
);
|
||||
SimpleTest.num_failed = new Array(SimpleTest.expected.length);
|
||||
SimpleTest.num_failed.fill(0);
|
||||
}
|
||||
};
|
||||
SimpleTest.setExpected();
|
||||
|
@ -368,7 +478,6 @@ SimpleTest.record = function(condition, name, diag, stack, expected) {
|
|||
stack.splice(0, 1);
|
||||
stack = stack.join("\n");
|
||||
}
|
||||
|
||||
SimpleTest._logResult(test, successInfo, failureInfo, stack);
|
||||
SimpleTest._tests.push(test);
|
||||
};
|
||||
|
@ -464,6 +573,8 @@ SimpleTest.getTestFileURL = function(path) {
|
|||
|
||||
SimpleTest._getCurrentTestURL = function() {
|
||||
return (
|
||||
(SimpleTest.harnessParameters &&
|
||||
SimpleTest.harnessParameters.currentTestURL) ||
|
||||
(parentRunner && parentRunner.currentTestURL) ||
|
||||
(typeof gTestPath == "string" && gTestPath) ||
|
||||
"unknown test url"
|
||||
|
@ -1331,7 +1442,6 @@ SimpleTest.finish = function() {
|
|||
expected: "FAIL",
|
||||
message: "TEST-UNEXPECTED-PASS",
|
||||
};
|
||||
|
||||
SimpleTest._logResult(test, successInfo, failureInfo);
|
||||
SimpleTest._tests.push(test);
|
||||
} else if (usesFailurePatterns()) {
|
||||
|
|
|
@ -75,6 +75,16 @@ function flattenArguments(lst /* ...*/) {
|
|||
return res;
|
||||
}
|
||||
|
||||
function testInXOriginFrame() {
|
||||
// Check if the test running in an iframe is a cross origin test.
|
||||
try {
|
||||
$("testframe").contentWindow.origin;
|
||||
return false;
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TestRunner: A test runner for SimpleTest
|
||||
* TODO:
|
||||
|
@ -356,7 +366,30 @@ TestRunner._makeIframe = function(url, retry) {
|
|||
);
|
||||
}
|
||||
window.scrollTo(0, $("indicator").offsetTop);
|
||||
iframe.src = url;
|
||||
try {
|
||||
let urlObj = new URL(url);
|
||||
if (TestRunner.xOriginTests) {
|
||||
// The test will run in a xorigin iframe, so we pass in additional test params in the
|
||||
// URL since the content process won't be able to access them from the parentRunner
|
||||
// directly.
|
||||
let params = TestRunner.getParameterInfo();
|
||||
urlObj.searchParams.append(
|
||||
"currentTestURL",
|
||||
urlObj.pathname.replace("/tests/", "")
|
||||
);
|
||||
urlObj.searchParams.append("closeWhenDone", params.closeWhenDone);
|
||||
urlObj.searchParams.append("showTestReport", TestRunner.showTestReport);
|
||||
urlObj.searchParams.append("expected", TestRunner.expected);
|
||||
iframe.src = urlObj.href;
|
||||
} else {
|
||||
iframe.src = url;
|
||||
}
|
||||
} catch {
|
||||
// If the provided `url` is not a valid URL (i.e. doesn't include a protocol)
|
||||
// then the new URL() constructor will raise a TypeError. This is expected in the
|
||||
// usual case (i.e. non-xorigin iFrame tests) so set the URL in the usual way.
|
||||
iframe.src = url;
|
||||
}
|
||||
iframe.name = url;
|
||||
iframe.width = "500";
|
||||
};
|
||||
|
@ -367,12 +400,15 @@ TestRunner._makeIframe = function(url, retry) {
|
|||
* being finished first.
|
||||
*/
|
||||
TestRunner.getLoadedTestURL = function() {
|
||||
var prefix = "";
|
||||
// handle mochitest-chrome URIs
|
||||
if ($("testframe").contentWindow.location.protocol == "chrome:") {
|
||||
prefix = "chrome://mochitests";
|
||||
if (!testInXOriginFrame()) {
|
||||
var prefix = "";
|
||||
// handle mochitest-chrome URIs
|
||||
if ($("testframe").contentWindow.location.protocol == "chrome:") {
|
||||
prefix = "chrome://mochitests";
|
||||
}
|
||||
return prefix + $("testframe").contentWindow.location.pathname;
|
||||
}
|
||||
return prefix + $("testframe").contentWindow.location.pathname;
|
||||
return TestRunner.currentTestURL;
|
||||
};
|
||||
|
||||
TestRunner.setParameterInfo = function(params) {
|
||||
|
@ -704,34 +740,39 @@ TestRunner.testFinished = function(tests) {
|
|||
}
|
||||
|
||||
var interstitialURL;
|
||||
if ($("testframe").contentWindow.location.protocol == "chrome:") {
|
||||
if (
|
||||
!testInXOriginFrame() &&
|
||||
$("testframe").contentWindow.location.protocol == "chrome:"
|
||||
) {
|
||||
interstitialURL = "tests/SimpleTest/iframe-between-tests.html";
|
||||
} else {
|
||||
interstitialURL = "/tests/SimpleTest/iframe-between-tests.html";
|
||||
}
|
||||
// check if there were test run after SimpleTest.finish, which should never happen
|
||||
$("testframe").contentWindow.addEventListener("unload", function() {
|
||||
var testwin = $("testframe").contentWindow;
|
||||
if (
|
||||
testwin.SimpleTest &&
|
||||
testwin.SimpleTest._tests.length != testwin.SimpleTest.testsLength
|
||||
) {
|
||||
var wrongtestlength =
|
||||
testwin.SimpleTest._tests.length - testwin.SimpleTest.testsLength;
|
||||
var wrongtestname = "";
|
||||
for (var i = 0; i < wrongtestlength; i++) {
|
||||
wrongtestname =
|
||||
testwin.SimpleTest._tests[testwin.SimpleTest.testsLength + i]
|
||||
.name;
|
||||
TestRunner.structuredLogger.error(
|
||||
TestRunner.currentTestURL +
|
||||
" logged result after SimpleTest.finish(): " +
|
||||
wrongtestname
|
||||
);
|
||||
if (!testInXOriginFrame()) {
|
||||
$("testframe").contentWindow.addEventListener("unload", function() {
|
||||
var testwin = $("testframe").contentWindow;
|
||||
if (
|
||||
testwin.SimpleTest &&
|
||||
testwin.SimpleTest._tests.length != testwin.SimpleTest.testsLength
|
||||
) {
|
||||
var wrongtestlength =
|
||||
testwin.SimpleTest._tests.length - testwin.SimpleTest.testsLength;
|
||||
var wrongtestname = "";
|
||||
for (var i = 0; i < wrongtestlength; i++) {
|
||||
wrongtestname =
|
||||
testwin.SimpleTest._tests[testwin.SimpleTest.testsLength + i]
|
||||
.name;
|
||||
TestRunner.structuredLogger.error(
|
||||
TestRunner.currentTestURL +
|
||||
" logged result after SimpleTest.finish(): " +
|
||||
wrongtestname
|
||||
);
|
||||
}
|
||||
TestRunner.updateUI([{ result: false }]);
|
||||
}
|
||||
TestRunner.updateUI([{ result: false }]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
TestRunner._makeIframe(interstitialURL, 0);
|
||||
}
|
||||
|
||||
|
@ -891,3 +932,43 @@ TestRunner.updateUI = function(tests) {
|
|||
TestRunner.displayLoopErrors("fail-table", tests);
|
||||
}
|
||||
};
|
||||
|
||||
// XOrigin Tests
|
||||
// If "--enable-xorigin-tests" is set, mochitests are run in a cross origin iframe.
|
||||
// The parent process will run at http://mochi.xorigin-test:8888", and individual
|
||||
// mochitests will be launched in a cross-origin iframe at http://mochi.test:8888.
|
||||
|
||||
var xOriginDispatchMap = {
|
||||
runner: TestRunner,
|
||||
logger: TestRunner.structuredLogger,
|
||||
addFailedTest: TestRunner.addFailedTest,
|
||||
expectAssertions: TestRunner.expectAssertions,
|
||||
requestLongerTimeout: TestRunner.requestLongerTimeout,
|
||||
testUnloaded: TestRunner.testUnloaded,
|
||||
"structuredLogger.deactivateBuffering":
|
||||
TestRunner.structuredLogger.deactivateBuffering,
|
||||
"structuredLogger.activateBuffering":
|
||||
TestRunner.structuredLogger.activateBuffering,
|
||||
"structuredLogger.testStatus": TestRunner.structuredLogger.testStatus,
|
||||
"structuredLogger.info": TestRunner.structuredLogger.info,
|
||||
testFinished: TestRunner.testFinished,
|
||||
};
|
||||
|
||||
function xOriginTestRunnerHandler(event) {
|
||||
if (event.data.harnessType != "SimpleTest") {
|
||||
return;
|
||||
}
|
||||
if (event.data.command in xOriginDispatchMap) {
|
||||
xOriginDispatchMap[event.data.command].apply(
|
||||
xOriginDispatchMap[event.data.applyOn],
|
||||
event.data.params
|
||||
);
|
||||
} else {
|
||||
TestRunner.error(`Command ${event.data.command} not found
|
||||
in xOriginDispatchMap`);
|
||||
}
|
||||
}
|
||||
|
||||
TestRunner.setXOriginEventHandler = function() {
|
||||
window.addEventListener("message", xOriginTestRunnerHandler);
|
||||
};
|
||||
|
|
|
@ -90,6 +90,8 @@ if (config.testRoot == "chrome" || config.testRoot == "a11y") {
|
|||
}
|
||||
params = config;
|
||||
params.baseurl = "chrome://mochitests/content";
|
||||
} else if (params.xOriginTests) {
|
||||
params.baseurl = "http://mochi.test:8888/tests/";
|
||||
} else {
|
||||
params.baseurl = "";
|
||||
}
|
||||
|
@ -100,6 +102,9 @@ if (params.testRoot == "browser") {
|
|||
params.testPrefix = "chrome://mochitests/content/chrome/";
|
||||
} else if (params.testRoot == "a11y") {
|
||||
params.testPrefix = "chrome://mochitests/content/a11y/";
|
||||
} else if (params.xOriginTests) {
|
||||
params.testPrefix = "http://mochi.test:8888/tests/";
|
||||
params.httpsBaseUrl = "https://example.org:443/tests/";
|
||||
} else {
|
||||
params.testPrefix = "/tests/";
|
||||
}
|
||||
|
@ -175,6 +180,11 @@ if (params.cleanupCrashes) {
|
|||
TestRunner.cleanupCrashes = true;
|
||||
}
|
||||
|
||||
if (params.xOriginTests) {
|
||||
TestRunner.xOriginTests = true;
|
||||
TestRunner.setXOriginEventHandler();
|
||||
}
|
||||
|
||||
// Log things to the console if appropriate.
|
||||
TestRunner.logger.addListener("dumpListener", consoleLevel + "", function(msg) {
|
||||
dump(msg.info.join(" ") + "\n");
|
||||
|
|
Загрузка…
Ссылка в новой задаче