--- a/browser/components/migration/tests/marionette/test_refresh_firefox.py
+++ b/browser/components/migration/tests/marionette/test_refresh_firefox.py
@@ -41,127 +41,134 @@ class TestFirefoxRefresh(MarionetteTestC
"username",
"password"
);
Services.logins.addLogin(myLogin)
""", script_args=(self._username, self._password))
def createBookmarkInMenu(self):
error = self.runAsyncCode("""
- let url = arguments[0];
- let title = arguments[1];
+ // let url = arguments[0];
+ // let title = arguments[1];
+ // let resolve = arguments[arguments.length - 1];
+ let [url, title, resolve] = arguments;
PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.menuGuid, url, title
- }).then(() => marionetteScriptFinished(false), marionetteScriptFinished);
+ }).then(() => resolve(false), resolve);
""", script_args=(self._bookmarkURL, self._bookmarkText))
if error:
print(error)
def createBookmarksOnToolbar(self):
error = self.runAsyncCode("""
+ let resolve = arguments[arguments.length - 1];
let children = [];
for (let i = 1; i <= 5; i++) {
children.push({url: `about:rights?p=${i}`, title: `Bookmark ${i}`});
}
PlacesUtils.bookmarks.insertTree({
guid: PlacesUtils.bookmarks.toolbarGuid,
children
- }).then(() => marionetteScriptFinished(false), marionetteScriptFinished);
+ }).then(() => resolve(false), resolve);
""")
if error:
print(error)
def createHistory(self):
error = self.runAsyncCode("""
+ let resolve = arguments[arguments.length - 1];
PlacesUtils.history.insert({
url: arguments[0],
title: arguments[1],
visits: [{
date: new Date(Date.now() - 5000),
referrer: "about:mozilla"
}]
- }).then(() => marionetteScriptFinished(false),
- ex => marionetteScriptFinished("Unexpected error in adding visit: " + ex));
+ }).then(() => resolve(false),
+ ex => resolve("Unexpected error in adding visit: " + ex));
""", script_args=(self._historyURL, self._historyTitle))
if error:
print(error)
def createFormHistory(self):
error = self.runAsyncCode("""
let updateDefinition = {
op: "add",
fieldname: arguments[0],
value: arguments[1],
firstUsed: (Date.now() - 5000) * 1000,
};
let finished = false;
+ let resolve = arguments[arguments.length - 1];
global.FormHistory.update(updateDefinition, {
handleError(error) {
finished = true;
- marionetteScriptFinished(error);
+ resolve(error);
},
handleCompletion() {
if (!finished) {
- marionetteScriptFinished(false);
+ resolve(false);
}
}
});
""", script_args=(self._formHistoryFieldName, self._formHistoryValue))
if error:
print(error)
def createFormAutofill(self):
if not self._formAutofillAvailable:
return
self._formAutofillAddressGuid = self.runAsyncCode("""
+ let resolve = arguments[arguments.length - 1];
const TEST_ADDRESS_1 = {
"given-name": "John",
"additional-name": "R.",
"family-name": "Smith",
organization: "World Wide Web Consortium",
"street-address": "32 Vassar Street\\\nMIT Room 32-G524",
"address-level2": "Cambridge",
"address-level1": "MA",
"postal-code": "02139",
country: "US",
tel: "+15195555555",
email: "user@example.com",
};
return global.formAutofillStorage.initialize().then(() => {
return global.formAutofillStorage.addresses.add(TEST_ADDRESS_1);
- }).then(marionetteScriptFinished);
+ }).then(resolve);
""")
def createCookie(self):
self.runCode("""
// Expire in 15 minutes:
let expireTime = Math.floor(Date.now() / 1000) + 15 * 60;
Services.cookies.add(arguments[0], arguments[1], arguments[2], arguments[3],
true, false, false, expireTime);
""", script_args=(self._cookieHost, self._cookiePath, self._cookieName, self._cookieValue))
def createSession(self):
self.runAsyncCode("""
+ let resolve = arguments[arguments.length - 1];
const COMPLETE_STATE = Ci.nsIWebProgressListener.STATE_STOP +
Ci.nsIWebProgressListener.STATE_IS_NETWORK;
let {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
let expectedURLs = Array.from(arguments[0])
gBrowser.addTabsProgressListener({
onStateChange(browser, webprogress, request, flags, status) {
try {
request && request.QueryInterface(Ci.nsIChannel);
} catch (ex) {}
let uriLoaded = request.originalURI && request.originalURI.spec;
if ((flags & COMPLETE_STATE == COMPLETE_STATE) && uriLoaded &&
expectedURLs.includes(uriLoaded)) {
TabStateFlusher.flush(browser).then(function() {
expectedURLs.splice(expectedURLs.indexOf(uriLoaded), 1);
if (!expectedURLs.length) {
gBrowser.removeTabsProgressListener(this);
- marionetteScriptFinished();
+ resolve();
}
});
}
}
});
let expectedTabs = new Set();
for (let url of expectedURLs) {
expectedTabs.add(gBrowser.addTab(url));
@@ -174,21 +181,22 @@ class TestFirefoxRefresh(MarionetteTestC
}
}
""", script_args=(self._expectedURLs,)) # NOQA: E501
def createSync(self):
# This script will write an entry to the login manager and create
# a signedInUser.json in the profile dir.
self.runAsyncCode("""
+ let resolve = arguments[arguments.length - 1];
Cu.import("resource://gre/modules/FxAccountsStorage.jsm");
let storage = new FxAccountsStorageManager();
let data = {email: "test@test.com", uid: "uid", keyFetchToken: "top-secret"};
storage.initialize(data);
- storage.finalize().then(marionetteScriptFinished);
+ storage.finalize().then(resolve);
""")
def checkPassword(self):
loginInfo = self.marionette.execute_script("""
let ary = Services.logins.findLogins({},
"test.marionette.mozilla.com",
"http://test.marionette.mozilla.com/some/form/",
null, {});
@@ -201,98 +209,102 @@ class TestFirefoxRefresh(MarionetteTestC
loginCount = self.marionette.execute_script("""
return Services.logins.getAllLogins().length;
""")
# Note that we expect 2 logins - one from us, one from sync.
self.assertEqual(loginCount, 2, "No other logins are present")
def checkBookmarkInMenu(self):
titleInBookmarks = self.runAsyncCode("""
- let url = arguments[0];
+ let [url, resolve] = arguments;
PlacesUtils.bookmarks.fetch({url}).then(
- bookmark => marionetteScriptFinished(bookmark ? bookmark.title : ""),
- ex => marionetteScriptFinished(ex)
+ bookmark => resolve(bookmark ? bookmark.title : ""),
+ ex => resolve(ex)
);
""", script_args=(self._bookmarkURL,))
self.assertEqual(titleInBookmarks, self._bookmarkText)
def checkBookmarkToolbarVisibility(self):
toolbarVisible = self.marionette.execute_script("""
const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
let xulStore = Cc["@mozilla.org/xul/xulstore;1"].getService(Ci.nsIXULStore);
return xulStore.getValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed")
""")
self.assertEqual(toolbarVisible, "false")
def checkHistory(self):
historyResult = self.runAsyncCode("""
+ let resolve = arguments[arguments.length - 1];
PlacesUtils.history.fetch(arguments[0]).then(pageInfo => {
if (!pageInfo) {
- marionetteScriptFinished("No visits found");
+ resolve("No visits found");
} else {
- marionetteScriptFinished(pageInfo);
+ resolve(pageInfo);
}
}).catch(e => {
- marionetteScriptFinished("Unexpected error in fetching page: " + e);
+ resolve("Unexpected error in fetching page: " + e);
});
""", script_args=(self._historyURL,))
if type(historyResult) == str:
self.fail(historyResult)
return
self.assertEqual(historyResult['title'], self._historyTitle)
def checkFormHistory(self):
formFieldResults = self.runAsyncCode("""
+ let resolve = arguments[arguments.length - 1];
let results = [];
global.FormHistory.search(["value"], {fieldname: arguments[0]}, {
handleError(error) {
results = error;
},
handleResult(result) {
results.push(result);
},
handleCompletion() {
- marionetteScriptFinished(results);
+ resolve(results);
},
});
""", script_args=(self._formHistoryFieldName,))
if type(formFieldResults) == str:
self.fail(formFieldResults)
return
formFieldResultCount = len(formFieldResults)
self.assertEqual(formFieldResultCount, 1,
"Should have exactly 1 entry for this field, got %d" %
formFieldResultCount)
if formFieldResultCount == 1:
self.assertEqual(
formFieldResults[0]['value'], self._formHistoryValue)
formHistoryCount = self.runAsyncCode("""
+ let [resolve] = arguments;
let count;
let callbacks = {
handleResult: rv => count = rv,
handleCompletion() {
- marionetteScriptFinished(count);
+ resolve(count);
},
};
global.FormHistory.count({}, callbacks);
""")
self.assertEqual(formHistoryCount, 1,
"There should be only 1 entry in the form history")
def checkFormAutofill(self):
if not self._formAutofillAvailable:
return
formAutofillResults = self.runAsyncCode("""
+ let resolve = arguments[arguments.length - 1];
return global.formAutofillStorage.initialize().then(() => {
return global.formAutofillStorage.addresses.getAll()
- }).then(marionetteScriptFinished);
+ }).then(resolve);
""",)
if type(formAutofillResults) == str:
self.fail(formAutofillResults)
return
formAutofillAddressCount = len(formAutofillResults)
self.assertEqual(formAutofillAddressCount, 1,
"Should have exactly 1 saved address, got %d" % formAutofillAddressCount)
@@ -338,23 +350,24 @@ class TestFirefoxRefresh(MarionetteTestC
# default browser dialog if it shows up.
try:
alert = self.marionette.switch_to_alert()
alert.dismiss()
except NoAlertPresentException:
pass
tabURIs = self.runAsyncCode("""
+ let resolve = arguments[arguments.length - 1]
let mm = gBrowser.selectedBrowser.messageManager;
let {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
window.addEventListener("SSWindowStateReady", function testSSPostReset() {
window.removeEventListener("SSWindowStateReady", testSSPostReset, false);
Promise.all(gBrowser.browsers.map(b => TabStateFlusher.flush(b))).then(function() {
- marionetteScriptFinished([... gBrowser.browsers].map(b => b.currentURI && b.currentURI.spec));
+ resolve([... gBrowser.browsers].map(b => b.currentURI && b.currentURI.spec));
});
}, false);
let fs = function() {
if (content.document.readyState === "complete") {
content.document.getElementById("errorTryAgain").click();
} else {
content.window.addEventListener("load", function(event) {
@@ -365,28 +378,29 @@ class TestFirefoxRefresh(MarionetteTestC
mm.loadFrameScript("data:application/javascript,(" + fs.toString() + ")()", true);
""") # NOQA: E501
self.assertSequenceEqual(tabURIs, self._expectedURLs)
def checkSync(self, hasMigrated):
result = self.runAsyncCode("""
Cu.import("resource://gre/modules/FxAccountsStorage.jsm");
+ let resolve = arguments[arguments.length - 1];
let prefs = new global.Preferences("services.sync.");
let storage = new FxAccountsStorageManager();
let result = {};
storage.initialize();
storage.getAccountData().then(data => {
result.accountData = data;
return storage.finalize();
}).then(() => {
result.prefUsername = prefs.get("username");
- marionetteScriptFinished(result);
+ resolve(result);
}).catch(err => {
- marionetteScriptFinished(err.toString());
+ resolve(err.toString());
});
""")
if type(result) != dict:
self.fail(result)
return
self.assertEqual(result["accountData"]["email"], "test@test.com")
self.assertEqual(result["accountData"]["uid"], "uid")
self.assertEqual(result["accountData"]["keyFetchToken"], "top-secret")
--- a/testing/awsy/awsy/awsy_test_case.py
+++ b/testing/awsy/awsy/awsy_test_case.py
@@ -139,21 +139,22 @@ class AwsyTestCase(MarionetteTestCase):
def do_full_gc(self):
"""Performs a full garbage collection cycle and returns when it is finished.
Returns True on success and False on failure.
"""
# NB: we could do this w/ a signal or the fifo queue too
self.logger.info("starting gc...")
gc_script = """
+ let [resolve] = arguments;
Cu.import("resource://gre/modules/Services.jsm");
Services.obs.notifyObservers(null, "child-mmu-request", null);
let memMgrSvc = Cc["@mozilla.org/memory-reporter-manager;1"].getService(Ci.nsIMemoryReporterManager);
- memMgrSvc.minimizeMemoryUsage(() => marionetteScriptFinished("gc done!"));
+ memMgrSvc.minimizeMemoryUsage(() => {resolve("gc done!");});
"""
result = None
try:
result = self.marionette.execute_async_script(
gc_script, script_timeout=180000)
except JavascriptException, e:
self.logger.error("GC JavaScript error: %s" % e)
except ScriptTimeoutException:
@@ -182,20 +183,21 @@ class AwsyTestCase(MarionetteTestCase):
# separator \ and escape it to prevent it from being
# interpreted as an escape character.
if sys.platform.startswith('win'):
checkpoint_path = (checkpoint_path.
replace('\\', '\\\\').
replace('/', '\\\\'))
checkpoint_script = r"""
+ let [resolve] = arguments;
let dumper = Cc["@mozilla.org/memory-info-dumper;1"].getService(Ci.nsIMemoryInfoDumper);
dumper.dumpMemoryReportsToNamedFile(
"%s",
- () => marionetteScriptFinished("memory report done!"),
+ () => resolve("memory report done!"),
null,
/* anonymize */ false);
""" % checkpoint_path
checkpoint = None
try:
finished = self.marionette.execute_async_script(
checkpoint_script, script_timeout=60000)
--- a/testing/marionette/client/docs/basics.rst
+++ b/testing/marionette/client/docs/basics.rst
@@ -163,23 +163,24 @@ functions. They accomplish what their na
synchronous JavaScript, while the latter provides a callback mechanism for
running asynchronous JavaScript:
.. parsed-literal::
result = client.execute_script("return arguments[0] + arguments[1];",
script_args=[2, 3])
assert result == 5
-The async method works the same way, except it won't return until a special
-`marionetteScriptFinished()` function is called:
+The async method works the same way, except it won't return until the
+`resolve()` function is called:
.. parsed-literal::
result = client.execute_async_script("""
+ let [resolve] = arguments;
setTimeout(function() {
- marionetteScriptFinished("all done");
+ resolve("all done");
}, arguments[0]);
""", script_args=[1000])
assert result == "all done"
Beware that running asynchronous scripts can potentially hang the program
indefinitely if they are not written properly. It is generally a good idea to
set a script timeout using :func:`~Marionette.timeout.script` and handling
`ScriptTimeoutException`.
--- a/testing/marionette/client/marionette_driver/marionette.py
+++ b/testing/marionette/client/marionette_driver/marionette.py
@@ -1718,18 +1718,19 @@ class Marionette(object):
Usage example:
::
marionette.timeout.script = 10
result = self.marionette.execute_async_script('''
// this script waits 5 seconds, and then returns the number 1
+ let [resolve] = arguments;
setTimeout(function() {
- marionetteScriptFinished(1);
+ resolve(1);
}, 5000);
''')
assert result == 1
"""
args = self._to_json(script_args)
stack = traceback.extract_stack()
frame = stack[-2:-1][0] # grab the second-to-last frame
filename = frame[0] if sys.platform == "win32" else os.path.relpath(frame[0])
--- a/testing/marionette/evaluate.js
+++ b/testing/marionette/evaluate.js
@@ -23,40 +23,39 @@ const log = Log.repository.getLogger("Ma
this.EXPORTED_SYMBOLS = ["evaluate", "sandbox", "Sandboxes"];
const ARGUMENTS = "__webDriverArguments";
const CALLBACK = "__webDriverCallback";
const COMPLETE = "__webDriverComplete";
const DEFAULT_TIMEOUT = 10000; // ms
const FINISH = "finish";
-const MARIONETTE_SCRIPT_FINISHED = "marionetteScriptFinished";
/** @namespace */
this.evaluate = {};
/**
* Evaluate a script in given sandbox.
*
* The the provided `script` will be wrapped in an anonymous function
* with the `args` argument applied.
*
* The arguments provided by the `args<` argument are exposed
* through the `arguments` object available in the script context,
* and if the script is executed asynchronously with the `async`
* option, an additional last argument that is synonymous to the
- * `marionetteScriptFinished` global is appended, and can be accessed
+ * name `resolve` is appended, and can be accessed
* through `arguments[arguments.length - 1]`.
*
* The `timeout` option specifies the duration for how long the
* script should be allowed to run before it is interrupted and aborted.
* An interrupted script will cause a {@link ScriptTimeoutError} to occur.
*
* The `async` option indicates that the script will not return
- * until the `marionetteScriptFinished` global callback is invoked,
+ * until the `resolve` callback is invoked,
* which is analogous to the last argument of the `arguments` object.
*
* The `file` option is used in error messages to provide information
* on the origin script file in the local end.
*
* The `line` option is used in error messages, along with `filename`,
* to provide the line number in the origin script file on the local end.
*
@@ -68,19 +67,16 @@ this.evaluate = {};
* A sequence of arguments to call the script with.
* @param {boolean=} [async=false] async
* Indicates if the script should return immediately or wait for
* the callback to be invoked before returning.
* @param {string=} [file="dummy file"] file
* File location of the program in the client.
* @param {number=} [line=0] line
* Line number of th eprogram in the client.
- * @param {string=} sandboxName
- * Name of the sandbox. Elevated system privileges, equivalent to
- * chrome space, will be given if it is <tt>system</tt>.
* @param {number=} [timeout=DEFAULT_TIMEOUT] timeout
* Duration in milliseconds before interrupting the script.
*
* @return {Promise}
* A promise that when resolved will give you the return value from
* the script. Note that the return value requires serialisation before
* it can be sent to the client.
*
@@ -89,17 +85,16 @@ this.evaluate = {};
* @throws {ScriptTimeoutError}
* If the script was interrupted due to script timeout.
*/
evaluate.sandbox = function(sb, script, args = [],
{
async = false,
file = "dummy file",
line = 0,
- sandboxName = null,
timeout = DEFAULT_TIMEOUT,
} = {}) {
let scriptTimeoutID, timeoutHandler, unloadHandler;
let promise = new Promise((resolve, reject) => {
let src = "";
sb[COMPLETE] = resolve;
timeoutHandler = () => reject(new ScriptTimeoutError(`Timed out after ${timeout} ms`));
@@ -117,22 +112,16 @@ evaluate.sandbox = function(sb, script,
// on the arguments object
if (async) {
sb[CALLBACK] = sb[COMPLETE];
src += `${ARGUMENTS}.push(rv => ${CALLBACK}(rv));`;
}
src += `(function() { ${script} }).apply(null, ${ARGUMENTS})`;
- // marionetteScriptFinished is not WebDriver conformant,
- // hence it is only exposed to immutable sandboxes
- if (sandboxName) {
- sb[MARIONETTE_SCRIPT_FINISHED] = sb[CALLBACK];
- }
-
// timeout and unload handlers
scriptTimeoutID = setTimeout(timeoutHandler, timeout);
sb.window.onunload = unloadHandler;
let res;
try {
res = Cu.evalInSandbox(src, sb, "1.8", file, line);
} catch (e) {
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_addons.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_addons.py
@@ -25,34 +25,38 @@ class TestAddons(MarionetteTestCase):
self.reset_addons()
super(TestAddons, self).tearDown()
@property
def all_addon_ids(self):
with self.marionette.using_context("chrome"):
addons = self.marionette.execute_async_script("""
+ let [resolve] = arguments;
Components.utils.import("resource://gre/modules/AddonManager.jsm");
+
AddonManager.getAllAddons().then(function(addons) {
let ids = addons.map(x => x.id);
- marionetteScriptFinished(ids);
+ resolve(ids);
});
""")
return set(addons)
def reset_addons(self):
with self.marionette.using_context("chrome"):
for addon in (self.all_addon_ids - self.preinstalled_addons):
addon_id = self.marionette.execute_async_script("""
+ let [resolve] = arguments;
Components.utils.import("resource://gre/modules/AddonManager.jsm");
+
return new Promise(await resolve => {
let addon = await AddonManager.getAddonByID(arguments[0]);
addon.uninstall();
- marionetteScriptFinished(addon.id);
+ resolve(addon.id);
});
""", script_args=(addon,))
self.assertEqual(addon_id, addon,
msg="Failed to uninstall {}".format(addon))
def test_temporary_install_and_remove_unsigned_addon(self):
addon_path = os.path.join(here, "webextension-unsigned.xpi")
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_execute_async_script.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_execute_async_script.py
@@ -14,53 +14,53 @@ class TestExecuteAsyncContent(Marionette
def setUp(self):
super(TestExecuteAsyncContent, self).setUp()
self.marionette.timeout.script = 1
def test_execute_async_simple(self):
self.assertEqual(1, self.marionette.execute_async_script("arguments[arguments.length-1](1);"))
def test_execute_async_ours(self):
- self.assertEqual(1, self.marionette.execute_async_script("marionetteScriptFinished(1);"))
+ self.assertEqual(1, self.marionette.execute_async_script("arguments[0](1);"))
def test_execute_async_timeout(self):
self.assertRaises(ScriptTimeoutException, self.marionette.execute_async_script, "var x = 1;")
def test_execute_async_unique_timeout(self):
- self.assertEqual(2, self.marionette.execute_async_script("setTimeout(function() {marionetteScriptFinished(2);}, 2000);", script_timeout=5000))
- self.assertRaises(ScriptTimeoutException, self.marionette.execute_async_script, "setTimeout(function() {marionetteScriptFinished(3);}, 2000);")
+ self.assertEqual(2, self.marionette.execute_async_script("setTimeout(() => arguments[0](2), 2000);", script_timeout=5000))
+ self.assertRaises(ScriptTimeoutException, self.marionette.execute_async_script, "setTimeout(() => arguments[0](3), 2000);")
def test_no_timeout(self):
self.marionette.timeout.script = 10
self.assertTrue(self.marionette.execute_async_script("""
var callback = arguments[arguments.length - 1];
setTimeout(function() { callback(true); }, 500);
"""))
def test_execute_async_unload(self):
self.marionette.timeout.script = 5
unload = """
window.location.href = "about:blank";
"""
self.assertRaises(JavascriptException, self.marionette.execute_async_script, unload)
def test_check_window(self):
- self.assertTrue(self.marionette.execute_async_script("marionetteScriptFinished(window !=null && window != undefined);"))
+ self.assertTrue(self.marionette.execute_async_script("arguments[0](window != null && window != undefined);"))
def test_same_context(self):
var1 = 'testing'
self.assertEqual(self.marionette.execute_script("""
this.testvar = '{}';
return this.testvar;
""".format(var1)), var1)
self.assertEqual(self.marionette.execute_async_script(
- "marionetteScriptFinished(this.testvar);", new_sandbox=False), var1)
+ "arguments[0](this.testvar);", new_sandbox=False), var1)
def test_execute_no_return(self):
- self.assertEqual(self.marionette.execute_async_script("marionetteScriptFinished()"), None)
+ self.assertEqual(self.marionette.execute_async_script("arguments[0]()"), None)
def test_execute_js_exception(self):
try:
self.marionette.execute_async_script("""
let a = 1;
foo(bar);
""")
self.fail()
@@ -76,39 +76,41 @@ class TestExecuteAsyncContent(Marionette
""")
self.fail()
except JavascriptException as e:
self.assertIsNotNone(e.stacktrace)
self.assertIn(os.path.relpath(__file__.replace(".pyc", ".py")), e.stacktrace)
def test_script_finished(self):
self.assertTrue(self.marionette.execute_async_script("""
- marionetteScriptFinished(true);
+ arguments[0](true);
"""))
def test_execute_permission(self):
self.assertRaises(JavascriptException, self.marionette.execute_async_script, """
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
-marionetteScriptFinished(4);
+arguments[0](4);
""")
def test_sandbox_reuse(self):
# Sandboxes between `execute_script()` invocations are shared.
self.marionette.execute_async_script("this.foobar = [23, 42];"
- "marionetteScriptFinished();")
+ "arguments[0]();")
self.assertEqual(self.marionette.execute_async_script(
- "marionetteScriptFinished(this.foobar);", new_sandbox=False), [23, 42])
+ "arguments[0](this.foobar);", new_sandbox=False), [23, 42])
def test_sandbox_refresh_arguments(self):
self.marionette.execute_async_script("this.foobar = [arguments[0], arguments[1]];"
- "marionetteScriptFinished();",
+ "let resolve = "
+ "arguments[arguments.length - 1];"
+ "resolve();",
script_args=[23, 42])
self.assertEqual(self.marionette.execute_async_script(
- "marionetteScriptFinished(this.foobar);", new_sandbox=False),
+ "arguments[0](this.foobar);", new_sandbox=False),
[23, 42])
# Functions defined in higher privilege scopes, such as the privileged
# content frame script listener.js runs in, cannot be accessed from
# content. This tests that it is possible to introspect the objects on
# `arguments` without getting permission defined errors. This is made
# possible because the last argument is always the callback/complete
# function.
@@ -126,17 +128,17 @@ class TestExecuteAsyncChrome(TestExecute
self.marionette.set_context("chrome")
def test_execute_async_unload(self):
pass
def test_execute_permission(self):
self.assertEqual(5, self.marionette.execute_async_script("""
var c = Components.classes;
-marionetteScriptFinished(5);
+arguments[0](5);
"""))
def test_execute_async_js_exception(self):
# Javascript exceptions are not propagated in chrome code
self.marionette.timeout.script = 0.2
self.assertRaises(ScriptTimeoutException,
self.marionette.execute_async_script, """
var callback = arguments[arguments.length - 1];
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_execute_isolate.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_execute_isolate.py
@@ -16,22 +16,23 @@ class TestExecuteIsolationContent(Marion
def test_execute_async_isolate(self):
# Results from one execute call that has timed out should not
# contaminate a future call.
multiplier = "*3" if self.content else "*1"
self.marionette.timeout.script = 0.5
self.assertRaises(ScriptTimeoutException,
self.marionette.execute_async_script,
- ("setTimeout(function() {{ marionetteScriptFinished(5{}); }}, 3000);"
+ ("setTimeout(function() {{ arguments[0](5{}); }}, 3000);"
.format(multiplier)))
self.marionette.timeout.script = 6
result = self.marionette.execute_async_script("""
- setTimeout(function() {{ marionetteScriptFinished(10{}); }}, 5000);
+ let [resolve] = arguments;
+ setTimeout(function() {{ resolve(10{}); }}, 5000);
""".format(multiplier))
self.assertEqual(result, 30 if self.content else 10)
class TestExecuteIsolationChrome(TestExecuteIsolationContent):
def setUp(self):
super(TestExecuteIsolationChrome, self).setUp()
self.marionette.set_context("chrome")
self.content = False
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_execute_sandboxes.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_execute_sandboxes.py
@@ -20,17 +20,17 @@ class TestExecuteSandboxes(MarionetteTes
sandbox="system")
self.assertEqual(result, 1)
def test_execute_async_system_sandbox(self):
# Test that "system" sandbox has elevated privileges in
# execute_async_script.
result = self.marionette.execute_async_script("""
let result = Ci.nsIPermissionManager.ALLOW_ACTION;
- marionetteScriptFinished(result);""",
+ arguments[0](result);""",
sandbox="system")
self.assertEqual(result, 1)
def test_execute_switch_sandboxes(self):
# Test that sandboxes are retained when switching between them
# for execute_script.
self.marionette.execute_script("foo = 1", sandbox="1")
self.marionette.execute_script("foo = 2", sandbox="2")
@@ -54,26 +54,26 @@ class TestExecuteSandboxes(MarionetteTes
foo = self.marionette.execute_script(
"return foo", sandbox="2", new_sandbox=False)
self.assertEqual(foo, 2)
def test_execute_async_switch_sandboxes(self):
# Test that sandboxes are retained when switching between them
# for execute_async_script.
self.marionette.execute_async_script(
- "foo = 1; marionetteScriptFinished()", sandbox="1")
+ "foo = 1; arguments[0]();", sandbox="1")
self.marionette.execute_async_script(
- "foo = 2; marionetteScriptFinished()", sandbox='2')
+ "foo = 2; arguments[0]();", sandbox='2')
foo = self.marionette.execute_async_script(
- "marionetteScriptFinished(foo)",
+ "arguments[0](foo);",
sandbox="1",
new_sandbox=False)
self.assertEqual(foo, 1)
foo = self.marionette.execute_async_script(
- "marionetteScriptFinished(foo)",
+ "arguments[0](foo);",
sandbox="2",
new_sandbox=False)
self.assertEqual(foo, 2)
class TestExecuteSandboxesChrome(TestExecuteSandboxes):
def setUp(self):
super(TestExecuteSandboxesChrome, self).setUp()
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_window_close_content.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_window_close_content.py
@@ -118,17 +118,17 @@ class TestCloseWindow(WindowManagerMixin
self.marionette.switch_to_window(self.start_tab)
with self.marionette.using_context("chrome"):
self.marionette.execute_async_script("""
Components.utils.import("resource:///modules/BrowserWindowTracker.jsm");
let win = BrowserWindowTracker.getTopWindow();
win.addEventListener("TabBrowserDiscarded", ev => {
- marionetteScriptFinished(true);
+ arguments[0](true);
}, { once: true});
win.gBrowser.discardBrowser(win.gBrowser.tabs[1].linkedBrowser);
""")
window_handles = self.marionette.window_handles
window_handles.remove(self.start_tab)
self.assertEqual(1, len(window_handles))
self.marionette.switch_to_window(window_handles[0], focus=False)
--- a/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/places.py
+++ b/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/places.py
@@ -27,39 +27,41 @@ class Places(BaseLib):
:param url: The URL to Check
:returns: True, if the URL is a bookmark
"""
return self.marionette.execute_async_script("""
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
- PlacesUtils.bookmarks.fetch({url: arguments[0]}).then(bm => {
- marionetteScriptFinished(bm != null);
+ let [url, resolve] = arguments;
+ PlacesUtils.bookmarks.fetch({url}).then(bm => {
+ resolve(bm != null);
});
""", script_args=[url])
def get_folder_ids_for_url(self, url):
"""Retrieve the folder ids where the given URL has been bookmarked in.
:param url: URL of the bookmark
:returns: List of folder ids
"""
return self.marionette.execute_async_script("""
+ let [url, resolve] = arguments;
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
- let folderGuids = []
+ let folderGuids = [];
function onResult(bm) {
folderGuids.push(bm.parentGuid);
}
- PlacesUtils.bookmarks.fetch({url: arguments[0]}, onResult).then(() => {
- marionetteScriptFinished(folderGuids);
+ PlacesUtils.bookmarks.fetch({url}, onResult).then(() => {
+ resolve(folderGuids);
});
""", script_args=[url])
def is_bookmark_star_button_ready(self):
"""Check if the status of the star-button is not updating.
:returns: True, if the button is ready
"""
@@ -67,26 +69,27 @@ class Places(BaseLib):
let button = window.BookmarkingUI;
return button.status !== button.STATUS_UPDATING;
""")
def restore_default_bookmarks(self):
"""Restore the default bookmarks for the current profile."""
retval = self.marionette.execute_async_script("""
+ let [resolve] = arguments;
Components.utils.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
// Default bookmarks.html file is stored inside omni.jar,
// so get it via a resource URI
let defaultBookmarks = 'chrome://browser/locale/bookmarks.html';
// Trigger the import of the default bookmarks
BookmarkHTMLUtils.importFromURL(defaultBookmarks, { replace: true })
- .then(() => marionetteScriptFinished(true))
- .catch(() => marionetteScriptFinished(false));
+ .then(() => resolve(true))
+ .catch(() => resolve(false));
""", script_timeout=10000)
if not retval:
raise MarionetteException("Restore Default Bookmarks failed")
# Browser history related helpers #
def get_all_urls_in_history(self):
@@ -106,21 +109,22 @@ class Places(BaseLib):
root.containerOpen = false;
return urls;
""")
def remove_all_history(self):
"""Remove all history items."""
retval = self.marionette.execute_async_script("""
+ let [resolve] = arguments;
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
PlacesUtils.history.clear()
- .then(() => marionetteScriptFinished(true))
- .catch(() => marionetteScriptFinished(false));
+ .then(() => resolve(true))
+ .catch(() => resolve(false));
""", script_timeout=10000)
if not retval:
raise MarionetteException("Removing all history failed")
def wait_for_visited(self, urls, callback):
"""Wait until all passed-in urls have been visited.
--- a/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/software_update.py
+++ b/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/software_update.py
@@ -376,25 +376,27 @@ class SoftwareUpdate(BaseLib):
def get_formatted_update_url(self, force=False):
"""Retrieve the formatted AUS update URL the update snippet is retrieved from.
:param force: Boolean flag to force an update check
:returns: The URL of the update snippet
"""
url = self.marionette.execute_async_script("""
+ let resolve = arguments[arguments.length - 1];
Components.utils.import("resource://gre/modules/UpdateUtils.jsm");
let res = UpdateUtils.formatUpdateURL(arguments[0]);
+
// Format the URL by replacing placeholders
// In 56 we switched the method to be async.
// For now, support both approaches.
if (res.then) {
- res.then(marionetteScriptFinished);
+ res.then(resolve);
} else {
- marionetteScriptFinished(res);
+ resolve(res);
}
""", script_args=[self.update_url])
if force:
if '?' in url:
url += '&'
else:
url += '?'
--- a/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/utils.py
+++ b/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/utils.py
@@ -48,33 +48,34 @@ class Utils(BaseLib):
more: https://dxr.mozilla.org/mozilla-central/source/browser/modules/Sanitizer.jsm
:param data_type: optional, Information specifying data to be sanitized
"""
with self.marionette.using_context('chrome'):
result = self.marionette.execute_async_script("""
+ let resolve = arguments[arguments.length - 1];
var {Sanitizer} = Components.utils.import("resource:///modules/Sanitizer.jsm", {});
var data_type = arguments[0];
// Apply options for what to sanitize
var itemsToClear = [];
for (var pref of Object.keys(data_type)) {
if (data_type[pref]) {
itemsToClear.push(pref);
}
};
// Sanitize and wait for the promise to resolve
Sanitizer.sanitize(itemsToClear).then(() => {
- marionetteScriptFinished(true);
+ resolve(true);
}, aError => {
- marionetteScriptFinished(false);
+ resolve(false);
});
""", script_args=[data_type])
if not result:
raise MarionetteException('Sanitizing of profile data failed.')
class Permissions(BaseLib):