/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; /** * Tests for the Glean version of onboarding telemetry. */ const { AboutWelcomeTelemetry } = ChromeUtils.import( "resource://activity-stream/aboutwelcome/lib/AboutWelcomeTelemetry.jsm" ); const TEST_DEFAULT_CONTENT = [ { id: "AW_STEP1", content: { position: "split", title: "Step 1", page: "page 1", source: "test", primary_button: { label: "Next", action: { navigate: true, }, }, secondary_button: { label: "link", }, secondary_button_top: { label: "link top", action: { type: "SHOW_FIREFOX_ACCOUNTS", data: { entrypoint: "test" }, }, }, help_text: { text: "Here's some sample help text", }, }, }, { id: "AW_STEP2", content: { position: "center", title: "Step 2", page: "page 1", source: "test", primary_button: { label: "Next", action: { navigate: true, }, }, secondary_button: { label: "link", }, has_noodles: true, }, }, ]; const TEST_DEFAULT_JSON = JSON.stringify(TEST_DEFAULT_CONTENT); async function openAboutWelcome() { await setAboutWelcomePref(true); await setAboutWelcomeMultiStage(TEST_DEFAULT_JSON); let tab = await BrowserTestUtils.openNewForegroundTab( gBrowser, "about:welcome", true ); registerCleanupFunction(() => { BrowserTestUtils.removeTab(tab); }); return tab.linkedBrowser; } add_task(async function test_welcome_telemetry() { const sandbox = sinon.createSandbox(); // Be sure to stub out PingCentre so it doesn't hit the network. sandbox .stub(AboutWelcomeTelemetry.prototype, "pingCentre") .value({ sendStructuredIngestionPing: () => {} }); // Have to turn on AS telemetry for anything to be recorded. await SpecialPowers.pushPrefEnv({ set: [["browser.newtabpage.activity-stream.telemetry", true]], }); registerCleanupFunction(async () => { await SpecialPowers.popPrefEnv(); }); Services.fog.testResetFOG(); // Let's check that there is nothing in the impression event. // This is useful in mochitests because glean inits fairly late in startup. // We want to make sure we are fully initialized during testing so that // when we call testGetValue() we get predictable behavior. Assert.equal(undefined, Glean.messagingSystem.messageId.testGetValue()); // Setup testBeforeNextSubmit. We do this first, progress onboarding, submit // and then check submission. We put the asserts inside testBeforeNextSubmit // because metric lifetimes are 'ping' and are cleared after submission. // See: https://firefox-source-docs.mozilla.org/toolkit/components/glean/user/instrumentation_tests.html#xpcshell-tests let pingSubmitted = false; GleanPings.messagingSystem.testBeforeNextSubmit(() => { pingSubmitted = true; const message = Glean.messagingSystem.messageId.testGetValue(); // Because of the asynchronous nature of receiving messages, we cannot // guarantee that we will get the same message first. Instead we check // that the one we get is a valid example of that type. Assert.ok( message.startsWith("MR_WELCOME_DEFAULT"), "Ping is of an expected type" ); Assert.equal( Glean.messagingSystem.unknownKeyCount.testGetValue(), undefined ); }); let browser = await openAboutWelcome(); // `openAboutWelcome` isn't synchronous wrt the onboarding flow impressing. await TestUtils.waitForCondition( () => pingSubmitted, "Ping was submitted, callback was called." ); registerCleanupFunction(() => { sandbox.restore(); }); // Let's reset and assert some values in the next button click. pingSubmitted = false; GleanPings.messagingSystem.testBeforeNextSubmit(() => { pingSubmitted = true; // Sometimes the impression for MR_WELCOME_DEFAULT_0_AW_STEP1_SS reaches // the parent process before the button click does. // See https://bugzilla.mozilla.org/show_bug.cgi?id=1834620 if (Glean.messagingSystem.event.testGetValue() === "IMPRESSION") { Assert.equal( Glean.messagingSystem.eventPage.testGetValue(), "about:welcome" ); const message = Glean.messagingSystem.messageId.testGetValue(); Assert.ok( message.startsWith("MR_WELCOME_DEFAULT"), "Ping is of an expected type" ); } else { // This is the common and, to my mind, correct case: // the click coming before the next steps' impression. Assert.equal(Glean.messagingSystem.event.testGetValue(), "CLICK_BUTTON"); Assert.equal( Glean.messagingSystem.eventSource.testGetValue(), "primary_button" ); Assert.equal( Glean.messagingSystem.messageId.testGetValue(), "MR_WELCOME_DEFAULT_0_AW_STEP1" ); } Assert.equal( Glean.messagingSystem.unknownKeyCount.testGetValue(), undefined ); }); await onButtonClick(browser, "button.primary"); Assert.ok(pingSubmitted, "Ping was submitted, callback was called."); });