summaryrefslogtreecommitdiffstats
path: root/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_telemetry_connection_attempt.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_telemetry_connection_attempt.js')
-rw-r--r--devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_telemetry_connection_attempt.js274
1 files changed, 274 insertions, 0 deletions
diff --git a/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_telemetry_connection_attempt.js b/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_telemetry_connection_attempt.js
new file mode 100644
index 0000000000..a5836ad50a
--- /dev/null
+++ b/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_telemetry_connection_attempt.js
@@ -0,0 +1,274 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/* import-globals-from helper-telemetry.js */
+Services.scriptloader.loadSubScript(
+ CHROME_URL_ROOT + "helper-telemetry.js",
+ this
+);
+
+const USB_RUNTIME = {
+ id: "runtime-id-1",
+ deviceName: "Device A",
+ name: "Runtime 1",
+ shortName: "R1",
+};
+
+/**
+ * Check that telemetry events for connection attempts are correctly recorded in various
+ * scenarios:
+ * - successful connection
+ * - successful connection after showing the timeout warning
+ * - failed connection
+ * - connection timeout
+ */
+add_task(async function testSuccessfulConnectionAttempt() {
+ const { doc, mocks, runtimeId, sessionId, tab } =
+ await setupConnectionAttemptTest();
+
+ await connectToRuntime(USB_RUNTIME.deviceName, doc);
+
+ const connectionEvents = checkTelemetryEvents(
+ [
+ { method: "runtime_connected", extras: { runtime_id: runtimeId } },
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("start", runtimeId),
+ },
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("success", runtimeId),
+ },
+ ],
+ sessionId
+ ).filter(({ method }) => method === "connection_attempt");
+
+ checkConnectionId(connectionEvents);
+
+ await removeUsbRuntime(USB_RUNTIME, mocks, doc);
+ await removeTab(tab);
+});
+
+add_task(async function testFailedConnectionAttempt() {
+ const { doc, mocks, runtimeId, sessionId, tab } =
+ await setupConnectionAttemptTest();
+ mocks.runtimeClientFactoryMock.createClientForRuntime = async runtime => {
+ throw new Error("failed");
+ };
+
+ info(
+ "Try to connect to the runtime and wait for the connection error message"
+ );
+ const usbRuntimeSidebarItem = findSidebarItemByText(
+ USB_RUNTIME.deviceName,
+ doc
+ );
+ const connectButton =
+ usbRuntimeSidebarItem.querySelector(".qa-connect-button");
+ connectButton.click();
+ await waitUntil(() =>
+ usbRuntimeSidebarItem.querySelector(".qa-connection-error")
+ );
+
+ const connectionEvents = checkTelemetryEvents(
+ [
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("start", runtimeId),
+ },
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("failed", runtimeId),
+ },
+ ],
+ sessionId
+ ).filter(({ method }) => method === "connection_attempt");
+
+ checkConnectionId(connectionEvents);
+
+ await removeUsbRuntime(USB_RUNTIME, mocks, doc);
+ await removeTab(tab);
+});
+
+add_task(async function testPendingConnectionAttempt() {
+ info("Set timeout preferences to avoid cancelling the connection");
+ await pushPref(
+ "devtools.aboutdebugging.test-connection-timing-out-delay",
+ 100
+ );
+ await pushPref(
+ "devtools.aboutdebugging.test-connection-cancel-delay",
+ 100000
+ );
+
+ const { doc, mocks, runtimeId, sessionId, tab } =
+ await setupConnectionAttemptTest();
+
+ info("Simulate a pending connection");
+ let resumeConnection;
+ const resumeConnectionPromise = new Promise(r => {
+ resumeConnection = r;
+ });
+ mocks.runtimeClientFactoryMock.createClientForRuntime = async runtime => {
+ await resumeConnectionPromise;
+ return mocks._clients[runtime.type][runtime.id];
+ };
+
+ info("Click on the connect button and wait for the warning message");
+ const usbRuntimeSidebarItem = findSidebarItemByText(
+ USB_RUNTIME.deviceName,
+ doc
+ );
+ const connectButton =
+ usbRuntimeSidebarItem.querySelector(".qa-connect-button");
+ connectButton.click();
+ await waitUntil(() => doc.querySelector(".qa-connection-not-responding"));
+
+ info("Resume the connection and wait for the connection to succeed");
+ resumeConnection();
+ await waitUntil(
+ () => !usbRuntimeSidebarItem.querySelector(".qa-connect-button")
+ );
+
+ const connectionEvents = checkTelemetryEvents(
+ [
+ { method: "runtime_connected", extras: { runtime_id: runtimeId } },
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("start", runtimeId),
+ },
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("not responding", runtimeId),
+ },
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("success", runtimeId),
+ },
+ ],
+ sessionId
+ ).filter(({ method }) => method === "connection_attempt");
+ checkConnectionId(connectionEvents);
+
+ await removeUsbRuntime(USB_RUNTIME, mocks, doc);
+ await removeTab(tab);
+});
+
+add_task(async function testCancelledConnectionAttempt() {
+ info("Set timeout preferences to quickly cancel the connection");
+ await pushPref(
+ "devtools.aboutdebugging.test-connection-timing-out-delay",
+ 100
+ );
+ await pushPref("devtools.aboutdebugging.test-connection-cancel-delay", 1000);
+
+ const { doc, mocks, runtimeId, sessionId, tab } =
+ await setupConnectionAttemptTest();
+
+ info("Simulate a connection timeout");
+ mocks.runtimeClientFactoryMock.createClientForRuntime = async runtime => {
+ await new Promise(r => {});
+ };
+
+ info("Click on the connect button and wait for the error message");
+ const usbRuntimeSidebarItem = findSidebarItemByText(
+ USB_RUNTIME.deviceName,
+ doc
+ );
+ const connectButton =
+ usbRuntimeSidebarItem.querySelector(".qa-connect-button");
+ connectButton.click();
+ await waitUntil(() =>
+ usbRuntimeSidebarItem.querySelector(".qa-connection-timeout")
+ );
+
+ const connectionEvents = checkTelemetryEvents(
+ [
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("start", runtimeId),
+ },
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("not responding", runtimeId),
+ },
+ {
+ method: "connection_attempt",
+ extras: getEventExtras("cancelled", runtimeId),
+ },
+ ],
+ sessionId
+ ).filter(({ method }) => method === "connection_attempt");
+ checkConnectionId(connectionEvents);
+
+ await removeUsbRuntime(USB_RUNTIME, mocks, doc);
+ await removeTab(tab);
+});
+
+function checkConnectionId(connectionEvents) {
+ const connectionId = connectionEvents[0].extras.connection_id;
+ ok(
+ !!connectionId,
+ "Found a valid connection id in the first connection_attempt event"
+ );
+ for (const evt of connectionEvents) {
+ is(
+ evt.extras.connection_id,
+ connectionId,
+ "All connection_attempt events share the same connection id"
+ );
+ }
+}
+
+// Small helper to create the expected event extras object for connection_attempt events
+function getEventExtras(status, runtimeId) {
+ return {
+ connection_type: "usb",
+ runtime_id: runtimeId,
+ status,
+ };
+}
+
+// Open about:debugging, setup telemetry, mocks and create a mocked USB runtime.
+async function setupConnectionAttemptTest() {
+ const mocks = new Mocks();
+ setupTelemetryTest();
+
+ const { tab, document } = await openAboutDebugging();
+
+ const sessionId = getOpenEventSessionId();
+ ok(!isNaN(sessionId), "Open event has a valid session id");
+
+ mocks.createUSBRuntime(USB_RUNTIME.id, {
+ deviceName: USB_RUNTIME.deviceName,
+ name: USB_RUNTIME.name,
+ shortName: USB_RUNTIME.shortName,
+ });
+ mocks.emitUSBUpdate();
+
+ info("Wait for the runtime to appear in the sidebar");
+ await waitUntil(() => findSidebarItemByText(USB_RUNTIME.shortName, document));
+ const evts = checkTelemetryEvents(
+ [
+ { method: "device_added", extras: {} },
+ { method: "runtime_added", extras: {} },
+ ],
+ sessionId
+ );
+
+ const runtimeId = evts.filter(e => e.method === "runtime_added")[0].extras
+ .runtime_id;
+ return { doc: document, mocks, runtimeId, sessionId, tab };
+}
+
+async function removeUsbRuntime(runtime, mocks, doc) {
+ mocks.removeRuntime(runtime.id);
+ mocks.emitUSBUpdate();
+ await waitUntil(
+ () =>
+ !findSidebarItemByText(runtime.name, doc) &&
+ !findSidebarItemByText(runtime.shortName, doc)
+ );
+}