Bug 977774 - Count the number of times a user opts out of Instant Translation. r=felipe.

This commit is contained in:
Asaf Romano 2014-06-24 08:30:47 +03:00
parent eea3b3a418
commit d1b3d852f0
3 changed files with 120 additions and 41 deletions

View File

@ -255,6 +255,11 @@ TranslationUI.prototype = {
}
break;
}
},
infobarClosed: function() {
if (this.state == Translation.STATE_OFFER)
TranslationHealthReport.recordDeniedTranslationOffer();
}
};

View File

@ -7,6 +7,58 @@ let tmp = {};
Cu.import("resource:///modules/translation/Translation.jsm", tmp);
let {Translation} = tmp;
let MetricsChecker = {
_metricsTime: new Date(),
_midnightError: new Error("Getting metrics around midnight may fail sometimes"),
updateMetrics: Task.async(function* () {
let svc = Cc["@mozilla.org/datareporting/service;1"].getService();
let reporter = svc.wrappedJSObject.healthReporter;
yield reporter.onInit();
// Get the provider.
let provider = reporter.getProvider("org.mozilla.translation");
let measurement = provider.getMeasurement("translation", 1);
let values = yield measurement.getValues();
let metricsTime = new Date();
let day = values.days.getDay(metricsTime);
if (!day) {
// This should never happen except when the test runs at midnight.
throw this._midnightError;
}
// .get() may return `undefined`, which we can't compute.
this._metrics = {
pageCount: day.get("pageTranslatedCount") || 0,
charCount: day.get("charactersTranslatedCount") || 0,
deniedOffers: day.get("deniedTranslationOffer") || 0
};
this._metricsTime = metricsTime;
}),
checkAdditions: Task.async(function* (additions) {
let prevMetrics = this._metrics, prevMetricsTime = this._metricsTime;
try {
yield this.updateMetrics();
} catch(ex if ex == this._midnightError) {
return;
}
// Check that it's still the same day of the month as when we started. This
// prevents intermittent failures when the test starts before and ends after
// midnight.
if (this._metricsTime.getDate() != prevMetricsTime.getDate()) {
for (let metric of Object.keys(prevMetrics)) {
prevMetrics[metric] = 0;
}
}
for (let metric of Object.keys(additions)) {
Assert.equal(prevMetrics[metric] + additions[metric], this._metrics[metric]);
}
})
};
add_task(function* setup() {
Services.prefs.setBoolPref("toolkit.telemetry.enabled", true);
Services.prefs.setBoolPref("browser.translation.detectLanguage", true);
@ -17,53 +69,48 @@ add_task(function* setup() {
Services.prefs.clearUserPref("browser.translation.detectLanguage");
Services.prefs.clearUserPref("browser.translation.ui.show");
});
yield MetricsChecker.updateMetrics();
});
add_task(function* test_fhr() {
let start = new Date();
// Translate a page.
yield translate("<h1>Hallo Welt!</h1>", "de", "en");
let [pageCount, charCount] = yield retrieveTranslationCounts();
// Translate another page.
yield translate("<h1>Hallo Welt!</h1><h1>Bratwurst!</h1>", "de", "en");
let [pageCount2, charCount2] = yield retrieveTranslationCounts();
// Check that it's still the same day of the month as when we started. This
// prevents intermittent failures when the test starts before and ends after
// midnight.
if (start.getDate() == new Date().getDate()) {
Assert.equal(pageCount2, pageCount + 1);
Assert.equal(charCount2, charCount + 21);
}
yield MetricsChecker.checkAdditions({ pageCount: 1, charCount: 21, deniedOffers: 0});
});
function retrieveTranslationCounts() {
return Task.spawn(function* task_retrieve_counts() {
let svc = Cc["@mozilla.org/datareporting/service;1"].getService();
let reporter = svc.wrappedJSObject.healthReporter;
yield reporter.onInit();
add_task(function* test_deny_translation_metric() {
function* offerAndDeny(elementAnonid) {
let tab = yield offerTranslatationFor("<h1>Hallo Welt!</h1>", "de", "en");
getInfobarElement(tab.linkedBrowser, elementAnonid).doCommand();
yield MetricsChecker.checkAdditions({ deniedOffers: 1 });
gBrowser.removeTab(tab);
}
// Get the provider.
let provider = reporter.getProvider("org.mozilla.translation");
let measurement = provider.getMeasurement("translation", 1);
let values = yield measurement.getValues();
yield offerAndDeny("notNow");
yield offerAndDeny("neverForSite");
yield offerAndDeny("neverForLanguage");
yield offerAndDeny("closeButton");
let day = values.days.getDay(new Date());
if (!day) {
// This should never happen except when the test runs at midnight.
return [0, 0];
}
// Test that the close button doesn't record a denied translation if
// the infobar is not in its "offer" state.
let tab =
yield translate("<h1>Hallo Welt!</h1>", "de", "en", false);
yield MetricsChecker.checkAdditions({ deniedOffers: 0 });
gBrowser.removeTab(tab);
});
// .get() may return `undefined`, which we can't compute.
return [day.get("pageTranslatedCount") || 0, day.get("charactersTranslatedCount") || 0];
});
function getInfobarElement(browser, anonid) {
let notif = browser.translationUI
.notificationBox.getNotificationWithValue("translation");
return notif._getAnonElt(anonid);
}
function translate(text, from, to) {
return Task.spawn(function* task_translate() {
function offerTranslatationFor(text, from) {
return Task.spawn(function* task_offer_translation() {
// Create some content to translate.
let tab = gBrowser.selectedTab =
gBrowser.addTab("data:text/html;charset=utf-8," + text);
@ -77,12 +124,28 @@ function translate(text, from, to) {
originalShown: true,
detectedLanguage: from});
// Translate the page.
browser.translationUI.translate(from, to);
yield waitForMessage(browser, "Translation:Finished");
return tab;
});
}
// Cleanup.
gBrowser.removeTab(tab);
function acceptTranslationOffer(tab, to) {
return Task.spawn(function* task_accept_translation_offer() {
let browser = tab.linkedBrowser;
getInfobarElement(browser, "toLanguage").value = to;
getInfobarElement(browser, "toLanguage").doCommand();
yield waitForMessage(browser, "Translation:Finished");
});
}
function translate(text, from, to, closeTab = true) {
return Task.spawn(function* task_translate() {
let tab = yield offerTranslatationFor(text, from);
yield acceptTranslationOffer(tab, to);
if (closeTab) {
gBrowser.removeTab(tab);
} else {
return tab;
}
});
}

View File

@ -38,7 +38,7 @@
oncommand="document.getBindingParent(this).translate();"/>
<xul:button class="translate-infobar-element"
label="&translation.notNow.button;" anonid="notNow"
oncommand="document.getBindingParent(this).close();"/>
oncommand="document.getBindingParent(this).closeCommand();"/>
</xul:hbox>
<!-- translating -->
@ -122,10 +122,11 @@
</xul:hbox>
<xul:toolbarbutton ondblclick="event.stopPropagation();"
anonid="closeButton"
class="messageCloseButton close-icon tabbable"
xbl:inherits="hidden=hideclose"
tooltiptext="&closeNotification.tooltip;"
oncommand="document.getBindingParent(this).close();"/>
oncommand="document.getBindingParent(this).closeCommand();"/>
</xul:hbox>
</content>
<implementation>
@ -216,6 +217,16 @@
</body>
</method>
<!-- To be called when the infobar should be closed per user's wish (e.g.
by clicking the notification's close button -->
<method name="closeCommand">
<body>
<![CDATA[
this.close();
this.translation.infobarClosed();
]]>
</body>
</method>
<method name="_handleButtonHiding">
<body>
<![CDATA[
@ -301,7 +312,7 @@
Services.prefs.setCharPref(kPrefName, val);
this.close();
this.closeCommand();
]]>
</body>
</method>
@ -313,7 +324,7 @@
let perms = Services.perms;
perms.add(uri, "translate", perms.DENY_ACTION);
this.close();
this.closeCommand();
]]>
</body>
</method>