diff --git a/frontend/test/__support__/integrated_tests.js b/frontend/test/__support__/integrated_tests.js
index b6331c3e7bd84ec3c07ccfd0c71a637874c2ee6b..712b26dd9974072427f6950c26486178978d3117 100644
--- a/frontend/test/__support__/integrated_tests.js
+++ b/frontend/test/__support__/integrated_tests.js
@@ -191,23 +191,24 @@ const testStoreEnhancer = (createStore, history, getRoutes) => {
         const testStoreExtensions = {
             _originalDispatch: store.dispatch,
             _onActionDispatched: null,
-            _dispatchedActions: [],
+            _allDispatchedActions: [],
+            _latestDispatchedActions: [],
             _finalStoreInstance: null,
 
             dispatch: (action) => {
                 const result = store._originalDispatch(action);
-                store._dispatchedActions = store._dispatchedActions.concat([{
+
+                const actionWithTimestamp = [{
                     ...action,
                     timestamp: Date.now()
-                }]);
+                }]
+                store._allDispatchedActions = store._allDispatchedActions.concat(actionWithTimestamp);
+                store._latestDispatchedActions = store._latestDispatchedActions.concat(actionWithTimestamp);
+
                 if (store._onActionDispatched) store._onActionDispatched();
                 return result;
             },
 
-            resetDispatchedActions: () => {
-                store._dispatchedActions = [];
-            },
-
             /**
              * Waits until all actions with given type identifiers have been called or fails if the maximum waiting
              * time defined in `timeout` is exceeded.
@@ -221,8 +222,14 @@ const testStoreEnhancer = (createStore, history, getRoutes) => {
 
                 actionTypes = Array.isArray(actionTypes) ? actionTypes : [actionTypes]
 
+                // Returns all actions that are triggered after the last action which belongs to `actionTypes
+                const getRemainingActions = () => {
+                    const lastActionIndex = _.findLastIndex(store._latestDispatchedActions, (action) => actionTypes.includes(action.type))
+                    return store._latestDispatchedActions.slice(lastActionIndex + 1)
+                }
+
                 const allActionsAreTriggered = () => _.every(actionTypes, actionType =>
-                    store._dispatchedActions.filter((action) => action.type === actionType).length > 0
+                    store._latestDispatchedActions.filter((action) => action.type === actionType).length > 0
                 );
 
                 if (allActionsAreTriggered()) {
@@ -232,6 +239,7 @@ const testStoreEnhancer = (createStore, history, getRoutes) => {
                     return new Promise((resolve, reject) => {
                         store._onActionDispatched = () => {
                             if (allActionsAreTriggered()) {
+                                store._latestDispatchedActions = getRemainingActions();
                                 store._onActionDispatched = null;
                                 resolve()
                             }
@@ -241,14 +249,17 @@ const testStoreEnhancer = (createStore, history, getRoutes) => {
 
                             if (allActionsAreTriggered()) {
                                 // TODO: Figure out why we sometimes end up here instead of _onActionDispatched hook
+                                store._latestDispatchedActions = getRemainingActions();
                                 resolve()
                             } else {
                                 return reject(
                                     new Error(
                                         `These actions were not dispatched within ${timeout}ms:\n` +
                                         chalk.cyan(actionTypes.join("\n")) +
-                                        "\n\nDispatched actions since initialization / last call of `store.resetDispatchedActions()`:\n" +
-                                        (store._dispatchedActions.map(store._formatDispatchedAction).join("\n") || "No dispatched actions")
+                                        "\n\nDispatched actions since the last call of `waitForActions`:\n" +
+                                        (store._latestDispatchedActions.map(store._formatDispatchedAction).join("\n") || "No dispatched actions") +
+                                        "\n\nDispatched actions since the initialization of test suite:\n" +
+                                        (store._allDispatchedActions.map(store._formatDispatchedAction).join("\n") || "No dispatched actions")
                                     )
                                 )
                             }
@@ -260,8 +271,10 @@ const testStoreEnhancer = (createStore, history, getRoutes) => {
 
             logDispatchedActions: () => {
                 console.log(
-                    chalk.bold("\n\nDispatched actions since initialization / last call of `store.resetDispatchedActions()`:\n") +
-                    store._dispatchedActions.map(store._formatDispatchedAction).join("\n") || "No dispatched actions"
+                    chalk.bold("Dispatched actions since last call of `waitForActions`:\n") +
+                    (store._latestDispatchedActions.map(store._formatDispatchedAction).join("\n") || "No dispatched actions") +
+                    chalk.bold("\n\nDispatched actions since initialization of test suite:\n") +
+                    store._allDispatchedActions.map(store._formatDispatchedAction).join("\n") || "No dispatched actions"
                 )
             },
 
diff --git a/frontend/test/admin/datamodel/FieldApp.integ.spec.js b/frontend/test/admin/datamodel/FieldApp.integ.spec.js
index cad966f5918a678d1aa5afac16aa538e45bd4a55..f43cd62ef9fc2c4dd5de70a6590a7e51e623fae9 100644
--- a/frontend/test/admin/datamodel/FieldApp.integ.spec.js
+++ b/frontend/test/admin/datamodel/FieldApp.integ.spec.js
@@ -61,7 +61,6 @@ const initFieldApp = async ({ tableId = 1, fieldId }) => {
     store.pushPath(`/admin/datamodel/database/1/table/${tableId}/${fieldId}`);
     const fieldApp = mount(store.connectContainer(<FieldApp />));
     await store.waitForActions([FETCH_IDFIELDS]);
-    store.resetDispatchedActions();
     return { store, fieldApp }
 }
 
@@ -87,7 +86,6 @@ describe("FieldApp", () => {
 
             setInputValue(nameInput, newTitle);
             await store.waitForActions([UPDATE_FIELD])
-            store.resetDispatchedActions();
 
             setInputValue(descriptionInput, newDescription);
             await store.waitForActions([UPDATE_FIELD])
@@ -200,7 +198,6 @@ describe("FieldApp", () => {
             const foreignKeyButton = typeSelect.find(TestPopover).find("li").at(2).children().first();
             click(foreignKeyButton);
             await store.waitForActions([UPDATE_FIELD])
-            store.resetDispatchedActions();
 
             expect(picker.text()).toMatch(/Foreign KeySelect a target/);
             const fkFieldSelect = picker.find(Select).at(1)
@@ -254,7 +251,6 @@ describe("FieldApp", () => {
             const useFKButton = pickerOptions.at(1).children().first()
             click(useFKButton);
             store.waitForActions([UPDATE_FIELD_DIMENSION, FETCH_TABLE_METADATA])
-            store.resetDispatchedActions();
             // TODO: Figure out a way to avoid using delay – the use of delays may lead to occasional CI failures
             await delay(500);
 
diff --git a/frontend/test/admin/datamodel/datamodel.integ.spec.js b/frontend/test/admin/datamodel/datamodel.integ.spec.js
index 213685b78a04ba92cc49293fd5583566d1081d34..bf9ab6dc76efdbfce49ddd696754d6e1220ca0a6 100644
--- a/frontend/test/admin/datamodel/datamodel.integ.spec.js
+++ b/frontend/test/admin/datamodel/datamodel.integ.spec.js
@@ -51,17 +51,14 @@ describe("admin/datamodel", () => {
             const adminListItems = app.find(".AdminList-item");
             click(adminListItems.at(0));
             await store.waitForActions([SELECT_TABLE]);
-            store.resetDispatchedActions()
 
             // Toggle its visibility to "Hidden"
             click(app.find("#VisibilityTypes > span").at(1))
             await store.waitForActions([UPDATE_TABLE]);
-            store.resetDispatchedActions()
 
             // Toggle "Why hide" to "Irrelevant/Cruft"
             click(app.find("#VisibilitySubTypes > span").at(2))
             await store.waitForActions([UPDATE_TABLE]);
-            store.resetDispatchedActions()
 
             // Unhide
             click(app.find("#VisibilityTypes > span").at(0))
@@ -69,7 +66,6 @@ describe("admin/datamodel", () => {
             // Open "People" table section
             click(adminListItems.at(1));
             await store.waitForActions([SELECT_TABLE]);
-            store.resetDispatchedActions()
 
             // hide fields from people table
             // Set Address field to "Only in Detail Views"
@@ -80,7 +76,6 @@ describe("admin/datamodel", () => {
             expect(onlyInDetailViewsRow.text()).toMatch(/Only in Detail Views/);
             click(onlyInDetailViewsRow);
             await store.waitForActions([UPDATE_FIELD]);
-            store.resetDispatchedActions();
 
             // Set Birth Date field to "Do Not Include"
             click(columnsListItems.at(1).find(".TableEditor-field-visibility"));
@@ -90,7 +85,6 @@ describe("admin/datamodel", () => {
             click(doNotIncludeRow);
 
             await store.waitForActions([UPDATE_FIELD]);
-            store.resetDispatchedActions();
 
             // modify special type for address field
             click(columnsListItems.first().find(".TableEditor-field-special-type"))
@@ -110,13 +104,11 @@ describe("admin/datamodel", () => {
             const app = mount(store.getAppContainer())
 
             await store.waitForActions([INITIALIZE_METADATA, FETCH_IDFIELDS]);
-            store.resetDispatchedActions();
 
             // Click the new segment button and check that we get properly redirected
             click(app.find(SegmentsList).find(Link));
             expect(store.getPath()).toBe('/admin/datamodel/segment/create?table=2')
             await store.waitForActions([FETCH_TABLE_METADATA, UPDATE_PREVIEW_SUMMARY]);
-            store.resetDispatchedActions();
 
             // Add "Email Is Not gmail" filter
             click(app.find(".GuiBuilder-filtered-by a").first())
@@ -142,7 +134,6 @@ describe("admin/datamodel", () => {
             click(app.find('button[children="Save changes"]'))
 
             await store.waitForActions([CREATE_SEGMENT, INITIALIZE_METADATA]);
-            store.resetDispatchedActions();
             expect(store.getPath()).toBe("/admin/datamodel/database/1/table/2")
 
             // Validate that the segment got actually added
@@ -157,7 +148,6 @@ describe("admin/datamodel", () => {
             const app = mount(store.getAppContainer())
 
             await store.waitForActions([INITIALIZE_METADATA, FETCH_IDFIELDS]);
-            store.resetDispatchedActions();
 
             // Click the new metric button and check that we get properly redirected
             click(app.find(MetricsList).find(Link));
diff --git a/frontend/test/parameters/parameters.integ.spec.js b/frontend/test/parameters/parameters.integ.spec.js
index b57e4d2b112de859de85c946b5aeccbb9abeb8c3..98b586db144fba1b56709c2244a0603ce25d01bc 100644
--- a/frontend/test/parameters/parameters.integ.spec.js
+++ b/frontend/test/parameters/parameters.integ.spec.js
@@ -126,7 +126,6 @@ describe("parameters", () => {
 
             click(app.find(".Icon-sql"));
             await store.waitForActions([SET_QUERY_MODE]);
-            store.resetDispatchedActions();
 
             await updateQueryText(store, "select count(*) from products where {{category}}");
 
@@ -137,7 +136,6 @@ describe("parameters", () => {
             click(fieldFilterVarType);
 
             await store.waitForActions([UPDATE_TEMPLATE_TAG]);
-            store.resetDispatchedActions();
 
             await delay(100);
 
@@ -154,7 +152,6 @@ describe("parameters", () => {
             // test without the parameter
             click(app.find(RunButton));
             await store.waitForActions([RUN_QUERY, QUERY_COMPLETED])
-            await store.resetDispatchedActions();
             expect(app.find(Scalar).text()).toBe(COUNT_ALL);
 
             // test the parameter
@@ -215,7 +212,6 @@ describe("parameters", () => {
                 const app = mount(store.getAppContainer())
 
                 await store.waitForActions([ADD_PARAM_VALUES]);
-                store.resetDispatchedActions();
 
                 // Loading the query results is done in PublicQuestion itself so we have to add a delay here
                 await delay(200);
diff --git a/frontend/test/query_builder/components/dataref/FieldPane.integ.spec.js b/frontend/test/query_builder/components/dataref/FieldPane.integ.spec.js
index d721eafbcfe2d36a06520a09d6aec06b6441d4ab..404e74e26a4a28d2a741cdeaa808c0ee706cf760 100644
--- a/frontend/test/query_builder/components/dataref/FieldPane.integ.spec.js
+++ b/frontend/test/query_builder/components/dataref/FieldPane.integ.spec.js
@@ -67,7 +67,6 @@ describe("FieldPane", () => {
 
         click(getUseForButton());
         await store.waitForActions([QUERY_COMPLETED]);
-        store.resetDispatchedActions()
 
         // after the breakout has been applied, the button shouldn't be visible anymore
         expect(getUseForButton().length).toBe(0);
@@ -84,7 +83,6 @@ describe("FieldPane", () => {
         }
 
         await store.waitForActions([QUERY_COMPLETED]);
-        store.resetDispatchedActions()
 
         expect(queryBuilder.find(Table).length).toBe(1)
     });
diff --git a/frontend/test/query_builder/components/dataref/MetricPane.integ.spec.js b/frontend/test/query_builder/components/dataref/MetricPane.integ.spec.js
index 8697aeb67be15fcd161e84bbe609859b7329caec..c2e37b1ec0e95e61c54449b550f8792829001103 100644
--- a/frontend/test/query_builder/components/dataref/MetricPane.integ.spec.js
+++ b/frontend/test/query_builder/components/dataref/MetricPane.integ.spec.js
@@ -50,7 +50,6 @@ describe("MetricPane", () => {
         // then we can replace this with `store.waitForActions([FETCH_TABLE_FOREIGN_KEYS])` or similar
         await delay(3000)
 
-        store.resetDispatchedActions() // make sure that we wait for the newest actions
         click(dataReference.find(`a[children="${vendor_count_metric.name}"]`).first())
 
         await store.waitForActions([FETCH_TABLE_METADATA]);
diff --git a/frontend/test/query_builder/components/dataref/SegmentPane.integ.spec.js b/frontend/test/query_builder/components/dataref/SegmentPane.integ.spec.js
index 20fdd89fb458b0ffa766abff38f8a246274054c8..b4a3770b231898ddc38bfa238b2c22d6442bca9d 100644
--- a/frontend/test/query_builder/components/dataref/SegmentPane.integ.spec.js
+++ b/frontend/test/query_builder/components/dataref/SegmentPane.integ.spec.js
@@ -64,7 +64,6 @@ describe("SegmentPane", () => {
         // then we can replace this with `store.waitForActions([FETCH_TABLE_FOREIGN_KEYS])` or similar
         await delay(3000)
 
-        store.resetDispatchedActions() // make sure that we wait for the newest actions
         click(dataReference.find(`a[children="${orders_past_30_days_segment.name}"]`).first())
 
         await store.waitForActions([FETCH_TABLE_METADATA]);
@@ -84,7 +83,6 @@ describe("SegmentPane", () => {
         click(filterByButton.children().first());
 
         await store.waitForActions([QUERY_COMPLETED]);
-        store.resetDispatchedActions()
 
         expect(queryBuilder.find(DataReference).find(UseForButton).length).toBe(0);
     });
@@ -100,7 +98,6 @@ describe("SegmentPane", () => {
         }
 
         await store.waitForActions([QUERY_COMPLETED]);
-        store.resetDispatchedActions()
 
         // The value changes daily which wasn't originally taken into account
         // expect(queryBuilder.find(Scalar).text()).toBe("1,236")
@@ -118,7 +115,6 @@ describe("SegmentPane", () => {
         }
 
         await store.waitForActions([QUERY_COMPLETED]);
-        store.resetDispatchedActions()
 
         expect(queryBuilder.find(Table).length).toBe(1)
     });
diff --git a/frontend/test/query_builder/query_builder.integ.spec.js b/frontend/test/query_builder/query_builder.integ.spec.js
index a14cbfca8f69b874f53f5717640474b4c0c5a458..302907556e889e671cdbcd9649f65c9c2a02287c 100644
--- a/frontend/test/query_builder/query_builder.integ.spec.js
+++ b/frontend/test/query_builder/query_builder.integ.spec.js
@@ -75,7 +75,6 @@ const initQbWithDbAndTable = (dbId, tableId) => {
         store.dispatch(setQueryDatabase(dbId));
         store.dispatch(setQuerySourceTable(tableId));
         await store.waitForActions([FETCH_TABLE_METADATA]);
-        store.resetDispatchedActions();
 
         return { store, qb }
     }
@@ -307,7 +306,6 @@ describe("QueryBuilder", () => {
                 clickButton(addFilterButton);
 
                 await store.waitForActions([SET_DATASET_QUERY])
-                store.resetDispatchedActions();
 
                 expect(qb.find(FilterPopover).length).toBe(0);
                 const filterWidget = qb.find(FilterWidget);
@@ -385,7 +383,6 @@ describe("QueryBuilder", () => {
                 clickButton(addFilterButton);
 
                 await store.waitForActions([SET_DATASET_QUERY])
-                store.resetDispatchedActions();
 
                 expect(qb.find(FilterPopover).length).toBe(0);
                 const filterWidget = qb.find(FilterWidget);
@@ -492,7 +489,6 @@ describe("QueryBuilder", () => {
                 expect(breakoutWidget.text()).toBe("Total: 100 bins");
             });
             it("produces correct results for 100 bins", async () => {
-                store.resetDispatchedActions();
                 click(qb.find(RunButton));
                 await store.waitForActions([QUERY_COMPLETED]);
 
@@ -515,7 +511,6 @@ describe("QueryBuilder", () => {
                 click(qb.find(DimensionPicker).find('a[children="Don\'t bin"]'));
             });
             it("produces the expected count of rows when no binning", async () => {
-                store.resetDispatchedActions();
                 click(qb.find(RunButton));
                 await store.waitForActions([QUERY_COMPLETED]);
 
@@ -585,7 +580,6 @@ describe("QueryBuilder", () => {
             });
             it("produces correct results for 'Bin every 1 degree'", async () => {
                 // Run the raw data query
-                store.resetDispatchedActions();
                 click(qb.find(RunButton));
                 await store.waitForActions([QUERY_COMPLETED]);
 
@@ -631,7 +625,6 @@ describe("QueryBuilder", () => {
                 // Drill-through is delayed in handleVisualizationClick of Visualization.jsx by 100ms
                 await delay(150);
 
-                store.resetDispatchedActions();
                 click(qb.find(ChartClickActions).find('div[children="Zoom in"]'));
 
                 store.waitForActions([NAVIGATE_TO_NEW_CARD, UPDATE_URL, QUERY_COMPLETED]);
@@ -673,7 +666,6 @@ describe("QueryBuilder", () => {
                 // Drill-through is delayed in handleVisualizationClick of Visualization.jsx by 100ms
                 await delay(150);
 
-                store.resetDispatchedActions();
                 click(qb.find(ChartClickActions).find('div[children="Zoom in"]'));
 
                 store.waitForActions([NAVIGATE_TO_NEW_CARD, UPDATE_URL, QUERY_COMPLETED]);
@@ -719,7 +711,6 @@ describe("QueryBuilder", () => {
                 // Drill-through is delayed in handleVisualizationClick of Visualization.jsx by 100ms
                 await delay(150);
 
-                store.resetDispatchedActions();
                 click(qb.find(ChartClickActions).find('div[children="Zoom in"]'));
 
                 store.waitForActions([NAVIGATE_TO_NEW_CARD, UPDATE_URL, QUERY_COMPLETED]);
@@ -797,7 +788,6 @@ describe("QueryBuilder", () => {
                 clickButton(addFilterButton);
 
                 await store.waitForActions([SET_DATASET_QUERY])
-                store.resetDispatchedActions();
 
                 // validate the filter text value
                 expect(qb.find(FilterPopover).length).toBe(0);