summaryrefslogtreecommitdiffstats
path: root/toolkit/components/passwordmgr/test/browser/browser_doorhanger_submit_telemetry.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /toolkit/components/passwordmgr/test/browser/browser_doorhanger_submit_telemetry.js
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/passwordmgr/test/browser/browser_doorhanger_submit_telemetry.js')
-rw-r--r--toolkit/components/passwordmgr/test/browser/browser_doorhanger_submit_telemetry.js387
1 files changed, 387 insertions, 0 deletions
diff --git a/toolkit/components/passwordmgr/test/browser/browser_doorhanger_submit_telemetry.js b/toolkit/components/passwordmgr/test/browser/browser_doorhanger_submit_telemetry.js
new file mode 100644
index 0000000000..97353007ac
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/browser/browser_doorhanger_submit_telemetry.js
@@ -0,0 +1,387 @@
+/**
+ * Test that doorhanger submit telemetry is sent when the user saves/updates.
+ */
+
+add_setup(function () {
+ // This test used to rely on the initial timer of
+ // TestUtils.waitForCondition. See bug 1695395.
+ // The test is perma-fail on Linux asan opt without this.
+ let originalWaitForCondition = TestUtils.waitForCondition;
+ TestUtils.waitForCondition = async function (
+ condition,
+ msg,
+ interval = 100,
+ maxTries = 50
+ ) {
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(resolve => setTimeout(resolve, 100));
+
+ return originalWaitForCondition(condition, msg, interval, maxTries);
+ };
+ registerCleanupFunction(function () {
+ TestUtils.waitForCondition = originalWaitForCondition;
+ });
+});
+
+const PAGE_USERNAME_SELECTOR = "#form-basic-username";
+const PAGE_PASSWORD_SELECTOR = "#form-basic-password";
+
+const TEST_CASES = [
+ {
+ description:
+ "Saving a new login from page values without modification sends a 'no modification' event",
+ savedLogin: undefined,
+ userActions: [
+ {
+ pageChanges: {
+ username: "pageUn",
+ password: "pagePw",
+ },
+ doorhangerChanges: [],
+ },
+ ],
+ expectedEvents: [
+ {
+ type: "save",
+ ping: {
+ did_edit_un: "false",
+ did_select_un: "false",
+ did_edit_pw: "false",
+ did_select_pw: "false",
+ },
+ },
+ ],
+ },
+ /////////////////
+ {
+ description: "Saving two logins sends two events",
+ userActions: [
+ {
+ pageChanges: { password: "pagePw" },
+ doorhangerChanges: [
+ {
+ typedUsername: "doorhangerUn",
+ },
+ ],
+ },
+ {
+ pageChanges: { password: "pagePw2" },
+ doorhangerChanges: [
+ {
+ typedPassword: "doorhangerPw",
+ },
+ ],
+ },
+ ],
+ expectedEvents: [
+ {
+ type: "save",
+ ping: {
+ did_edit_un: "true",
+ did_select_un: "false",
+ did_edit_pw: "false",
+ did_select_pw: "false",
+ },
+ },
+ {
+ type: "update",
+ ping: {
+ did_edit_un: "false",
+ did_select_un: "false",
+ did_edit_pw: "true",
+ did_select_pw: "false",
+ },
+ },
+ ],
+ },
+ /////////////////
+ {
+ description: "Updating a doorhanger password sends a 'pw updated' event",
+ savedLogin: {
+ username: "savedUn",
+ password: "savedPw",
+ },
+ userActions: [
+ {
+ pageChanges: { password: "pagePw" },
+ doorhangerChanges: [
+ {
+ typedPassword: "doorhangerPw",
+ },
+ ],
+ },
+ ],
+ expectedEvents: [
+ {
+ type: "update",
+ ping: {
+ did_edit_un: "false",
+ did_select_un: "false",
+ did_edit_pw: "true",
+ did_select_pw: "false",
+ },
+ },
+ ],
+ },
+ /////////////////
+ {
+ description:
+ "Saving a new username with an existing password sends a 'un updated' event",
+ savedLogin: {
+ username: "savedUn",
+ password: "savedPw",
+ },
+ userActions: [
+ {
+ pageChanges: { password: "pagePw" },
+ doorhangerChanges: [
+ {
+ typedUsername: "doorhangerUn",
+ },
+ ],
+ },
+ ],
+ expectedEvents: [
+ {
+ type: "update",
+ ping: {
+ did_edit_un: "true",
+ did_select_un: "false",
+ did_edit_pw: "false",
+ did_select_pw: "false",
+ },
+ },
+ ],
+ },
+ ///////////////
+ {
+ description: "selecting a saved username sends a 'not edited' event",
+ savedLogin: {
+ username: "savedUn",
+ password: "savedPw",
+ },
+ userActions: [
+ {
+ pageChanges: { password: "pagePw" },
+ doorhangerChanges: [
+ {
+ selectUsername: "savedUn",
+ },
+ ],
+ },
+ ],
+ expectedEvents: [
+ {
+ type: "update",
+ ping: {
+ did_edit_un: "false",
+ did_select_un: "true",
+ did_edit_pw: "false",
+ did_select_pw: "false",
+ },
+ },
+ ],
+ },
+ /////////////////
+ {
+ description:
+ "typing a new username then selecting a saved username sends a 'not edited' event",
+ savedLogin: {
+ username: "savedUn",
+ password: "savedPw",
+ },
+ userActions: [
+ {
+ pageChanges: { password: "pagePw" },
+ doorhangerChanges: [
+ {
+ typedUsername: "doorhangerTypedUn",
+ },
+ {
+ selectUsername: "savedUn",
+ },
+ ],
+ },
+ ],
+ expectedEvents: [
+ {
+ type: "update",
+ ping: {
+ did_edit_un: "false",
+ did_select_un: "true",
+ did_edit_pw: "false",
+ did_select_pw: "false",
+ },
+ },
+ ],
+ },
+ /////////////////
+ {
+ description:
+ "selecting a saved username then typing a new username sends an 'edited' event",
+ savedLogin: {
+ username: "savedUn",
+ password: "savedPw",
+ },
+ userActions: [
+ {
+ pageChanges: { password: "pagePw" },
+ doorhangerChanges: [
+ {
+ selectUsername: "savedUn",
+ },
+ {
+ typedUsername: "doorhangerTypedUn",
+ },
+ ],
+ },
+ ],
+ expectedEvents: [
+ {
+ type: "update",
+ ping: {
+ did_edit_un: "true",
+ did_select_un: "false",
+ did_edit_pw: "false",
+ did_select_pw: "false",
+ },
+ },
+ ],
+ },
+ /////////////////
+];
+
+for (let testData of TEST_CASES) {
+ let tmp = {
+ async [testData.description]() {
+ info("testing with: " + JSON.stringify(testData));
+ await test_submit_telemetry(testData);
+ },
+ };
+ add_task(tmp[testData.description]);
+}
+
+function _validateTestCase(tc) {
+ for (let event of tc.expectedEvents) {
+ Assert.ok(
+ !(event.ping.did_edit_un && event.ping.did_select_un),
+ "'did_edit_un' and 'did_select_un' can never be true at the same time"
+ );
+ Assert.ok(
+ !(event.ping.did_edit_pw && event.ping.did_select_pw),
+ "'did_edit_pw' and 'did_select_pw' can never be true at the same time"
+ );
+ }
+}
+
+async function test_submit_telemetry(tc) {
+ if (tc.savedLogin) {
+ await Services.logins.addLoginAsync(
+ LoginTestUtils.testData.formLogin({
+ origin: "https://example.com",
+ formActionOrigin: "https://example.com",
+ username: tc.savedLogin.username,
+ password: tc.savedLogin.password,
+ })
+ );
+ }
+
+ let notif;
+ for (let userAction of tc.userActions) {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url:
+ "https://example.com/browser/toolkit/components/" +
+ "passwordmgr/test/browser/form_basic.html",
+ },
+ async function (browser) {
+ await SimpleTest.promiseFocus(browser.ownerGlobal);
+
+ if (userAction.pageChanges) {
+ info(
+ `Update form with changes: ${JSON.stringify(
+ userAction.pageChanges
+ )}`
+ );
+ let changeTo = {};
+ if (userAction.pageChanges.username) {
+ changeTo[PAGE_USERNAME_SELECTOR] = userAction.pageChanges.username;
+ }
+ if (userAction.pageChanges.password) {
+ changeTo[PAGE_PASSWORD_SELECTOR] = userAction.pageChanges.password;
+ }
+
+ await changeContentFormValues(browser, changeTo);
+ }
+
+ info("Submitting form");
+ let formSubmittedPromise = listenForTestNotification("ShowDoorhanger");
+ await SpecialPowers.spawn(browser, [], async function () {
+ let doc = this.content.document;
+ doc.getElementById("form-basic").submit();
+ });
+ await formSubmittedPromise;
+
+ let saveDoorhanger = waitForDoorhanger(browser, "password-save");
+ let updateDoorhanger = waitForDoorhanger(browser, "password-change");
+ notif = await Promise.race([saveDoorhanger, updateDoorhanger]);
+
+ if (PopupNotifications.panel.state !== "open") {
+ await BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ }
+
+ if (userAction.doorhangerChanges) {
+ for (let doorhangerChange of userAction.doorhangerChanges) {
+ if (
+ doorhangerChange.typedUsername ||
+ doorhangerChange.typedPassword
+ ) {
+ await updateDoorhangerInputValues({
+ username: doorhangerChange.typedUsername,
+ password: doorhangerChange.typedPassword,
+ });
+ }
+
+ if (doorhangerChange.selectUsername) {
+ await selectDoorhangerUsername(doorhangerChange.selectUsername);
+ }
+ if (doorhangerChange.selectPassword) {
+ await selectDoorhangerPassword(doorhangerChange.selectPassword);
+ }
+ }
+ }
+
+ info("Waiting for doorhanger");
+ await clickDoorhangerButton(notif, REMEMBER_BUTTON);
+ }
+ );
+ }
+
+ let expectedEvents = tc.expectedEvents.map(expectedEvent => [
+ "pwmgr",
+ "doorhanger_submitted",
+ expectedEvent.type,
+ null,
+ expectedEvent.ping,
+ ]);
+
+ await LoginTestUtils.telemetry.waitForEventCount(
+ expectedEvents.length,
+ "parent",
+ "pwmgr",
+ "doorhanger_submitted"
+ );
+ TelemetryTestUtils.assertEvents(
+ expectedEvents,
+ { category: "pwmgr", method: "doorhanger_submitted" },
+ { clear: true }
+ );
+
+ // Clean up the database before the next test case is executed.
+ await cleanupDoorhanger(notif);
+ Services.logins.removeAllUserFacingLogins();
+}