Bug 1544359 - Fixed report site issue extension: added marfeel and mobify support, fixed labels being passed to the server. r=twisniewski,Gijs, a=jcristau
Fixed report site issue: added marfeel and mobify support, fixed labels being passed to the server
Differential Revision:
https://phabricator.services.mozilla.com/D33018
--- a/browser/extensions/report-site-issue/background.js
+++ b/browser/extensions/report-site-issue/background.js
@@ -10,16 +10,18 @@ const Config = {
newIssueEndpoint: "https://webcompat.com/issues/new",
newIssueEndpointPref: "newIssueEndpoint",
screenshotFormat: {
format: "jpeg",
quality: 75,
},
};
+const FRAMEWORK_KEYS = ["hasFastClick", "hasMobify", "hasMarfeel"];
+
browser.pageActionExtras.setLabelForHistogram("webcompat");
browser.pageAction.onClicked.addListener(tab => {
return getWebCompatInfoForTab(tab).then(
info => {
return openWebCompatTab(info);
},
err => {
@@ -56,53 +58,77 @@ function hasFastClickPageScript() {
}
} catch (_) {
}
}
return false;
}
-function checkForFastClick(tabId) {
+function hasMobifyPageScript() {
+ const win = window.wrappedJSObject;
+ return !!(win.Mobify && win.Mobify.Tag);
+}
+
+function hasMarfeelPageScript() {
+ const win = window.wrappedJSObject;
+ return !!win.marfeel;
+}
+
+function checkForFrameworks(tabId) {
return browser.tabs.executeScript(tabId, {
- code: `${hasFastClickPageScript};hasFastClickPageScript()`,
- }).then(([hasFastClick]) => hasFastClick).catch(() => false);
+ code: `
+ (function() {
+ ${hasFastClickPageScript};
+ ${hasMobifyPageScript};
+ ${hasMarfeelPageScript};
+
+ const result = {
+ hasFastClick: hasFastClickPageScript(),
+ hasMobify: hasMobifyPageScript(),
+ hasMarfeel: hasMarfeelPageScript(),
+ }
+
+ return result;
+ })();
+ `,
+ }).then(([results]) => results).catch(() => false);
}
function getWebCompatInfoForTab(tab) {
const {id, url} = tab;
return Promise.all([
browser.browserInfo.getBlockList(),
browser.browserInfo.getBuildID(),
browser.browserInfo.getGraphicsPrefs(),
browser.browserInfo.getUpdateChannel(),
browser.browserInfo.hasTouchScreen(),
browser.tabExtras.getWebcompatInfo(id),
- checkForFastClick(id),
+ checkForFrameworks(id),
browser.tabs.captureTab(id, Config.screenshotFormat).catch(e => {
console.error("WebCompat Reporter: getting a screenshot failed", e);
return Promise.resolve(undefined);
}),
]).then(([blockList, buildID, graphicsPrefs, channel, hasTouchScreen,
- frameInfo, hasFastClick, screenshot]) => {
+ frameInfo, frameworks, screenshot]) => {
if (channel !== "linux") {
delete graphicsPrefs["layers.acceleration.force-enabled"];
}
const consoleLog = frameInfo.log;
delete frameInfo.log;
return Object.assign(frameInfo, {
tabId: id,
blockList,
details: Object.assign(graphicsPrefs, {
buildID,
channel,
consoleLog,
- hasFastClick,
+ frameworks,
hasTouchScreen,
"mixed active content blocked": frameInfo.hasMixedActiveContentBlocked,
"mixed passive content blocked": frameInfo.hasMixedDisplayContentBlocked,
"tracking content blocked": frameInfo.hasTrackingContentBlocked ?
`true (${blockList})` : "false",
}),
screenshot,
url,
@@ -125,28 +151,32 @@ async function openWebCompatTab(compatIn
const url = new URL(Config.newIssueEndpoint);
const {details} = compatInfo;
const params = {
url: `${compatInfo.url}`,
utm_source: "desktop-reporter",
utm_campaign: "report-site-issue-button",
src: "desktop-reporter",
details,
- label: [],
+ extra_labels: [],
};
- if (details.hasFastClick) {
- params.label.push("type-fastclick");
- } else {
- delete details.hasFastClick;
+
+ for (let framework of FRAMEWORK_KEYS) {
+ if (details.frameworks[framework]) {
+ params.details[framework] = true;
+ params.extra_labels.push(framework.replace(/^has/, "type-").toLowerCase());
+ }
}
+ delete details.frameworks;
+
if (details["gfx.webrender.all"] || details["gfx.webrender.enabled"]) {
- params.label.push("type-webrender-enabled");
+ params.extra_labels.push("type-webrender-enabled");
}
if (compatInfo.hasTrackingContentBlocked) {
- params.label.push(`type-tracking-protection-${compatInfo.blockList}`);
+ params.extra_labels.push(`type-tracking-protection-${compatInfo.blockList}`);
}
const tab = await browser.tabs.create({url: "about:blank"});
const json = stripNonASCIIChars(JSON.stringify(params));
await browser.tabExtras.loadURIWithPostData(tab.id, url.href, json,
"application/json");
await browser.tabs.executeScript(tab.id, {
runAt: "document_end",
--- a/browser/extensions/report-site-issue/test/browser/browser.ini
+++ b/browser/extensions/report-site-issue/test/browser/browser.ini
@@ -1,11 +1,11 @@
[DEFAULT]
support-files =
- fastclick1.html
- fastclick2.html
+ frameworks.html
+ fastclick.html
head.js
test.html
webcompat.html
[browser_disabled_cleanup.js]
[browser_button_state.js]
[browser_report_site_issue.js]
--- a/browser/extensions/report-site-issue/test/browser/browser_report_site_issue.js
+++ b/browser/extensions/report-site-issue/test/browser/browser_report_site_issue.js
@@ -74,16 +74,18 @@ add_task(async function test_opened_page
ok(Array.isArray(details.consoleLog), "Details has a consoleLog array.");
ok(details.consoleLog[0].match(/console\.log\(null\)[\s\S]*test.html:\d+:\d+/m), "Can handle degenerate console logs");
ok(details.consoleLog[1].match(/console\.error\(colored message\)[\s\S]*test.html:\d+:\d+/m), "Can handle fancy console logs");
ok(details.consoleLog[2].match(/document\.access is undefined[\s\S]*test.html:\d+:\d+/m), "Script errors are logged");
ok(typeof details.buildID == "string", "Details has a buildID string.");
ok(typeof details.channel == "string", "Details has a channel string.");
ok(typeof details.hasTouchScreen == "boolean", "Details has a hasTouchScreen flag.");
ok(typeof details.hasFastClick == "undefined", "Details does not have FastClick if not found.");
+ ok(typeof details.hasMobify == "undefined", "Details does not have Mobify if not found.");
+ ok(typeof details.hasMarfeel == "undefined", "Details does not have Marfeel if not found.");
ok(typeof details["mixed active content blocked"] == "boolean", "Details has a mixed active content blocked flag.");
ok(typeof details["mixed passive content blocked"] == "boolean", "Details has a mixed passive content blocked flag.");
ok(typeof details["tracking content blocked"] == "string", "Details has a tracking content blocked string.");
ok(typeof details["gfx.webrender.all"] == "boolean", "Details has gfx.webrender.all.");
ok(typeof details["gfx.webrender.blob-images"] == "boolean", "Details has gfx.webrender.blob-images.");
ok(typeof details["gfx.webrender.enabled"] == "boolean", "Details has gfx.webrender.enabled.");
ok(typeof details["image.mem.shared"] == "boolean", "Details has image.mem.shared.");
@@ -93,39 +95,59 @@ add_task(async function test_opened_page
ok(bgUrl.startsWith("data:image/jpeg;base64,"), "A jpeg screenshot was successfully postMessaged");
await isGreen(bgUrl);
});
BrowserTestUtils.removeTab(tab2);
BrowserTestUtils.removeTab(tab1);
});
-add_task(async function test_fastclick_detection1() {
- let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, FASTCLICK_TEST_PAGE1);
+add_task(async function test_framework_detection() {
+ let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, FRAMEWORKS_TEST_PAGE);
+ let tab2 = await clickToReportAndAwaitReportTabLoad();
+
+ await ContentTask.spawn(tab2.linkedBrowser, {}, async function(args) {
+ let doc = content.document;
+ let detailsParam = doc.getElementById("details").innerText;
+ const details = JSON.parse(detailsParam);
+ ok(typeof details == "object", "Details param is a stringified JSON object.");
+ is(details.hasFastClick, true, "FastClick was found.");
+ is(details.hasMobify, true, "Mobify was found.");
+ is(details.hasMarfeel, true, "Marfeel was found.");
+ });
+
+ BrowserTestUtils.removeTab(tab2);
+ BrowserTestUtils.removeTab(tab1);
+});
+
+add_task(async function test_fastclick_detection() {
+ let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, FASTCLICK_TEST_PAGE);
let tab2 = await clickToReportAndAwaitReportTabLoad();
await ContentTask.spawn(tab2.linkedBrowser, {}, async function(args) {
let doc = content.document;
let detailsParam = doc.getElementById("details").innerText;
const details = JSON.parse(detailsParam);
ok(typeof details == "object", "Details param is a stringified JSON object.");
is(details.hasFastClick, true, "FastClick was found.");
});
BrowserTestUtils.removeTab(tab2);
BrowserTestUtils.removeTab(tab1);
});
-add_task(async function test_fastclick_detection2() {
- let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, FASTCLICK_TEST_PAGE2);
+add_task(async function test_framework_label() {
+ let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, FRAMEWORKS_TEST_PAGE);
let tab2 = await clickToReportAndAwaitReportTabLoad();
await ContentTask.spawn(tab2.linkedBrowser, {}, async function(args) {
let doc = content.document;
- let detailsParam = doc.getElementById("details").innerText;
- const details = JSON.parse(detailsParam);
- ok(typeof details == "object", "Details param is a stringified JSON object.");
- is(details.hasFastClick, true, "FastClick was found.");
+ let labelParam = doc.getElementById("label").innerText;
+ const label = JSON.parse(labelParam);
+ ok(typeof label == "object", "Label param is a stringified JSON object.");
+ is(label.includes("type-fastclick"), true, "FastClick was found.");
+ is(label.includes("type-mobify"), true, "Mobify was found.");
+ is(label.includes("type-marfeel"), true, "Marfeel was found.");
});
BrowserTestUtils.removeTab(tab2);
BrowserTestUtils.removeTab(tab1);
});
rename from browser/extensions/report-site-issue/test/browser/fastclick2.html
rename to browser/extensions/report-site-issue/test/browser/fastclick.html
rename from browser/extensions/report-site-issue/test/browser/fastclick1.html
rename to browser/extensions/report-site-issue/test/browser/frameworks.html
--- a/browser/extensions/report-site-issue/test/browser/fastclick1.html
+++ b/browser/extensions/report-site-issue/test/browser/frameworks.html
@@ -1,6 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8">
<script>
"use strict";
function FastClick() {}
+ function marfeel() {}
+ var Mobify = {Tag: "something"};
</script>
--- a/browser/extensions/report-site-issue/test/browser/head.js
+++ b/browser/extensions/report-site-issue/test/browser/head.js
@@ -5,18 +5,18 @@ ChromeUtils.defineModuleGetter(this, "Ad
const {Management} = ChromeUtils.import("resource://gre/modules/Extension.jsm", null);
const PREF_WC_REPORTER_ENABLED = "extensions.webcompat-reporter.enabled";
const PREF_WC_REPORTER_ENDPOINT = "extensions.webcompat-reporter.newIssueEndpoint";
const TEST_ROOT = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
const TEST_PAGE = TEST_ROOT + "test.html";
-const FASTCLICK_TEST_PAGE1 = TEST_ROOT + "fastclick1.html";
-const FASTCLICK_TEST_PAGE2 = TEST_ROOT + "fastclick2.html";
+const FRAMEWORKS_TEST_PAGE = TEST_ROOT + "frameworks.html";
+const FASTCLICK_TEST_PAGE = TEST_ROOT + "fastclick.html";
const NEW_ISSUE_PAGE = TEST_ROOT + "webcompat.html";
const WC_ADDON_ID = "webcompat-reporter@mozilla.org";
const WC_PAGE_ACTION_ID = "webcompat-reporter_mozilla_org";
const WC_PAGE_ACTION_PANEL_ID = "pageAction-panel-webcompat-reporter_mozilla_org";
const WC_PAGE_ACTION_URLBAR_ID = "pageAction-urlbar-webcompat-reporter_mozilla_org";
@@ -181,16 +181,18 @@ async function startIssueServer() {
});
server.registerPathHandler("/new", function(request, response) {
response.setHeader("Content-Type", "text/html", false);
response.setStatusLine(request.httpVersion, 200, "OK");
const postData = JSON.parse(getRequestData(request));
const url = postData.url;
const details = JSON.stringify(postData.details);
+ const label = JSON.stringify(postData.extra_labels);
const output = landingTemplate.replace("$$URL$$", url)
- .replace("$$DETAILS$$", details);
+ .replace("$$DETAILS$$", details)
+ .replace("$$LABEL$$", label);
response.write(output);
});
server.start(-1);
return `http://localhost:${server.identity.primaryPort}/new`;
}
--- a/browser/extensions/report-site-issue/test/browser/webcompat.html
+++ b/browser/extensions/report-site-issue/test/browser/webcompat.html
@@ -1,15 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<style>
#screenshot-preview {width: 200px; height: 200px;}
</style>
<div id="url">$$URL$$</div>
<div id="details">$$DETAILS$$</div>
+<div id="label">$$LABEL$$</div>
<div id="screenshot-preview">Fail</div>
<script>
"use strict";
let preview = document.getElementById("screenshot-preview");
function getBlobAsDataURL(blob) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
--- a/mobile/android/extensions/report-site-issue/background.js
+++ b/mobile/android/extensions/report-site-issue/background.js
@@ -10,16 +10,18 @@ const Config = {
newIssueEndpoint: "https://webcompat.com/issues/new",
newIssueEndpointPref: "newIssueEndpoint",
screenshotFormat: {
format: "jpeg",
quality: 75,
},
};
+const FRAMEWORK_KEYS = ["hasFastClick", "hasMobify", "hasMarfeel"];
+
// If parental controls are on, we don't activate (that is, we don't show our
// menu item or prompt the user when they use "request desktop site".
browser.browserInfo.getParentalControlsEnabled().then(enabled => {
if (enabled) {
return;
}
browser.aboutConfigPrefs.onEndpointPrefChange.addListener(checkEndpointPref);
@@ -124,53 +126,77 @@ function hasFastClickPageScript() {
}
} catch (_) {
}
}
return false;
}
-function checkForFastClick(tabId) {
+function hasMobifyPageScript() {
+ const win = window.wrappedJSObject;
+ return !!(win.Mobify && win.Mobify.Tag);
+}
+
+function hasMarfeelPageScript() {
+ const win = window.wrappedJSObject;
+ return !!win.marfeel;
+}
+
+function checkForFrameworks(tabId) {
return browser.tabs.executeScript(tabId, {
- code: `${hasFastClickPageScript};hasFastClickPageScript()`,
- }).then(([hasFastClick]) => hasFastClick).catch(() => false);
+ code: `
+ (function() {
+ ${hasFastClickPageScript};
+ ${hasMobifyPageScript};
+ ${hasMarfeelPageScript};
+
+ const result = {
+ hasFastClick: hasFastClickPageScript(),
+ hasMobify: hasMobifyPageScript(),
+ hasMarfeel: hasMarfeelPageScript(),
+ }
+
+ return result;
+ })();
+ `,
+ }).then(([results]) => results).catch(() => false);
}
function getWebCompatInfoForTab(tab) {
const {id, windiwId, url} = tab;
return Promise.all([
browser.browserInfo.getBlockList(),
browser.browserInfo.getBuildID(),
browser.browserInfo.getGraphicsPrefs(),
browser.browserInfo.getUpdateChannel(),
browser.browserInfo.hasTouchScreen(),
browser.tabExtras.getWebcompatInfo(id),
- checkForFastClick(id),
+ checkForFrameworks(id),
browser.tabs.captureVisibleTab(windiwId, Config.screenshotFormat).catch(e => {
console.error("Report Site Issue: getting a screenshot failed", e);
return Promise.resolve(undefined);
}),
]).then(([blockList, buildID, graphicsPrefs, channel, hasTouchScreen,
- frameInfo, hasFastClick, screenshot]) => {
+ frameInfo, frameworks, screenshot]) => {
if (channel !== "linux") {
delete graphicsPrefs["layers.acceleration.force-enabled"];
}
const consoleLog = frameInfo.log;
delete frameInfo.log;
return Object.assign(frameInfo, {
tabId: id,
blockList,
details: Object.assign(graphicsPrefs, {
buildID,
channel,
consoleLog,
- hasFastClick,
+ frameworks,
hasTouchScreen,
"mixed active content blocked": frameInfo.hasMixedActiveContentBlocked,
"mixed passive content blocked": frameInfo.hasMixedDisplayContentBlocked,
"tracking content blocked": frameInfo.hasTrackingContentBlocked ?
`true (${blockList})` : "false",
}),
screenshot,
url,
@@ -187,28 +213,32 @@ async function openWebCompatTab(compatIn
const url = new URL(Config.newIssueEndpoint);
const {details} = compatInfo;
const params = {
url: `${compatInfo.url}`,
utm_source: "mobile-reporter",
utm_campaign: "report-site-issue-button",
src: "mobile-reporter",
details,
- label: [],
+ extra_labels: [],
};
- if (details.hasFastClick) {
- params.label.push("type-fastclick");
- } else {
- delete details.hasFastClick;
+
+ for (let framework of FRAMEWORK_KEYS) {
+ if (details.frameworks[framework]) {
+ params.details[framework] = true;
+ params.extra_labels.push(framework.replace(/^has/, "type-").toLowerCase());
+ }
}
+ delete details.frameworks;
+
if (details["gfx.webrender.all"] || details["gfx.webrender.enabled"]) {
- params.label.push("type-webrender-enabled");
+ params.extra_labels.push("type-webrender-enabled");
}
if (compatInfo.hasTrackingContentBlocked) {
- params.label.push(`type-tracking-protection-${compatInfo.blockList}`);
+ params.extra_labels.push(`type-tracking-protection-${compatInfo.blockList}`);
}
// Need custom API for private tabs until https://bugzil.la/1372178 is fixed
const tab = usePrivateTab ? await browser.tabExtras.createPrivateTab() :
await browser.tabs.create({url: "about:blank"});
const json = stripNonASCIIChars(JSON.stringify(params));
await browser.tabExtras.loadURIWithPostData(tab.id, url.href, json,
"application/json");