Bug 1654762 - Wait for store-objects-updated event in Storage Inspector init r=nchevobbe
authorJulian Descottes <jdescottes@mozilla.com>
Fri, 24 Jul 2020 11:37:31 +0000
changeset 542091 dfa63a8802e7e2b2ff86bebf725f0ac0aa8f48e0
parent 542090 feb3ad4b4a25f6935423d38b95866b0f488e03ff
child 542092 992c574a2e33cb6ec228ddce47cc60171780e354
push id122630
push userjdescottes@mozilla.com
push dateFri, 24 Jul 2020 18:18:20 +0000
treeherderautoland@dfa63a8802e7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnchevobbe
bugs1654762
milestone80.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 1654762 - Wait for store-objects-updated event in Storage Inspector init r=nchevobbe Depends on D84689 The test failures are coming from a race condition which became visible with the previous patch in the stack. The storage inspector head.js waits for an event emitted by the UI when opening the panel. But now that we don't have to wait for the 4 actorHasMethod calls, the event is emitted before the test can listen for it. One option is to let onTargetAvailable wait for the event instead, so that the Storage panel is only initialized when the store-objects-updated was fired. This way, the test harness no longer has to wait for this event. Differential Revision: https://phabricator.services.mozilla.com/D84788
devtools/client/storage/test/head.js
devtools/client/storage/ui.js
--- a/devtools/client/storage/test/head.js
+++ b/devtools/client/storage/test/head.js
@@ -172,19 +172,16 @@ var openStoragePanel = async function(cb
   gPanelWindow = storage.panelWindow;
   gUI = storage.UI;
   gToolbox = toolbox;
 
   // The table animation flash causes some timeouts on Linux debug tests,
   // so we disable it
   gUI.animationsEnabled = false;
 
-  info("Waiting for the stores to update");
-  await gUI.once("store-objects-updated");
-
   await waitForToolboxFrameFocus(toolbox);
 
   if (cb) {
     return cb(storage, toolbox);
   }
 
   return {
     toolbox: toolbox,
--- a/devtools/client/storage/ui.js
+++ b/devtools/client/storage/ui.js
@@ -308,17 +308,17 @@ class StorageUI {
           if (SAFE_HOSTS_PREFIXES_REGEX.test(host)) {
             newHosts[host] = dbs;
           }
         }
 
         storageTypes.indexedDB.hosts = newHosts;
       }
 
-      this.populateStorageTree(storageTypes);
+      await this.populateStorageTree(storageTypes);
     } catch (e) {
       if (!this._toolbox || this._toolbox._destroyer) {
         // The toolbox is in the process of being destroyed... in this case throwing here
         // is expected and normal so let's ignore the error.
         return;
       }
 
       // The toolbox is open so the error is unexpected and real so let's log it.
@@ -859,18 +859,32 @@ class StorageUI {
   /**
    * Populates the storage tree which displays the list of storages present for
    * the page.
    *
    * @param {object} storageTypes
    *        List of storages and their corresponding hosts returned by the
    *        StorageFront.listStores call.
    */
-  populateStorageTree(storageTypes) {
+  async populateStorageTree(storageTypes) {
     this.storageTypes = {};
+
+    // When can we expect the "store-objects-updated" event?
+    //   -> TreeWidget setter `selectedItem` emits a "select" event
+    //   -> on tree "select" event, this module calls `onHostSelect`
+    //   -> finally `onHostSelect` calls `fetchStorageObjects`, which will emit
+    //      "store-objects-updated" at the end of the method.
+    // So if the selection changed, we can wait for "store-objects-updated",
+    // which is emitted at the end of `fetchStorageObjects`.
+    const onStoresObjectsUpdated = this.once("store-objects-updated");
+
+    // Save the initially selected item to check if tree.selected was updated,
+    // see comment above.
+    const initialSelectedItem = this.tree.selectedItem;
+
     for (const type in storageTypes) {
       // Ignore `from` field, which is just a protocol.js implementation
       // artifact.
       if (type === "from") {
         continue;
       }
       let typeLabel = type;
       try {
@@ -897,16 +911,20 @@ class StorageUI {
             // Do Nothing
           }
         }
         if (!this.tree.selectedItem) {
           this.tree.selectedItem = [type, host];
         }
       }
     }
+
+    if (initialSelectedItem !== this.tree.selectedItem) {
+      await onStoresObjectsUpdated;
+    }
   }
 
   /**
    * Populates the selected entry from the table in the sidebar for a more
    * detailed view.
    */
   /* eslint-disable-next-line */
   async updateObjectSidebar() {