summaryrefslogtreecommitdiffstats
path: root/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_workers_remote_runtime.js
blob: 3e0ccf15322115d32f7a204025aabb0105971631 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const NETWORK_RUNTIME_HOST = "localhost:6080";
const NETWORK_RUNTIME_APP_NAME = "TestNetworkApp";
const USB_RUNTIME_ID = "test-runtime-id";
const USB_RUNTIME_DEVICE_NAME = "test device name";
const USB_RUNTIME_APP_NAME = "TestUsbApp";

const TESTS = [
  {
    category: "Other Workers",
    propertyName: "otherWorkers",
    workerName: "other/worker/script.js",
  },
  {
    category: "Service Workers",
    propertyName: "serviceWorkers",
    workerName: "service/worker/script.js",
  },
  {
    category: "Shared Workers",
    propertyName: "sharedWorkers",
    workerName: "shared/worker/script.js",
  },
];

const EMPTY_WORKERS_RESPONSE = {
  otherWorkers: [],
  serviceWorkers: [],
  sharedWorkers: [],
};

// Test that workers are displayed and updated for remote runtimes when expected.
add_task(async function () {
  const mocks = new Mocks();

  const { document, tab, window } = await openAboutDebugging({
    enableWorkerUpdates: true,
  });
  await selectThisFirefoxPage(document, window.AboutDebugging.store);

  info("Prepare USB client mock");
  const usbClient = mocks.createUSBRuntime(USB_RUNTIME_ID, {
    deviceName: USB_RUNTIME_DEVICE_NAME,
    name: USB_RUNTIME_APP_NAME,
  });
  mocks.emitUSBUpdate();

  info("Test addons in runtime page for USB client");
  await connectToRuntime(USB_RUNTIME_DEVICE_NAME, document);
  await selectRuntime(USB_RUNTIME_DEVICE_NAME, USB_RUNTIME_APP_NAME, document);
  for (const testData of TESTS) {
    await testWorkerOnMockedRemoteClient(
      testData,
      usbClient,
      mocks.thisFirefoxClient,
      document
    );
  }

  info("Prepare Network client mock");
  const networkClient = mocks.createNetworkRuntime(NETWORK_RUNTIME_HOST, {
    name: NETWORK_RUNTIME_APP_NAME,
  });

  info("Test workers in runtime page for Network client");
  await connectToRuntime(NETWORK_RUNTIME_HOST, document);
  await selectRuntime(NETWORK_RUNTIME_HOST, NETWORK_RUNTIME_APP_NAME, document);

  for (const testData of TESTS) {
    await testWorkerOnMockedRemoteClient(
      testData,
      networkClient,
      mocks.thisFirefoxClient,
      document
    );
  }

  await removeTab(tab);
});

/**
 * Check that workers are visible in the runtime page for a remote client.
 */
async function testWorkerOnMockedRemoteClient(
  testData,
  remoteClient,
  firefoxClient,
  document
) {
  const { category, propertyName, workerName } = testData;
  info(`Test workers for category [${category}] in remote runtime`);

  const workersPane = getDebugTargetPane(category, document);
  info("Check an empty target pane message is displayed");
  ok(
    workersPane.querySelector(".qa-debug-target-list-empty"),
    "Workers list is empty"
  );

  info(`Add a worker of type [${propertyName}] to the remote client`);
  const workers = Object.assign({}, EMPTY_WORKERS_RESPONSE, {
    [propertyName]: [
      {
        name: workerName,
        workerDescriptorFront: {
          actorID: workerName,
        },
      },
    ],
  });
  remoteClient.listWorkers = () => workers;
  remoteClient._eventEmitter.emit("workersUpdated");

  info("Wait until the worker appears");
  await waitUntil(
    () => !workersPane.querySelector(".qa-debug-target-list-empty")
  );

  const workerTarget = findDebugTargetByText(workerName, document);
  ok(workerTarget, "Worker target appeared for the remote runtime");

  // Check that the list of REMOTE workers are NOT updated when the local this-firefox
  // emits a workersUpdated event.
  info("Remove the worker from the remote client WITHOUT sending an event");
  remoteClient.listWorkers = () => EMPTY_WORKERS_RESPONSE;

  info("Simulate a worker update on the ThisFirefox client");
  firefoxClient._eventEmitter.emit("workersUpdated");

  // To avoid wait for a set period of time we trigger another async update, adding a new
  // tab. We assume that if the worker update mechanism had started, it would also be done
  // when the new tab was processed.
  info("Wait until the tab target for 'http://some.random/url.com' appears");
  const testTab = {
    retrieveFavicon: () => {},
    outerWindowID: 0,
    traits: {},
    url: "http://some.random/url.com",
  };
  remoteClient.listTabs = () => [testTab];
  remoteClient._eventEmitter.emit("tabListChanged");
  await waitUntil(() =>
    findDebugTargetByText("http://some.random/url.com", document)
  );

  ok(
    findDebugTargetByText(workerName, document),
    "The test worker is still visible"
  );

  info(
    "Emit `workersUpdated` on remoteClient and wait for the target list to update"
  );
  remoteClient._eventEmitter.emit("workersUpdated");
  await waitUntil(() => !findDebugTargetByText(workerName, document));
}