summaryrefslogtreecommitdiffstats
path: root/devtools/client/application/test/browser/head.js
blob: 6b7e67ff8d12686de64b1317ff46610711961d4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

/* eslint-env browser */
/* eslint no-unused-vars: [2, {"vars": "local"}] */

"use strict";

// Load the shared-head file first.
Services.scriptloader.loadSubScript(
  "chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js",
  this
);

/**
 * Set all preferences needed to enable service worker debugging and testing.
 */
async function enableServiceWorkerDebugging() {
  // Enable service workers.
  await pushPref("dom.serviceWorkers.enabled", true);
  // Accept workers from mochitest's http.
  await pushPref("dom.serviceWorkers.testing.enabled", true);
  // Force single content process, see Bug 1231208 for the SW refactor that should enable
  // SW debugging in multi-e10s.
  await pushPref("dom.ipc.processCount", 1);

  // Enable service workers in the debugger
  await pushPref("devtools.debugger.features.windowless-service-workers", true);
  // Disable randomly spawning processes during tests
  await pushPref("dom.ipc.processPrelaunch.enabled", false);

  // Wait for dom.ipc.processCount to be updated before releasing processes.
  Services.ppmm.releaseCachedProcesses();
}

async function enableApplicationPanel() {
  // FIXME bug 1575427 this rejection is very common.
  const { PromiseTestUtils } = ChromeUtils.importESModule(
    "resource://testing-common/PromiseTestUtils.sys.mjs"
  );
  PromiseTestUtils.allowMatchingRejectionsGlobally(
    /this._frontCreationListeners is null/
  );

  // Enable all preferences related to service worker debugging.
  await enableServiceWorkerDebugging();

  // Enable web manifest processing.
  Services.prefs.setBoolPref("dom.manifest.enabled", true);

  // Enable application panel in DevTools.
  await pushPref("devtools.application.enabled", true);
}

function setupTelemetryTest() {
  // Reset all the counts
  Services.telemetry.clearEvents();

  // Ensure no events have been logged
  const ALL_CHANNELS = Ci.nsITelemetry.DATASET_ALL_CHANNELS;
  const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true);
  ok(!snapshot.parent, "No events have been logged for the main process");
}

function getTelemetryEvents(objectName) {
  // read the requested events only
  const ALL_CHANNELS = Ci.nsITelemetry.DATASET_ALL_CHANNELS;
  const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true);
  // filter and transform the event data so the relevant info is in a single object:
  // { method: "...", extraField: "...", anotherExtraField: "...", ... }
  const events = snapshot.parent
    .filter(event => event[1] === "devtools.main" && event[3] === objectName)
    .map(event => ({ method: event[2], ...event[5] }));

  return events;
}

function checkTelemetryEvent(expectedEvent, objectName = "application") {
  info("Check telemetry event");
  const events = getTelemetryEvents(objectName);

  // assert we only got 1 event with a valid session ID
  is(events.length, 1, "There was only 1 event logged");
  const [event] = events;
  ok(event.session_id > 0, "There is a valid session_id in the event");

  // assert expected data
  Assert.deepEqual(event, { ...expectedEvent, session_id: event.session_id });
}

function getWorkerContainers(doc) {
  return doc.querySelectorAll(".js-sw-container");
}

async function openNewTabAndApplicationPanel(url) {
  const tab = await addTab(url);

  const toolbox = await gDevTools.showToolboxForTab(tab, {
    toolId: "application",
  });
  const panel = toolbox.getCurrentPanel();
  const target = toolbox.target;
  const commands = toolbox.commands;
  return { panel, tab, target, toolbox, commands };
}

async function unregisterAllWorkers(client, doc) {
  // This method is declared in shared-head.js
  await unregisterAllServiceWorkers(client);

  info("Wait for service workers to disappear from the UI");
  waitUntil(() => getWorkerContainers(doc).length === 0);
}

async function waitForWorkerRegistration(swTab) {
  info("Wait until the registration appears on the window");
  const swBrowser = swTab.linkedBrowser;
  await asyncWaitUntil(async () =>
    SpecialPowers.spawn(swBrowser, [], function () {
      return !!content.wrappedJSObject.getRegistration();
    })
  );
}

function selectPage(panel, page) {
  /**
   * Select a page by simulating a user click in the sidebar.
   * @param {string} page The page we want to select (see `PAGE_TYPES`)
   **/
  info(`Selecting application page: ${page}`);
  const doc = panel.panelWin.document;
  const navItem = doc.querySelector(`.js-sidebar-${page}`);
  navItem.click();
}