From 519e4ad8afa77fb0d42a1fcb409b14ba15a8cbd6 Mon Sep 17 00:00:00 2001 From: Matthew Noorenberghe Date: Mon, 18 Apr 2016 14:21:11 -0700 Subject: [PATCH 1/5] Bug 1265202 - Back out changeset ef98cb11ba62 from bug 12506160 which used a signed XPI. MozReview-Commit-ID: 1xvljv37AKM --- .../mozscreenshots/extension/Makefile.in | 12 ++++++++++++ .../mozscreenshots/extension/install.rdf | 2 +- .../mozscreenshots/extension/moz.build | 4 ---- .../extension/mozscreenshots-signed.xpi | Bin 38341 -> 0 bytes 4 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 browser/tools/mozscreenshots/mozscreenshots/extension/Makefile.in delete mode 100644 browser/tools/mozscreenshots/mozscreenshots/extension/mozscreenshots-signed.xpi diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/Makefile.in b/browser/tools/mozscreenshots/mozscreenshots/extension/Makefile.in new file mode 100644 index 000000000000..f403837cddb0 --- /dev/null +++ b/browser/tools/mozscreenshots/mozscreenshots/extension/Makefile.in @@ -0,0 +1,12 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions +GENERATED_DIRS = $(TEST_EXTENSIONS_DIR) +XPI_PKGNAME = mozscreenshots@mozilla.org + +include $(topsrcdir)/config/rules.mk + +libs:: + (cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - $(XPI_NAME)) | (cd $(TEST_EXTENSIONS_DIR) && tar -xf -) diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/install.rdf b/browser/tools/mozscreenshots/mozscreenshots/extension/install.rdf index 4d6152461878..429a35840801 100644 --- a/browser/tools/mozscreenshots/mozscreenshots/extension/install.rdf +++ b/browser/tools/mozscreenshots/mozscreenshots/extension/install.rdf @@ -9,7 +9,7 @@ mozscreenshots@mozilla.org - 0.3.2 +#expand __MOZILLA_VERSION_U__ true diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/moz.build b/browser/tools/mozscreenshots/mozscreenshots/extension/moz.build index 0a271a4508e3..564f48ee4f02 100644 --- a/browser/tools/mozscreenshots/mozscreenshots/extension/moz.build +++ b/browser/tools/mozscreenshots/mozscreenshots/extension/moz.build @@ -15,7 +15,3 @@ FINAL_TARGET_PP_FILES += [ 'bootstrap.js', 'install.rdf', ] - -TEST_HARNESS_FILES.testing.mochitest.extensions += [ - 'mozscreenshots-signed.xpi', -] diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/mozscreenshots-signed.xpi b/browser/tools/mozscreenshots/mozscreenshots/extension/mozscreenshots-signed.xpi deleted file mode 100644 index af47dca31ea885380144d612e86b7cc6fbf5da2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38341 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 Date: Mon, 18 Apr 2016 14:21:53 -0700 Subject: [PATCH 2/5] Bug 1265202 - Install mozscreenshots as a temporary add-on. r=bgrins MozReview-Commit-ID: 2qw2KY1AHb0 --- browser/tools/mozscreenshots/head.js | 10 +++++++++- .../mozscreenshots/extension/Makefile.in | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/browser/tools/mozscreenshots/head.js b/browser/tools/mozscreenshots/head.js index c7261f5b579c..1d71a73033c8 100644 --- a/browser/tools/mozscreenshots/head.js +++ b/browser/tools/mozscreenshots/head.js @@ -5,12 +5,20 @@ "use strict"; const {AddonWatcher} = Cu.import("resource://gre/modules/AddonWatcher.jsm", {}); +const chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry); const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); +const EXTENSION_DIR = "chrome://mochitests/content/extensions/mozscreenshots/browser/"; + let TestRunner; -function setup() { +function* setup() { requestLongerTimeout(20); + info("installing extension temporarily"); + let chromeURL = Services.io.newURI(EXTENSION_DIR, null, null); + let dir = chromeRegistry.convertChromeURL(chromeURL).QueryInterface(Ci.nsIFileURL).file; + yield AddonManager.installTemporaryAddon(dir); + info("Checking for mozscreenshots extension"); return new Promise((resolve) => { AddonManager.getAddonByID("mozscreenshots@mozilla.org", function(aAddon) { diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/Makefile.in b/browser/tools/mozscreenshots/mozscreenshots/extension/Makefile.in index f403837cddb0..b0004aaa7b1d 100644 --- a/browser/tools/mozscreenshots/mozscreenshots/extension/Makefile.in +++ b/browser/tools/mozscreenshots/mozscreenshots/extension/Makefile.in @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions -GENERATED_DIRS = $(TEST_EXTENSIONS_DIR) +GENERATED_DIRS = $(TEST_EXTENSIONS_DIR) XPI_PKGNAME = mozscreenshots@mozilla.org include $(topsrcdir)/config/rules.mk From 5ddfedd1ccd39f5dd4d6a6a726ad63adc1d93a57 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Tue, 5 Apr 2016 08:59:47 -0700 Subject: [PATCH 3/5] Bug 1248846: [webext] Test that event callbacks and promises do not fire later than expected. r=aswan MozReview-Commit-ID: 4fpHc22txy --HG-- extra : rebase_source : 24ddf22e1f273f753adcd7962f9262919e30b69c --- .../components/extensions/ExtensionUtils.jsm | 6 +- .../test/xpcshell/test_ext_contexts.js | 129 ++++++++++++++++++ .../extensions/test/xpcshell/xpcshell.ini | 1 + 3 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_contexts.js diff --git a/toolkit/components/extensions/ExtensionUtils.jsm b/toolkit/components/extensions/ExtensionUtils.jsm index 07d0c9ea296a..bb8eb57a4f42 100644 --- a/toolkit/components/extensions/ExtensionUtils.jsm +++ b/toolkit/components/extensions/ExtensionUtils.jsm @@ -616,7 +616,7 @@ EventManager.prototype = { for (let callback of this.callbacks) { Promise.resolve(callback).then(callback => { if (this.context.unloaded) { - dump(`${this.name} event fired after context unloaded.`); + dump(`${this.name} event fired after context unloaded.\n`); } else if (this.callbacks.has(callback)) { this.context.runSafe(callback, ...args); } @@ -634,7 +634,7 @@ EventManager.prototype = { if (this.callbacks.size) { this.unregister(); } - this.callbacks = null; + this.callbacks = Object.freeze([]); }, api() { @@ -661,7 +661,7 @@ SingletonEventManager.prototype = { addListener(callback, ...args) { let wrappedCallback = (...args) => { if (this.context.unloaded) { - dump(`${this.name} event fired after context unloaded.`); + dump(`${this.name} event fired after context unloaded.\n`); } else if (this.unregister.has(callback)) { return callback(...args); } diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_contexts.js b/toolkit/components/extensions/test/xpcshell/test_ext_contexts.js new file mode 100644 index 000000000000..1a75ceb4fe06 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_contexts.js @@ -0,0 +1,129 @@ +"use strict"; + +const global = this; + +Cu.import("resource://gre/modules/Timer.jsm"); + +Cu.import("resource://gre/modules/ExtensionUtils.jsm"); +var { + BaseContext, + EventManager, + SingletonEventManager, +} = ExtensionUtils; + +class StubContext extends BaseContext { + constructor() { + super(); + this.sandbox = new Cu.Sandbox(global); + } + + get cloneScope() { + return this. sandbox; + } + + get extension() { + return {id: "test@web.extension"}; + } +} + + +add_task(function* test_post_unload_promises() { + let context = new StubContext(); + + let fail = result => { + ok(false, `Unexpected callback: ${result}`); + }; + + // Make sure promises resolve normally prior to unload. + let promises = [ + context.wrapPromise(Promise.resolve()), + context.wrapPromise(Promise.reject({message: ""})).catch(() => {}), + ]; + + yield Promise.all(promises); + + // Make sure promises that resolve after unload do not trigger + // resolution handlers. + + context.wrapPromise(Promise.resolve("resolved")) + .then(fail); + + context.wrapPromise(Promise.reject({message: "rejected"})) + .then(fail, fail); + + context.unload(); + + // The `setTimeout` ensures that we return to the event loop after + // promise resolution, which means we're guaranteed to return after + // any micro-tasks that get enqueued by the resolution handlers above. + yield new Promise(resolve => setTimeout(resolve, 0)); +}); + + +add_task(function* test_post_unload_listeners() { + let context = new StubContext(); + + let fireEvent; + let onEvent = new EventManager(context, "onEvent", fire => { + fireEvent = fire; + return () => {}; + }); + + let fireSingleton; + let onSingleton = new SingletonEventManager(context, "onSingleton", callback => { + fireSingleton = () => { + Promise.resolve().then(callback); + }; + return () => {}; + }); + + let fail = event => { + ok(false, `Unexpected event: ${event}`); + }; + + // Check that event listeners aren't called after they've been removed. + onEvent.addListener(fail); + onSingleton.addListener(fail); + + let promises = [ + new Promise(resolve => onEvent.addListener(resolve)), + new Promise(resolve => onSingleton.addListener(resolve)), + ]; + + fireEvent("onEvent"); + fireSingleton("onSingleton"); + + // Both `fireEvent` calls are dispatched asynchronously, so they won't + // have fired by this point. The `fail` listeners that we remove now + // should not be called, even though the events have already been + // enqueued. + onEvent.removeListener(fail); + onSingleton.removeListener(fail); + + // Wait for the remaining listeners to be called, which should always + // happen after the `fail` listeners would normally be called. + yield Promise.all(promises); + + // Check that event listeners aren't called after the context has + // unloaded. + onEvent.addListener(fail); + onSingleton.addListener(fail); + + // The EventManager `fire` callback always dispatches events + // asynchronously, so we need to test that any pending event callbacks + // aren't fired after the context unloads. We also need to test that + // any `fire` calls that happen *after* the context is unloaded also + // do not trigger callbacks. + fireEvent("onEvent"); + Promise.resolve("onEvent").then(fireEvent); + + fireSingleton("onSingleton"); + Promise.resolve("onSingleton").then(fireSingleton); + + context.unload(); + + // The `setTimeout` ensures that we return to the event loop after + // promise resolution, which means we're guaranteed to return after + // any micro-tasks that get enqueued by the resolution handlers above. + yield new Promise(resolve => setTimeout(resolve, 0)); +}); diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell.ini b/toolkit/components/extensions/test/xpcshell/xpcshell.ini index 7d8e709f58f3..79aa7a8300c0 100644 --- a/toolkit/components/extensions/test/xpcshell/xpcshell.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell.ini @@ -6,5 +6,6 @@ skip-if = toolkit == 'gonk' [test_locale_data.js] [test_locale_converter.js] +[test_ext_contexts.js] [test_ext_schemas.js] [test_getAPILevelForWindow.js] \ No newline at end of file From 28f6b2f7bca094b9ebbc7c3df8e66325e35f18d9 Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Mon, 18 Apr 2016 12:02:42 +0200 Subject: [PATCH 4/5] Bug 1250191 - Add a way to serialize JSON canonically. r=MattN Based on Alexis Metaireau's patch. MozReview-Commit-ID: 3H3SKWy5GgM --HG-- extra : rebase_source : e09660d0e031e72093546df684229aae616b5a72 extra : amend_source : 9c02da14cd5ff7255f5afc4a7adc15786ab0f8b6 --- toolkit/modules/CanonicalJSON.jsm | 62 ++++++++ toolkit/modules/moz.build | 1 + .../tests/xpcshell/test_CanonicalJSON.js | 146 ++++++++++++++++++ toolkit/modules/tests/xpcshell/xpcshell.ini | 1 + 4 files changed, 210 insertions(+) create mode 100644 toolkit/modules/CanonicalJSON.jsm create mode 100644 toolkit/modules/tests/xpcshell/test_CanonicalJSON.js diff --git a/toolkit/modules/CanonicalJSON.jsm b/toolkit/modules/CanonicalJSON.jsm new file mode 100644 index 000000000000..ae754ff3a371 --- /dev/null +++ b/toolkit/modules/CanonicalJSON.jsm @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +this.EXPORTED_SYMBOLS = ["CanonicalJSON"]; + +const { classes: Cc, interfaces: Ci, utils: Cu } = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "jsesc", + "resource://gre/modules/third_party/jsesc/jsesc.js"); + +this.CanonicalJSON = { + /** + * Return the canonical JSON form of the passed source, sorting all the object + * keys recursively. Note that this method will cause an infinite loop if + * cycles exist in the source (bug 1265357). + * + * @param source + * The elements to be serialized. + * + * The output will have all unicode chars escaped with the unicode codepoint + * as lowercase hexadecimal. + * + * @usage + * CanonicalJSON.stringify(listOfRecords); + **/ + stringify: function stringify(source) { + if (Array.isArray(source)) { + const jsonArray = source.map(x => typeof x === "undefined" ? null : x); + return `[${jsonArray.map(stringify).join(",")}]`; + } + + if (typeof source === "number") { + if (source === 0) { + return (Object.is(source, -0)) ? "-0" : "0"; + } + } + + // Leverage jsesc library, mainly for unicode escaping. + const toJSON = (input) => jsesc(input, {lowercaseHex: true, json: true}); + + if (typeof source !== "object" || source === null) { + return toJSON(source); + } + + // Dealing with objects, ordering keys. + const sortedKeys = Object.keys(source).sort(); + const lastIndex = sortedKeys.length - 1; + return sortedKeys.reduce((serial, key, index) => { + const value = source[key]; + // JSON.stringify drops keys with an undefined value. + if (typeof value === "undefined") { + return serial; + } + const jsonValue = value && value.toJSON ? value.toJSON() : value; + const suffix = index !== lastIndex ? "," : ""; + const escapedKey = toJSON(key); + return serial + `${escapedKey}:${stringify(jsonValue)}${suffix}`; + }, "{") + "}"; + }, +}; diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index 68c390cec143..56cde0422d0a 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -27,6 +27,7 @@ EXTRA_JS_MODULES += [ 'Battery.jsm', 'BinarySearch.jsm', 'BrowserUtils.jsm', + 'CanonicalJSON.jsm', 'CertUtils.jsm', 'CharsetMenu.jsm', 'ClientID.jsm', diff --git a/toolkit/modules/tests/xpcshell/test_CanonicalJSON.js b/toolkit/modules/tests/xpcshell/test_CanonicalJSON.js new file mode 100644 index 000000000000..fa61f5a0105b --- /dev/null +++ b/toolkit/modules/tests/xpcshell/test_CanonicalJSON.js @@ -0,0 +1,146 @@ +const { CanonicalJSON } = Components.utils.import("resource://gre/modules/CanonicalJSON.jsm"); + +function stringRepresentation(obj) { + const clone = JSON.parse(JSON.stringify(obj)); + return JSON.stringify(clone); +} + +add_task(function* test_canonicalJSON_should_preserve_array_order() { + const input = ['one', 'two', 'three']; + // No sorting should be done on arrays. + do_check_eq(CanonicalJSON.stringify(input), '["one","two","three"]'); +}); + +add_task(function* test_canonicalJSON_orders_object_keys() { + const input = [{ + b: ['two', 'three'], + a: ['zero', 'one'] + }]; + do_check_eq( + CanonicalJSON.stringify(input), + '[{"a":["zero","one"],"b":["two","three"]}]' + ); +}); + +add_task(function* test_canonicalJSON_orders_nested_object_keys() { + const input = [{ + b: {d: 'd', c: 'c'}, + a: {b: 'b', a: 'a'} + }]; + do_check_eq( + CanonicalJSON.stringify(input), + '[{"a":{"a":"a","b":"b"},"b":{"c":"c","d":"d"}}]' + ); +}); + +add_task(function* test_canonicalJSON_escapes_unicode_values() { + do_check_eq( + CanonicalJSON.stringify([{key: '✓'}]), + '[{"key":"\\u2713"}]' + ); + // Unicode codepoints should be output in lowercase. + do_check_eq( + CanonicalJSON.stringify([{key: 'é'}]), + '[{"key":"\\u00e9"}]' + ); +}); + +add_task(function* test_canonicalJSON_escapes_unicode_object_keys() { + do_check_eq( + CanonicalJSON.stringify([{'é': 'check'}]), + '[{"\\u00e9":"check"}]' + ); +}); + + +add_task(function* test_canonicalJSON_does_not_alter_input() { + const records = [ + {'foo': 'bar', 'last_modified': '12345', 'id': '1'}, + {'bar': 'baz', 'last_modified': '45678', 'id': '2'} + ]; + const serializedJSON = JSON.stringify(records); + CanonicalJSON.stringify(records); + do_check_eq(JSON.stringify(records), serializedJSON); +}); + + +add_task(function* test_canonicalJSON_preserves_data() { + const records = [ + {'foo': 'bar', 'last_modified': '12345', 'id': '1'}, + {'bar': 'baz', 'last_modified': '45678', 'id': '2'}, + ] + const serialized = CanonicalJSON.stringify(records); + const expected = '[{"foo":"bar","id":"1","last_modified":"12345"},' + + '{"bar":"baz","id":"2","last_modified":"45678"}]'; + do_check_eq(CanonicalJSON.stringify(records), expected); +}); + +add_task(function* test_canonicalJSON_does_not_add_space_separators() { + const records = [ + {'foo': 'bar', 'last_modified': '12345', 'id': '1'}, + {'bar': 'baz', 'last_modified': '45678', 'id': '2'}, + ] + const serialized = CanonicalJSON.stringify(records); + do_check_false(serialized.includes(" ")); +}); + +add_task(function* test_canonicalJSON_serializes_empty_object() { + do_check_eq(CanonicalJSON.stringify({}), "{}"); +}); + +add_task(function* test_canonicalJSON_serializes_empty_array() { + do_check_eq(CanonicalJSON.stringify([]), "[]"); +}); + +add_task(function* test_canonicalJSON_serializes_NaN() { + do_check_eq(CanonicalJSON.stringify(NaN), "null"); +}); + +add_task(function* test_canonicalJSON_serializes_inf() { + // This isn't part of the JSON standard. + do_check_eq(CanonicalJSON.stringify(Infinity), "null"); +}); + + +add_task(function* test_canonicalJSON_serializes_empty_string() { + do_check_eq(CanonicalJSON.stringify(""), '""'); +}); + +add_task(function* test_canonicalJSON_escapes_backslashes() { + do_check_eq(CanonicalJSON.stringify("This\\and this"), '"This\\\\and this"'); +}); + +add_task(function* test_canonicalJSON_handles_signed_zeros() { + // do_check_eq doesn't support comparison of -0 and 0 properly. + do_check_true(CanonicalJSON.stringify(-0) === '-0'); + do_check_true(CanonicalJSON.stringify(0) === '0'); +}); + + +add_task(function* test_canonicalJSON_with_deeply_nested_dicts() { + const records = [{ + 'a': { + 'b': 'b', + 'a': 'a', + 'c': { + 'b': 'b', + 'a': 'a', + 'c': ['b', 'a', 'c'], + 'd': {'b': 'b', 'a': 'a'}, + 'id': '1', + 'e': 1, + 'f': [2, 3, 1], + 'g': {2: 2, 3: 3, 1: { + 'b': 'b', 'a': 'a', 'c': 'c'}}}}, + 'id': '1'}] + const expected = + '[{"a":{"a":"a","b":"b","c":{"a":"a","b":"b","c":["b","a","c"],' + + '"d":{"a":"a","b":"b"},"e":1,"f":[2,3,1],"g":{' + + '"1":{"a":"a","b":"b","c":"c"},"2":2,"3":3},"id":"1"}},"id":"1"}]'; + + do_check_eq(CanonicalJSON.stringify(records), expected); +}); + +function run_test() { + run_next_test(); +} diff --git a/toolkit/modules/tests/xpcshell/xpcshell.ini b/toolkit/modules/tests/xpcshell/xpcshell.ini index 279b336b77f5..e4cdcbc98efe 100644 --- a/toolkit/modules/tests/xpcshell/xpcshell.ini +++ b/toolkit/modules/tests/xpcshell/xpcshell.ini @@ -11,6 +11,7 @@ support-files = [test_BinarySearch.js] skip-if = toolkit == 'android' +[test_CanonicalJSON.js] [test_client_id.js] skip-if = toolkit == 'android' [test_DeferredTask.js] From ea625e931363295551afa9223b56e81de7968575 Mon Sep 17 00:00:00 2001 From: Andy McKay Date: Mon, 18 Apr 2016 16:41:07 -0700 Subject: [PATCH 5/5] Bug 1127476 - Point plugins to update check not blocklist page. r=aswan MozReview-Commit-ID: 6CgvYYTWp3J --- toolkit/mozapps/extensions/content/extensions.xml | 2 +- toolkit/mozapps/extensions/test/browser/browser_list.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/toolkit/mozapps/extensions/content/extensions.xml b/toolkit/mozapps/extensions/content/extensions.xml index 1ef99c0abe21..17599b894a13 100644 --- a/toolkit/mozapps/extensions/content/extensions.xml +++ b/toolkit/mozapps/extensions/content/extensions.xml @@ -1293,7 +1293,7 @@ [this.mAddon.name], 1 ); this._errorLink.value = gStrings.ext.GetStringFromName("notification.vulnerableUpdatable.link"); - this._errorLink.href = this.mAddon.blocklistURL; + this._errorLink.href = Services.urlFormatter.formatURLPref("plugins.update.url"); this._errorLink.hidden = false; } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) { this.setAttribute("notification", "error"); diff --git a/toolkit/mozapps/extensions/test/browser/browser_list.js b/toolkit/mozapps/extensions/test/browser/browser_list.js index 7338e7c3b540..b45467ef26f9 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_list.js +++ b/toolkit/mozapps/extensions/test/browser/browser_list.js @@ -88,7 +88,6 @@ add_task(function*() { blocklistState: Ci.nsIBlocklistService.STATE_OUTDATED, }, { id: "addon8@tests.mozilla.org", - blocklistURL: "http://example.com/addon8@tests.mozilla.org", name: "Test add-on 8", blocklistState: Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE, }, { @@ -395,7 +394,7 @@ add_task(function*() { is(get_node(addon, "error").textContent, "Test add-on 8 is known to be vulnerable and should be updated.", "Error message should be correct"); is_element_visible(get_node(addon, "error-link"), "Error link should be visible"); is(get_node(addon, "error-link").value, "Update Now", "Error link text should be correct"); - is(get_node(addon, "error-link").href, "http://example.com/addon8@tests.mozilla.org", "Error link should be correct"); + is(get_node(addon, "error-link").href, gPluginURL, "Error link should be correct"); is_element_hidden(get_node(addon, "pending"), "Pending message should be hidden"); info("Addon 9");