зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset a3c50d608b69 (bug 1308271) for various test failures. r=backout on a CLOSED TREE
--HG-- rename : browser/extensions/webcompat/test/browser.ini => browser/extensions/webcompat/test/browser/browser.ini rename : browser/extensions/webcompat/test/browser_check_installed.js => browser/extensions/webcompat/test/browser/browser_check_installed.js
This commit is contained in:
Родитель
2663bd16e0
Коммит
00f044376d
|
@ -2,105 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
"use strict";
|
||||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
function startup() {}
|
||||||
|
function shutdown() {}
|
||||||
const PREF_BRANCH = "extensions.webcompat.";
|
function install() {}
|
||||||
const PREF_DEFAULTS = {perform_ua_overrides: true};
|
function uninstall() {}
|
||||||
|
|
||||||
const UA_ENABLE_PREF_NAME = "extensions.webcompat.perform_ua_overrides";
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "UAOverrider", "chrome://webcompat/content/lib/ua_overrider.jsm");
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "UAOverrides", "chrome://webcompat/content/data/ua_overrides.jsm");
|
|
||||||
|
|
||||||
let overrider;
|
|
||||||
let tabUpdateHandler;
|
|
||||||
|
|
||||||
function UAEnablePrefObserver() {
|
|
||||||
let isEnabled = Services.prefs.getBoolPref(UA_ENABLE_PREF_NAME);
|
|
||||||
if (isEnabled && !overrider) {
|
|
||||||
overrider = new UAOverrider(UAOverrides);
|
|
||||||
overrider.init();
|
|
||||||
} else if (!isEnabled && overrider) {
|
|
||||||
overrider.uninit();
|
|
||||||
overrider = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setDefaultPrefs() {
|
|
||||||
const branch = Services.prefs.getDefaultBranch(PREF_BRANCH);
|
|
||||||
for (const [key, val] of Object.entries(PREF_DEFAULTS)) {
|
|
||||||
// If someone beat us to setting a default, don't overwrite it.
|
|
||||||
if (branch.getPrefType(key) !== branch.PREF_INVALID) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (typeof val) {
|
|
||||||
case "boolean":
|
|
||||||
branch.setBoolPref(key, val);
|
|
||||||
break;
|
|
||||||
case "number":
|
|
||||||
branch.setIntPref(key, val);
|
|
||||||
break;
|
|
||||||
case "string":
|
|
||||||
branch.setCharPref(key, val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.install = function() {};
|
|
||||||
this.uninstall = function() {};
|
|
||||||
|
|
||||||
this.startup = function({webExtension}) {
|
|
||||||
setDefaultPrefs();
|
|
||||||
|
|
||||||
// Intentionally reset the preference on every browser restart to avoid site
|
|
||||||
// breakage by accidentally toggled preferences or by leaving it off after
|
|
||||||
// debugging a site.
|
|
||||||
Services.prefs.clearUserPref(UA_ENABLE_PREF_NAME);
|
|
||||||
Services.prefs.addObserver(UA_ENABLE_PREF_NAME, UAEnablePrefObserver, false);
|
|
||||||
|
|
||||||
overrider = new UAOverrider(UAOverrides);
|
|
||||||
overrider.init();
|
|
||||||
|
|
||||||
// Initialize the embedded WebExtension that gets used to log a notifications
|
|
||||||
// about altered User Agents into the sites developer console.
|
|
||||||
// Per default, we can only log into the Browser Console, which is not very
|
|
||||||
// helpful in our use case since we want to talk to the site's developers.
|
|
||||||
// Note that this is only a temporary solution, which will get replaced
|
|
||||||
// by a more advanced implementation that will include some additional
|
|
||||||
// information like the reason why we override the User Agent.
|
|
||||||
webExtension.startup().then((api) => {
|
|
||||||
const {browser} = api;
|
|
||||||
|
|
||||||
// In tablog.js, we have a listener to tabs.onUpdated. That listener sends
|
|
||||||
// a message to us, containing the URL that has been loaded. Here, we check
|
|
||||||
// if the URL is one of the URLs we store User Agent overrides for and if
|
|
||||||
// so, we return true back to the background script, which in turn displays
|
|
||||||
// a message in the site's developer console.
|
|
||||||
tabUpdateHandler = function(message, sender, sendResponse) {
|
|
||||||
try {
|
|
||||||
if (overrider) {
|
|
||||||
let hasUAOverride = overrider.hasUAForURIInCache(Services.io.newURI(message.url, null, null));
|
|
||||||
sendResponse({reply: hasUAOverride});
|
|
||||||
}
|
|
||||||
} catch (exception) {
|
|
||||||
sendResponse({reply: false});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
browser.runtime.onMessage.addListener(tabUpdateHandler);
|
|
||||||
return;
|
|
||||||
}).catch((reason) => {
|
|
||||||
console.log(reason);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.shutdown = function() {
|
|
||||||
Services.prefs.removeObserver(UA_ENABLE_PREF_NAME, UAEnablePrefObserver);
|
|
||||||
|
|
||||||
if (overrider) {
|
|
||||||
overrider.uninit();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
/* 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 is an array of objects that specify user agent overrides. Each object
|
|
||||||
* can have three attributes:
|
|
||||||
*
|
|
||||||
* * `baseDomain`, required: The base domain that further checks and user
|
|
||||||
* agents override are applied to. This does not include subdomains.
|
|
||||||
* * `uriMatcher`: Function that gets the requested URI passed in the first
|
|
||||||
* argument and needs to return boolean whether or not the override should
|
|
||||||
* be applied. If not provided, the user agent override will be applied
|
|
||||||
* every time.
|
|
||||||
* * `uaTransformer`, required: Function that gets the original Firefox user
|
|
||||||
* agent passed as its first argument and needs to return a string that
|
|
||||||
* will be used as the the user agent for this URI.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
*
|
|
||||||
* Gets applied for all requests to mozilla.org and subdomains:
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* {
|
|
||||||
* baseDomain: "mozilla.org",
|
|
||||||
* uaTransformer: (originalUA) => `Ohai Mozilla, it's me, ${originalUA}`
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Applies to *.example.com/app/*:
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* {
|
|
||||||
* baseDomain: "example.com",
|
|
||||||
* uriMatcher: (uri) => uri.includes("/app/"),
|
|
||||||
* uaTransformer: (originalUA) => originalUA.replace("Firefox", "Otherfox")
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
|
|
||||||
const UAOverrides = [
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a dummy override that applies a Chrome UA to a dummy site that
|
|
||||||
* blocks all browsers but Chrome.
|
|
||||||
*
|
|
||||||
* This was only put in place to allow QA to test this system addon on an
|
|
||||||
* actual site, since we were not able to find a proper override in time.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
baseDomain: "schub.io",
|
|
||||||
uriMatcher: (uri) => uri.includes("webcompat-ua-dummy.schub.io"),
|
|
||||||
uaTransformer: (originalUA) => {
|
|
||||||
let prefix = originalUA.substr(0, originalUA.indexOf(")") + 1);
|
|
||||||
return `${prefix} AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["UAOverrides"]; /* exported UAOverrides */
|
|
|
@ -1,121 +0,0 @@
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
|
|
||||||
const DefaultUA = Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).userAgent;
|
|
||||||
const NS_HTTP_ON_USERAGENT_REQUEST_TOPIC = "http-on-useragent-request";
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "eTLDService", "@mozilla.org/network/effective-tld-service;1", "nsIEffectiveTLDService");
|
|
||||||
|
|
||||||
class UAOverrider {
|
|
||||||
constructor(overrides) {
|
|
||||||
this._overrides = {};
|
|
||||||
this._overrideForURICache = new Map();
|
|
||||||
|
|
||||||
this.initOverrides(overrides);
|
|
||||||
}
|
|
||||||
|
|
||||||
initOverrides(overrides) {
|
|
||||||
for (let override of overrides) {
|
|
||||||
if (!this._overrides[override.baseDomain]) {
|
|
||||||
this._overrides[override.baseDomain] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!override.uriMatcher) {
|
|
||||||
override.uriMatcher = () => true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._overrides[override.baseDomain].push(override);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
Services.obs.addObserver(this, NS_HTTP_ON_USERAGENT_REQUEST_TOPIC, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
uninit() {
|
|
||||||
Services.obs.removeObserver(this, NS_HTTP_ON_USERAGENT_REQUEST_TOPIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
observe(subject, topic) {
|
|
||||||
if (topic !== NS_HTTP_ON_USERAGENT_REQUEST_TOPIC) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let channel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
|
|
||||||
let uaOverride = this.getUAForURI(channel.URI);
|
|
||||||
|
|
||||||
if (uaOverride) {
|
|
||||||
channel.setRequestHeader("User-Agent", uaOverride, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getUAForURI(uri) {
|
|
||||||
let bareUri = uri.specIgnoringRef;
|
|
||||||
if (this._overrideForURICache.has(bareUri)) {
|
|
||||||
// Although the cache could have an entry to a bareUri, `false` is also
|
|
||||||
// a value that could be cached. A `false` cache entry means that there
|
|
||||||
// is no override for this URI.
|
|
||||||
// We cache these to avoid having to walk through all overrides to see
|
|
||||||
// if a domain matches.
|
|
||||||
let cachedUA = this._overrideForURICache.get(bareUri);
|
|
||||||
return (cachedUA ? cachedUA : DefaultUA);
|
|
||||||
}
|
|
||||||
|
|
||||||
let finalUA = this.lookupUAOverride(uri);
|
|
||||||
this._overrideForURICache.set(bareUri, finalUA);
|
|
||||||
|
|
||||||
return finalUA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function gets called from within the embedded webextension to check
|
|
||||||
* if the current site has been overriden or not. We only check the cached
|
|
||||||
* URI list here, but that's safe in our case since the tabUpdateHandler will
|
|
||||||
* always run after our message observer.
|
|
||||||
*/
|
|
||||||
hasUAForURIInCache(uri) {
|
|
||||||
let bareUri = uri.specIgnoringRef;
|
|
||||||
if (this._overrideForURICache.has(bareUri)) {
|
|
||||||
return !!this._overrideForURICache.get(bareUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function returns a User Agent based on the URI passed into. All
|
|
||||||
* override rules are defined in data/ua_overrides.jsm and the required format
|
|
||||||
* is explained there.
|
|
||||||
*
|
|
||||||
* Since it is expected and designed to have more than one override per base
|
|
||||||
* domain, we have to loop over this._overrides[baseDomain], which contains
|
|
||||||
* all available overrides.
|
|
||||||
*
|
|
||||||
* If the uriMatcher function returns true, the uaTransformer function gets
|
|
||||||
* called and its result will be used as the Use Agent for the current
|
|
||||||
* request.
|
|
||||||
*
|
|
||||||
* If there are more than one possible overrides, that is if two or more
|
|
||||||
* uriMatchers would return true, the first one gets applied.
|
|
||||||
*/
|
|
||||||
lookupUAOverride(uri) {
|
|
||||||
let baseDomain = eTLDService.getBaseDomain(uri);
|
|
||||||
if (this._overrides[baseDomain]) {
|
|
||||||
for (let uaOverride of this._overrides[baseDomain]) {
|
|
||||||
if (uaOverride.uriMatcher(uri.specIgnoringRef)) {
|
|
||||||
return uaOverride.uaTransformer(DefaultUA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["UAOverrider"]; /* exported UAOverrider */
|
|
|
@ -28,8 +28,5 @@
|
||||||
<!-- Front End MetaData -->
|
<!-- Front End MetaData -->
|
||||||
<em:name>Web Compat</em:name>
|
<em:name>Web Compat</em:name>
|
||||||
<em:description>Urgent post-release fixes for web compatibility.</em:description>
|
<em:description>Urgent post-release fixes for web compatibility.</em:description>
|
||||||
|
|
||||||
<!-- Embed WebExtension -->
|
|
||||||
<em:hasEmbeddedWebExtension>true</em:hasEmbeddedWebExtension>
|
|
||||||
</Description>
|
</Description>
|
||||||
</RDF>
|
</RDF>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
[features/webcompat@mozilla.org] chrome.jar:
|
|
||||||
% content webcompat %content/
|
|
||||||
content/ (content/*)
|
|
||||||
|
|
||||||
[features/webcompat@mozilla.org] webextension.jar:
|
|
||||||
. (webextension/*)
|
|
|
@ -15,5 +15,4 @@ FINAL_TARGET_PP_FILES.features['webcompat@mozilla.org'] += [
|
||||||
'install.rdf.in'
|
'install.rdf.in'
|
||||||
]
|
]
|
||||||
|
|
||||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
|
||||||
JAR_MANIFESTS += ['jar.mn']
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"extends": [
|
||||||
|
"../../../../../testing/mochitest/browser.eslintrc.js"
|
||||||
|
]
|
||||||
|
};
|
|
@ -1,4 +1,3 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
|
||||||
[browser_check_installed.js]
|
[browser_check_installed.js]
|
||||||
[browser_overrider.js]
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
add_task(function* test_enabled() {
|
||||||
|
let addon = yield new Promise(
|
||||||
|
resolve => AddonManager.getAddonByID("webcompat@mozilla.org", resolve)
|
||||||
|
);
|
||||||
|
isnot(addon, null, "Check addon exists");
|
||||||
|
is(addon.version, "1.0", "Check version");
|
||||||
|
is(addon.name, "Web Compat", "Check name");
|
||||||
|
ok(addon.isCompatible, "Check application compatibility");
|
||||||
|
ok(!addon.appDisabled, "Check not app disabled");
|
||||||
|
ok(addon.isActive, "Check addon is active");
|
||||||
|
});
|
|
@ -1,19 +0,0 @@
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
/* global AddonManager */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
add_task(function* installed() {
|
|
||||||
let addon = yield new Promise(
|
|
||||||
(resolve) => AddonManager.getAddonByID("webcompat@mozilla.org", resolve)
|
|
||||||
);
|
|
||||||
isnot(addon, null, "Webcompat addon should exist");
|
|
||||||
is(addon.name, "Web Compat");
|
|
||||||
ok(addon.isCompatible, "Webcompat addon is compatible with Firefox");
|
|
||||||
ok(!addon.appDisabled, "Webcompat addon is not app disabled");
|
|
||||||
ok(addon.isActive, "Webcompat addon is active");
|
|
||||||
is(addon.type, "extension", "Webcompat addon is type extension");
|
|
||||||
});
|
|
|
@ -1,40 +0,0 @@
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
/* globals XPCOMUtils, UAOverrider, IOService */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "UAOverrider", "chrome://webcompat/content/lib/ua_overrider.js");
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "IOService", "@mozilla.org/network/io-service;1", "nsIIOService");
|
|
||||||
|
|
||||||
function getnsIURI(uri) {
|
|
||||||
return IOService.newURI(uri, "utf-8", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
add_task(function test() {
|
|
||||||
let overrider = new UAOverrider([
|
|
||||||
{
|
|
||||||
baseDomain: "example.org",
|
|
||||||
uaTransformer: () => "Test UA"
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
let finalUA = overrider.getUAForURI(getnsIURI("http://www.example.org/foobar/"));
|
|
||||||
is(finalUA, "Test UA", "Overrides the UA without a matcher function");
|
|
||||||
});
|
|
||||||
|
|
||||||
add_task(function test() {
|
|
||||||
let overrider = new UAOverrider([
|
|
||||||
{
|
|
||||||
baseDomain: "example.org",
|
|
||||||
uriMatcher: () => false,
|
|
||||||
uaTransformer: () => "Test UA"
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
let finalUA = overrider.getUAForURI(getnsIURI("http://www.example.org/foobar/"));
|
|
||||||
isnot(finalUA, "Test UA", "Does not override the UA with the matcher returning false");
|
|
||||||
});
|
|
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
"description": "WebCompat Go Faster Web Extension",
|
|
||||||
"manifest_version": 2,
|
|
||||||
"name": "webcompat-extension",
|
|
||||||
"version": "1.0",
|
|
||||||
|
|
||||||
"permissions": [
|
|
||||||
"tabs",
|
|
||||||
"<all_urls>"
|
|
||||||
],
|
|
||||||
|
|
||||||
"background": {
|
|
||||||
"scripts": ["tablog.js"]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const consoleLogScript = 'console.log("The user agent has been overridden for compatibility reasons.");';
|
|
||||||
|
|
||||||
/* This function handle tab updates.
|
|
||||||
* While changeInfo.status is loading and there is url
|
|
||||||
* Send tab url to ua_overrider.js to query if needs to print web console log.
|
|
||||||
*/
|
|
||||||
function handleUpdated(tabId, changeInfo, tabInfo) {
|
|
||||||
if (changeInfo.status === "loading" && changeInfo.url) {
|
|
||||||
chrome.runtime.sendMessage({url: changeInfo.url}, (message) => {
|
|
||||||
if (message.reply) {
|
|
||||||
chrome.tabs.executeScript(tabId, {code: consoleLogScript});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.tabs.onUpdated.addListener(handleUpdated);
|
|
Загрузка…
Ссылка в новой задаче