diff --git a/app/assets/javascripts/notifications_dropdown.js b/app/assets/javascripts/notifications_dropdown.js
index e7fa05faa8af63d935e7bba0eaafb98dae313c42..6aed2492084094a91f349568c9c5f10e51d58555 100644
--- a/app/assets/javascripts/notifications_dropdown.js
+++ b/app/assets/javascripts/notifications_dropdown.js
@@ -4,6 +4,7 @@ import Flash from './flash';
 export default function notificationsDropdown() {
   $(document).on('click', '.update-notification', function updateNotificationCallback(e) {
     e.preventDefault();
+
     if ($(this).is('.is-active') && $(this).data('notificationLevel') === 'custom') {
       return;
     }
diff --git a/package.json b/package.json
index ff6be94b9e27c926f6f4ffef2d164930148d86df..cb063c9782c8651ce5b99e5616f3e8d62254d8a8 100644
--- a/package.json
+++ b/package.json
@@ -118,14 +118,14 @@
     "underscore": "^1.9.0",
     "url-loader": "^1.1.2",
     "visibilityjs": "^1.2.4",
-    "vue": "^2.5.21",
+    "vue": "^2.6.10",
     "vue-apollo": "^3.0.0-beta.28",
-    "vue-loader": "^15.4.2",
+    "vue-loader": "^15.7.0",
     "vue-resource": "^1.5.1",
     "vue-router": "^3.0.2",
-    "vue-template-compiler": "^2.5.21",
-    "vue-virtual-scroll-list": "^1.2.5",
-    "vuex": "^3.0.1",
+    "vue-template-compiler": "^2.6.10",
+    "vue-virtual-scroll-list": "^1.3.1",
+    "vuex": "^3.1.0",
     "webpack": "^4.29.0",
     "webpack-bundle-analyzer": "^3.0.3",
     "webpack-cli": "^3.2.1",
@@ -152,8 +152,8 @@
     "eslint-plugin-import": "^2.14.0",
     "eslint-plugin-jasmine": "^2.10.1",
     "eslint-plugin-jest": "^22.3.0",
-    "gettext-extractor": "^3.3.2",
-    "gettext-extractor-vue": "^4.0.1",
+    "gettext-extractor": "^3.4.3",
+    "gettext-extractor-vue": "^4.0.2",
     "graphql-tag": "^2.10.0",
     "istanbul": "^0.4.5",
     "jasmine-core": "^2.9.0",
diff --git a/spec/javascripts/ide/components/error_message_spec.js b/spec/javascripts/ide/components/error_message_spec.js
index 430e8e2baa3d537c07ab5382eebbb8f747cf962f..80d6c7fd5644e81d532cbd3c91d851ba2cd109de 100644
--- a/spec/javascripts/ide/components/error_message_spec.js
+++ b/spec/javascripts/ide/components/error_message_spec.js
@@ -84,7 +84,7 @@ describe('IDE error message component', () => {
 
       expect(vm.isLoading).toBe(true);
 
-      vm.$nextTick(() => {
+      setTimeout(() => {
         expect(vm.isLoading).toBe(false);
 
         done();
diff --git a/spec/javascripts/ide/stores/actions/file_spec.js b/spec/javascripts/ide/stores/actions/file_spec.js
index 7ddc734ff565cc82344b5b6783f921b400cefe1e..1e5b55af4bae50309add1985c20607585d0f5f76 100644
--- a/spec/javascripts/ide/stores/actions/file_spec.js
+++ b/spec/javascripts/ide/stores/actions/file_spec.js
@@ -121,68 +121,48 @@ describe('IDE store file actions', () => {
       store._actions.scrollToTab = oldScrollToTab; // eslint-disable-line
     });
 
-    it('calls scrollToTab', done => {
-      store
-        .dispatch('setFileActive', localFile.path)
-        .then(() => {
-          expect(scrollToTabSpy).toHaveBeenCalled();
-
-          done();
-        })
-        .catch(done.fail);
-    });
+    it('calls scrollToTab', () => {
+      const dispatch = jasmine.createSpy();
 
-    it('sets the file active', done => {
-      store
-        .dispatch('setFileActive', localFile.path)
-        .then(() => {
-          expect(localFile.active).toBeTruthy();
+      actions.setFileActive(
+        { commit() {}, state: store.state, getters: store.getters, dispatch },
+        localFile.path,
+      );
 
-          done();
-        })
-        .catch(done.fail);
+      expect(dispatch).toHaveBeenCalledWith('scrollToTab');
     });
 
-    it('returns early if file is already active', done => {
-      localFile.active = true;
+    it('commits SET_FILE_ACTIVE', () => {
+      const commit = jasmine.createSpy();
 
-      store
-        .dispatch('setFileActive', localFile.path)
-        .then(() => {
-          expect(scrollToTabSpy).not.toHaveBeenCalled();
+      actions.setFileActive(
+        { commit, state: store.state, getters: store.getters, dispatch() {} },
+        localFile.path,
+      );
 
-          done();
-        })
-        .catch(done.fail);
+      expect(commit).toHaveBeenCalledWith('SET_FILE_ACTIVE', {
+        path: localFile.path,
+        active: true,
+      });
     });
 
-    it('sets current active file to not active', done => {
+    it('sets current active file to not active', () => {
       const f = file('newActive');
       store.state.entries[f.path] = f;
       localFile.active = true;
       store.state.openFiles.push(localFile);
 
-      store
-        .dispatch('setFileActive', f.path)
-        .then(() => {
-          expect(localFile.active).toBeFalsy();
+      const commit = jasmine.createSpy();
 
-          done();
-        })
-        .catch(done.fail);
-    });
-
-    it('resets location.hash for line highlighting', done => {
-      window.location.hash = 'test';
-
-      store
-        .dispatch('setFileActive', localFile.path)
-        .then(() => {
-          expect(window.location.hash).not.toBe('test');
+      actions.setFileActive(
+        { commit, state: store.state, getters: store.getters, dispatch() {} },
+        f.path,
+      );
 
-          done();
-        })
-        .catch(done.fail);
+      expect(commit).toHaveBeenCalledWith('SET_FILE_ACTIVE', {
+        path: localFile.path,
+        active: false,
+      });
     });
   });
 
diff --git a/spec/javascripts/notes/components/note_app_spec.js b/spec/javascripts/notes/components/note_app_spec.js
index d716ece37665c248fe4fbc1213470796bd74cc7d..ef876dc294165f0a35e2abe5b47a2ee8e6c596f1 100644
--- a/spec/javascripts/notes/components/note_app_spec.js
+++ b/spec/javascripts/notes/components/note_app_spec.js
@@ -192,9 +192,9 @@ describe('note_app', () => {
 
         expect(service.updateNote).toHaveBeenCalled();
         // Wait for the requests to finish before destroying
-        Vue.nextTick()
-          .then(done)
-          .catch(done.fail);
+        setTimeout(() => {
+          done();
+        });
       });
     });
 
@@ -227,9 +227,9 @@ describe('note_app', () => {
 
         expect(service.updateNote).toHaveBeenCalled();
         // Wait for the requests to finish before destroying
-        Vue.nextTick()
-          .then(done)
-          .catch(done.fail);
+        setTimeout(() => {
+          done();
+        });
       });
     });
   });
diff --git a/spec/javascripts/pipelines/graph/action_component_spec.js b/spec/javascripts/pipelines/graph/action_component_spec.js
index 3d2232ff23992baa87e47e65f914be45a439a9ea..95717d659b8c23229af5d6afb8027b58cbf6a58c 100644
--- a/spec/javascripts/pipelines/graph/action_component_spec.js
+++ b/spec/javascripts/pipelines/graph/action_component_spec.js
@@ -55,13 +55,16 @@ describe('pipeline graph action component', () => {
 
       component.$el.click();
 
-      component
-        .$nextTick()
-        .then(() => {
-          expect(component.$emit).toHaveBeenCalledWith('pipelineActionRequestComplete');
-        })
-        .then(done)
-        .catch(done.fail);
+      setTimeout(() => {
+        component
+          .$nextTick()
+          .then(() => {
+            expect(component.$emit).toHaveBeenCalledWith('pipelineActionRequestComplete');
+          })
+          .catch(done.fail);
+
+        done();
+      }, 0);
     });
   });
 });
diff --git a/spec/javascripts/pipelines/stage_spec.js b/spec/javascripts/pipelines/stage_spec.js
index 3c8b8032de8f975e381e3380933441f981571985..19ae7860333b396793b4114ba13dd3f9ff217ac6 100644
--- a/spec/javascripts/pipelines/stage_spec.js
+++ b/spec/javascripts/pipelines/stage_spec.js
@@ -120,13 +120,15 @@ describe('Pipelines stage component', () => {
 
         setTimeout(() => {
           component.$el.querySelector('.js-ci-action').click();
-          component
-            .$nextTick()
-            .then(() => {
-              expect(eventHub.$emit).toHaveBeenCalledWith('refreshPipelinesTable');
-            })
-            .then(done)
-            .catch(done.fail);
+          setTimeout(() => {
+            component
+              .$nextTick()
+              .then(() => {
+                expect(eventHub.$emit).toHaveBeenCalledWith('refreshPipelinesTable');
+              })
+              .then(done)
+              .catch(done.fail);
+          }, 0);
         }, 0);
       });
     });
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js
index 030662b4d9096eea4582b94da7f7ee20b4e57529..1eb7cb4bd5b73d6838b64f648a4ff33aa9b2f685 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js
+++ b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js
@@ -53,36 +53,32 @@ describe('GkeProjectIdDropdown', () => {
     });
 
     it('returns default toggle text', done =>
-      vm
-        .$nextTick()
-        .then(() => {
-          vm.setItem(emptyProjectMock);
+      setTimeout(() => {
+        vm.setItem(emptyProjectMock);
 
-          expect(vm.toggleText).toBe(LABELS.DEFAULT);
-          done();
-        })
-        .catch(done.fail));
+        expect(vm.toggleText).toBe(LABELS.DEFAULT);
+
+        done();
+      }));
 
     it('returns project name if project selected', done =>
-      vm
-        .$nextTick()
-        .then(() => {
-          expect(vm.toggleText).toBe(selectedProjectMock.name);
-          done();
-        })
-        .catch(done.fail));
+      setTimeout(() => {
+        vm.isLoading = false;
+
+        expect(vm.toggleText).toBe(selectedProjectMock.name);
+
+        done();
+      }));
 
     it('returns empty toggle text', done =>
-      vm
-        .$nextTick()
-        .then(() => {
-          vm.$store.commit(SET_PROJECTS, null);
-          vm.setItem(emptyProjectMock);
+      setTimeout(() => {
+        vm.$store.commit(SET_PROJECTS, null);
+        vm.setItem(emptyProjectMock);
 
-          expect(vm.toggleText).toBe(LABELS.EMPTY);
-          done();
-        })
-        .catch(done.fail));
+        expect(vm.toggleText).toBe(LABELS.EMPTY);
+
+        done();
+      }));
   });
 
   describe('selectItem', () => {
diff --git a/yarn.lock b/yarn.lock
index fad1aceee484b089e40e69a2b54bb4781d722ec8..2bdbca103b176a376f24857c5183f2903617b449 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -707,10 +707,10 @@
   resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86"
   integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==
 
-"@types/glob@^5":
-  version "5.0.35"
-  resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a"
-  integrity sha512-wc+VveszMLyMWFvXLkloixT4n0harUIVZjnpzztaZ0nKLuul7Z32iMt2fUFGAaZ4y1XWjFRMtCI5ewvyh4aIeg==
+"@types/glob@5 - 7":
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
+  integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
   dependencies:
     "@types/events" "*"
     "@types/minimatch" "*"
@@ -791,7 +791,7 @@
   resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d"
   integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==
 
-"@vue/component-compiler-utils@^2.0.0", "@vue/component-compiler-utils@^2.4.0":
+"@vue/component-compiler-utils@^2.4.0", "@vue/component-compiler-utils@^2.5.1":
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.6.0.tgz#aa46d2a6f7647440b0b8932434d22f12371e543b"
   integrity sha512-IHjxt7LsOFYc0DkTncB7OXJL7UzwOLPPQCfEUNyxL2qt+tF12THV+EO33O1G2Uk4feMSWua3iD39Itszx0f0bw==
@@ -4546,27 +4546,27 @@ getpass@^0.1.1:
   dependencies:
     assert-plus "^1.0.0"
 
-gettext-extractor-vue@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/gettext-extractor-vue/-/gettext-extractor-vue-4.0.1.tgz#69d2737eb8f1938803ffcf9317133ed59fb2372f"
-  integrity sha512-UnkWVO5jQQrs17L7HSlKj3O7U8C4+AQFzE05MK/I+JkMZdQdB6JMjA0IK0c4GObSlkgx4aiCCG6zWqIBnDR95w==
+gettext-extractor-vue@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/gettext-extractor-vue/-/gettext-extractor-vue-4.0.2.tgz#16e1cdbdaf37e5bdf3cb0aff63685bdc5e74e906"
+  integrity sha512-tnTAU1TdQFREv4Q4hfBDuB329eugeFsYmV7lE9U1jkZEyxcf4oPgimLHNZVNaEUg4+JJwhB8B9HIeqbcbSW32g==
   dependencies:
     bluebird "^3.5.1"
     glob "^7.1.2"
-    vue-template-compiler "^2.5.0"
+    vue-template-compiler "^2.5.20"
 
-gettext-extractor@^3.3.2:
-  version "3.3.2"
-  resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.3.2.tgz#d5172ba8d175678bd40a5abe7f908fa2a9d9473b"
-  integrity sha1-1RcrqNF1Z4vUClq+f5CPoqnZRzs=
+gettext-extractor@^3.4.3:
+  version "3.4.3"
+  resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.4.3.tgz#882679cefc71888eb6e69297e6b2dc14c0384fef"
+  integrity sha512-YSNdTCHmzm58Rc21thtXj7jRIOlqINftM3XbtvNK28C88i35EnEB89iOeV9Vetv7wcb/wiPAtcq/6iSnt2pMyw==
   dependencies:
-    "@types/glob" "^5"
+    "@types/glob" "5 - 7"
     "@types/parse5" "^5"
     css-selector-parser "^1.3"
     glob "5 - 7"
     parse5 "^5"
     pofile "^1"
-    typescript "^2"
+    typescript "2 - 3"
 
 glob-parent@^3.1.0:
   version "3.1.0"
@@ -10512,10 +10512,10 @@ typedarray@^0.0.6:
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
   integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
-typescript@^2:
-  version "2.9.2"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
-  integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==
+"typescript@2 - 3":
+  version "3.3.4000"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.4000.tgz#76b0f89cfdbf97827e1112d64f283f1151d6adf0"
+  integrity sha512-jjOcCZvpkl2+z7JFn0yBOoLQyLoIkNZAs/fYJkUG6VKy6zLPHJGfQJYFHzibB6GJaF/8QrcECtlQ5cpvRHSMEA==
 
 uc.micro@^1.0.1, uc.micro@^1.0.5:
   version "1.0.5"
@@ -10938,12 +10938,12 @@ vue-jest@^4.0.0-beta.2:
     source-map "^0.5.6"
     ts-jest "^23.10.5"
 
-vue-loader@^15.4.2:
-  version "15.4.2"
-  resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.4.2.tgz#812bb26e447dd3b84c485eb634190d914ce125e2"
-  integrity sha512-nVV27GNIA9MeoD8yQ3dkUzwlAaAsWeYSWZHsu/K04KCD339lW0Jv2sJWsjj3721SP7sl2lYdPmjcHgkWQSp5bg==
+vue-loader@^15.4.2, vue-loader@^15.7.0:
+  version "15.7.0"
+  resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.7.0.tgz#27275aa5a3ef4958c5379c006dd1436ad04b25b3"
+  integrity sha512-x+NZ4RIthQOxcFclEcs8sXGEWqnZHodL2J9Vq+hUz+TDZzBaDIh1j3d9M2IUlTjtrHTZy4uMuRdTi8BGws7jLA==
   dependencies:
-    "@vue/component-compiler-utils" "^2.0.0"
+    "@vue/component-compiler-utils" "^2.5.1"
     hash-sum "^1.0.2"
     loader-utils "^1.1.0"
     vue-hot-reload-api "^2.3.0"
@@ -10969,10 +10969,10 @@ vue-style-loader@^4.1.0:
     hash-sum "^1.0.2"
     loader-utils "^1.0.2"
 
-vue-template-compiler@^2.5.0, vue-template-compiler@^2.5.21:
-  version "2.5.21"
-  resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.21.tgz#a57ceb903177e8f643560a8d639a0f8db647054a"
-  integrity sha512-Vmk5Cv7UcmI99B9nXJEkaK262IQNnHp5rJYo+EwYpe2epTAXqcVyExhV6pk8jTkxQK2vRc8v8KmZBAwdmUZvvw==
+vue-template-compiler@^2.5.20, vue-template-compiler@^2.6.10:
+  version "2.6.10"
+  resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz#323b4f3495f04faa3503337a82f5d6507799c9cc"
+  integrity sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==
   dependencies:
     de-indent "^1.0.2"
     he "^1.1.0"
@@ -10982,20 +10982,20 @@ vue-template-es2015-compiler@^1.9.0:
   resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
   integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
 
-vue-virtual-scroll-list@^1.2.5:
-  version "1.2.5"
-  resolved "https://registry.yarnpkg.com/vue-virtual-scroll-list/-/vue-virtual-scroll-list-1.2.5.tgz#bcbd010f7cdb035eba8958ebf807c6214d9a167a"
-  integrity sha1-vL0BD3zbA166iVjr+AfGIU2aFno=
+vue-virtual-scroll-list@^1.3.1:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/vue-virtual-scroll-list/-/vue-virtual-scroll-list-1.3.1.tgz#efcb83d3a3dcc69cd886fa4de1130a65493e8f76"
+  integrity sha512-PMTxiK9/P1LtgoWWw4n1QnmDDkYqIdWWCNdt1L4JD9g6rwDgnsGsSV10bAnd5n7DQLHGWHjRex+zAbjXWT8t0g==
 
-vue@^2.5.21:
-  version "2.5.21"
-  resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85"
-  integrity sha512-Aejvyyfhn0zjVeLvXd70h4hrE4zZDx1wfZqia6ekkobLmUZ+vNFQer53B4fu0EjWBSiqApxPejzkO1Znt3joxQ==
+vue@^2.5.21, vue@^2.6.10:
+  version "2.6.10"
+  resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
+  integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==
 
-vuex@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.0.1.tgz#e761352ebe0af537d4bb755a9b9dc4be3df7efd2"
-  integrity sha512-wLoqz0B7DSZtgbWL1ShIBBCjv22GV5U+vcBFox658g6V0s4wZV9P4YjCNyoHSyIBpj1f29JBoNQIqD82cR4O3w==
+vuex@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.1.0.tgz#634b81515cf0cfe976bd1ffe9601755e51f843b9"
+  integrity sha512-mdHeHT/7u4BncpUZMlxNaIdcN/HIt1GsGG5LKByArvYG/v6DvHcOxvDCts+7SRdCoIRGllK8IMZvQtQXLppDYg==
 
 w3c-hr-time@^1.0.1:
   version "1.0.1"