summaryrefslogtreecommitdiffstats
path: root/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_remote_runtime.js
blob: 607b8e15b49949359fed70b5f1f7402a92a3ae08 (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
/* 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";

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

  const { document, tab, window } = await openAboutDebugging();
  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);
  await testAddonsOnMockedRemoteClient(
    usbClient,
    mocks.thisFirefoxClient,
    document
  );

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

  info("Test addons in runtime page for Network client");
  await connectToRuntime(NETWORK_RUNTIME_HOST, document);
  await selectRuntime(NETWORK_RUNTIME_HOST, NETWORK_RUNTIME_APP_NAME, document);
  await testAddonsOnMockedRemoteClient(
    networkClient,
    mocks.thisFirefoxClient,
    document
  );

  await removeTab(tab);
});

/**
 * Check that addons are visible in the runtime page for a remote client (USB or network).
 */
async function testAddonsOnMockedRemoteClient(
  remoteClient,
  firefoxClient,
  document
) {
  const extensionPane = getDebugTargetPane("Extensions", document);
  info("Check an empty target pane message is displayed");
  ok(
    extensionPane.querySelector(".qa-debug-target-list-empty"),
    "Extensions list is empty"
  );

  info("Add an extension to the remote client");
  const addon = { name: "Test extension name", debuggable: true };
  const temporaryAddon = {
    name: "Test temporary extension",
    debuggable: true,
    temporarilyInstalled: true,
  };
  remoteClient.listAddons = () => [addon, temporaryAddon];
  remoteClient._eventEmitter.emit("addonListChanged");

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

  const extensionTarget = findDebugTargetByText(
    "Test extension name",
    document
  );
  ok(extensionTarget, "Extension target appeared for the remote runtime");

  const temporaryExtensionTarget = findDebugTargetByText(
    "Test temporary extension",
    document
  );
  ok(
    temporaryExtensionTarget,
    "Temporary Extension target appeared for the remote runtime"
  );

  const removeButton = temporaryExtensionTarget.querySelector(
    ".qa-temporary-extension-remove-button"
  );
  ok(removeButton, "Remove button expected for the temporary extension");

  const reloadButton = temporaryExtensionTarget.querySelector(
    ".qa-temporary-extension-reload-button"
  );
  ok(reloadButton, "Reload button expected for the temporary extension");

  // The goal here is to check that runtimes addons are only updated when the remote
  // runtime is sending addonListChanged events. The reason for this test is because the
  // previous implementation was updating the remote runtime extensions list when the
  // _local_ AddonManager was updated.
  info("Remove the extension from the remote client WITHOUT sending an event");
  remoteClient.listAddons = () => [];

  info("Simulate an addon update on the ThisFirefox client");
  firefoxClient._eventEmitter.emit("addonListChanged");

  // To avoid wait for a set period of time we trigger another async update, adding a new
  // tab. We assume that if the addon 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("Test extension name", document),
    "The test extension is still visible"
  );

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