Bug 1497457 - Test runtime is still connected after about:debugging reload;r=daisuke,ladybenko
authorJulian Descottes <jdescottes@mozilla.com>
Tue, 27 Nov 2018 10:17:55 +0000
changeset 448223 162b26b027a5b63242d37b6c8135ca2171295755
parent 448222 fe4c1c6d7ebf20056824d489e085856b507f4bdf
child 448224 f0c4ce1b0cf99f1d14093327810c9b9ae6ff1191
push id35107
push userrmaries@mozilla.com
push dateTue, 27 Nov 2018 17:30:25 +0000
treeherdermozilla-central@8be20508c9d5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdaisuke, ladybenko
bugs1497457
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1497457 - Test runtime is still connected after about:debugging reload;r=daisuke,ladybenko Depends on D11993 Differential Revision: https://phabricator.services.mozilla.com/D12039
devtools/client/aboutdebugging-new/test/browser/browser.ini
devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_persist_connection.js
devtools/client/aboutdebugging-new/test/browser/head.js
devtools/client/aboutdebugging-new/test/browser/mocks/head-usb-mocks.js
--- a/devtools/client/aboutdebugging-new/test/browser/browser.ini
+++ b/devtools/client/aboutdebugging-new/test/browser/browser.ini
@@ -22,16 +22,17 @@ support-files =
 [browser_aboutdebugging_connect_toggle_usb_devices.js]
 skip-if = (os == 'linux' && bits == 32) # ADB start() fails on linux 32, see Bug 1499638
 [browser_aboutdebugging_connection_prompt_setting.js]
 [browser_aboutdebugging_debug-target-pane_collapsibilities_interaction.js]
 [browser_aboutdebugging_debug-target-pane_collapsibilities_preference.js]
 [browser_aboutdebugging_debug-target-pane_empty.js]
 [browser_aboutdebugging_debug-target-pane_usb_runtime.js]
 [browser_aboutdebugging_navigate.js]
+[browser_aboutdebugging_persist_connection.js]
 [browser_aboutdebugging_sidebar_network_runtimes.js]
 [browser_aboutdebugging_sidebar_usb_runtime.js]
 [browser_aboutdebugging_sidebar_usb_runtime_connect.js]
 [browser_aboutdebugging_sidebar_usb_runtime_refresh.js]
 [browser_aboutdebugging_sidebar_usb_status.js]
 skip-if = (os == 'linux' && bits == 32) # ADB start() fails on linux 32, see Bug 1499638
 [browser_aboutdebugging_system_addons.js]
 [browser_aboutdebugging_tab_favicons.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_persist_connection.js
@@ -0,0 +1,50 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const RUNTIME_ID = "test-runtime-id";
+const RUNTIME_DEVICE_NAME = "test device name";
+const RUNTIME_APP_NAME = "TestApp";
+
+/* import-globals-from mocks/head-usb-mocks.js */
+Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "mocks/head-usb-mocks.js", this);
+
+// Test that remote runtime connections are persisted across about:debugging reloads.
+add_task(async function() {
+  const usbMocks = new UsbMocks();
+  usbMocks.enableMocks();
+  registerCleanupFunction(() => usbMocks.disableMocks());
+
+  let { document, tab } = await openAboutDebugging();
+
+  const usbClient = usbMocks.createRuntime(RUNTIME_ID, {
+    name: RUNTIME_APP_NAME,
+    deviceName: RUNTIME_DEVICE_NAME,
+  });
+  usbMocks.emitUpdate();
+
+  await connectToRuntime(RUNTIME_DEVICE_NAME, RUNTIME_APP_NAME, document);
+
+  info("Reload about:debugging");
+  document = await reloadAboutDebugging(tab);
+  usbMocks.emitUpdate();
+
+  info("Wait until the remote runtime appears as connected");
+  await waitUntil(() => {
+    const sidebarItem = findSidebarItemByText(RUNTIME_DEVICE_NAME, document);
+    return sidebarItem && !sidebarItem.querySelector(".js-connect-button");
+  });
+
+  // Remove the runtime without emitting an update.
+  // This is what happens today when we simply close Firefox for Android.
+  info("Remove the runtime from the list of USB runtimes");
+  usbMocks.removeRuntime(RUNTIME_ID);
+
+  info("Emit 'closed' on the client and wait for the sidebar item to disappear");
+  usbClient._eventEmitter.emit("closed");
+  await waitUntil(() => !findSidebarItemByText(RUNTIME_DEVICE_NAME, document));
+
+  info("Remove the tab");
+  await removeTab(tab);
+});
--- a/devtools/client/aboutdebugging-new/test/browser/head.js
+++ b/devtools/client/aboutdebugging-new/test/browser/head.js
@@ -41,29 +41,47 @@ async function enableNewAboutDebugging()
   await pushPref("devtools.aboutdebugging.new-enabled", true);
   await pushPref("devtools.aboutdebugging.network", true);
 }
 
 async function openAboutDebugging(page, win) {
   await enableNewAboutDebugging();
 
   info("opening about:debugging");
+
   const tab = await addTab("about:debugging", { window: win });
   const browser = tab.linkedBrowser;
   const document = browser.contentDocument;
   const window = browser.contentWindow;
-  const { AboutDebugging } = window;
+  await waitForInitialDispatch(window);
+
+  return { tab, document, window };
+}
+
+async function reloadAboutDebugging(tab) {
+  info("reload about:debugging");
 
-  await Promise.all([
+  await refreshTab(tab);
+  const browser = tab.linkedBrowser;
+  const document = browser.contentDocument;
+  const window = browser.contentWindow;
+  await waitForInitialDispatch(window);
+
+  return document;
+}
+
+function waitForInitialDispatch(win) {
+  info("wait for the initial about debugging actions to be dispatched");
+
+  const { AboutDebugging } = win;
+  return Promise.all([
     waitForDispatch(AboutDebugging.store, "REQUEST_EXTENSIONS_SUCCESS"),
     waitForDispatch(AboutDebugging.store, "REQUEST_TABS_SUCCESS"),
     waitForDispatch(AboutDebugging.store, "REQUEST_WORKERS_SUCCESS"),
   ]);
-
-  return { tab, document, window };
 }
 
 /**
  * Wait for all client requests to settle, meaning here that no new request has been
  * dispatched after the provided delay.
  */
 async function waitForRequestsToSettle(store, delay = 500) {
   let hasSettled = false;
--- a/devtools/client/aboutdebugging-new/test/browser/mocks/head-usb-mocks.js
+++ b/devtools/client/aboutdebugging-new/test/browser/mocks/head-usb-mocks.js
@@ -23,16 +23,22 @@ class UsbMocks {
   constructor() {
     // Setup the usb-runtimes mock to rely on the internal _runtimes array.
     this.usbRuntimesMock = createUsbRuntimesMock();
     this._runtimes = [];
     this.usbRuntimesMock.getUSBRuntimes = () => {
       return this._runtimes;
     };
 
+    // refreshUSBRuntimes normally starts scan, which should ultimately fire the
+    // "runtime-list-updated" event.
+    this.usbRuntimesMock.refreshUSBRuntimes = () => {
+      this.emitUpdate();
+    };
+
     // Prepare a fake observer to be able to emit events from this mock.
     this._observerMock = addObserverMock(this.usbRuntimesMock);
 
     // Setup the runtime-client-factory mock to rely on the internal _clients map.
     this.runtimeClientFactoryMock = createRuntimeClientFactoryMock();
     this._clients = {};
     this.runtimeClientFactoryMock.createClientForRuntime = runtime => {
       return { clientWrapper: this._clients[runtime.id] };