From 7e1b1f7a7c24caa883776497cff9fe18f85af96a Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 11:46:00 +0300 Subject: [PATCH 01/12] chore(babel): support async/await, add transform-runtime --- .babelrc | 2 +- package.json | 1 + yarn.lock | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.babelrc b/.babelrc index 92119bf2c..a7acc43cb 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,4 @@ { "presets": ["env", "flow-vue"], - "plugins": ["syntax-dynamic-import"] + "plugins": ["syntax-dynamic-import", "transform-runtime"] } diff --git a/package.json b/package.json index 819a11093..dd2ae80ec 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "babel-eslint": "^10.0.1", "babel-loader": "^7.1.3", "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.6.1", "babel-preset-flow-vue": "^1.0.0", "browserstack-local": "^1.4.0", diff --git a/yarn.lock b/yarn.lock index 319063627..8b8223f44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2017,6 +2017,13 @@ babel-plugin-transform-regenerator@^6.22.0: dependencies: regenerator-transform "^0.10.0" +babel-plugin-transform-runtime@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee" + integrity sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4= + dependencies: + babel-runtime "^6.22.0" + babel-plugin-transform-strict-mode@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" From 9bb5f1b72d7f46d8996587b31e757f4369b000ca Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 11:57:22 +0300 Subject: [PATCH 02/12] fix: thrown async/await on router.onError --- src/history/base.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/history/base.js b/src/history/base.js index fbdf25696..c99da4a68 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -126,12 +126,12 @@ export class History { ) this.pending = route - const iterator = (hook: NavigationGuard, next) => { + const iterator = async (hook: NavigationGuard, next) => { if (this.pending !== route) { return abort() } try { - hook(route, current, (to: any) => { + await hook(route, current, (to: any) => { if (to === false || isError(to)) { // next(false) -> abort navigation, ensure current URL this.ensureURL(true) From 2a36de22cb22b8c432417b42ba5527b34faacbaf Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 12:46:17 +0300 Subject: [PATCH 03/12] chore(test): coverage async router.beforeEach --- test/unit/specs/error-handling.spec.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/unit/specs/error-handling.spec.js b/test/unit/specs/error-handling.spec.js index b912dca62..03c2cd3f0 100644 --- a/test/unit/specs/error-handling.spec.js +++ b/test/unit/specs/error-handling.spec.js @@ -52,4 +52,21 @@ describe('error handling', () => { expect(spy1).toHaveBeenCalledWith(err) expect(spy2).toHaveBeenCalledWith(err) }) + + // #2833 + it('async router.beforeEach, handle onError', () => { + const router = new VueRouter() + const err = new Error('foo') + const spy = jasmine.createSpy('error') + router.onError(spy) + + router.push('/') + router.beforeEach(async () => { throw err }) + + router.push('/foo', () => { + fail('onError function did not receive an error') + }, () => { + expect(spy).toHaveBeenCalledWith(err) + }) + }) }) From 5dcda8bdbf39d31fce579d8733aeef13a51b595d Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 13:15:14 +0300 Subject: [PATCH 04/12] chore(revert): remove babel transform-runtime --- .babelrc | 2 +- package.json | 1 - yarn.lock | 7 ------- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.babelrc b/.babelrc index a7acc43cb..92119bf2c 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,4 @@ { "presets": ["env", "flow-vue"], - "plugins": ["syntax-dynamic-import", "transform-runtime"] + "plugins": ["syntax-dynamic-import"] } diff --git a/package.json b/package.json index dd2ae80ec..819a11093 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "babel-eslint": "^10.0.1", "babel-loader": "^7.1.3", "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.6.1", "babel-preset-flow-vue": "^1.0.0", "browserstack-local": "^1.4.0", diff --git a/yarn.lock b/yarn.lock index 8b8223f44..319063627 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2017,13 +2017,6 @@ babel-plugin-transform-regenerator@^6.22.0: dependencies: regenerator-transform "^0.10.0" -babel-plugin-transform-runtime@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee" - integrity sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4= - dependencies: - babel-runtime "^6.22.0" - babel-plugin-transform-strict-mode@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" From d8d228610aa740d75e0a41258dbaf6da3f4929e0 Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 14:23:06 +0300 Subject: [PATCH 05/12] chore: rewrite async/await to promise --- src/history/base.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/history/base.js b/src/history/base.js index c99da4a68..cf3737ce1 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -126,12 +126,12 @@ export class History { ) this.pending = route - const iterator = async (hook: NavigationGuard, next) => { + const iterator = (hook: NavigationGuard, next) => { if (this.pending !== route) { return abort() } try { - await hook(route, current, (to: any) => { + const hookResponse = hook(route, current, (to: any) => { if (to === false || isError(to)) { // next(false) -> abort navigation, ensure current URL this.ensureURL(true) @@ -155,6 +155,11 @@ export class History { next(to) } }) + + // Support async/await in guard (#2833) + if (hookResponse instanceof Promise) { + hookResponse.catch(err => abort(err)) + } } catch (e) { abort(e) } From f00d600b73a8384c76744a7b91bfb9f5122a0927 Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 14:24:01 +0300 Subject: [PATCH 06/12] chore: add example template for error-handling --- examples/error-handling/app.js | 62 ++++++++++++++++++++++++++++++ examples/error-handling/index.html | 6 +++ examples/index.html | 1 + 3 files changed, 69 insertions(+) create mode 100644 examples/error-handling/app.js create mode 100644 examples/error-handling/index.html diff --git a/examples/error-handling/app.js b/examples/error-handling/app.js new file mode 100644 index 000000000..e93a3671f --- /dev/null +++ b/examples/error-handling/app.js @@ -0,0 +1,62 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' + +Vue.use(VueRouter) + +// Components +const Home = { template: '
Home
' } +const Default = { template: '
Default
' } +const Sync = { template: '
Sync
' } +const Async = { template: '
Async
' } + +const router = new VueRouter({ + mode: 'history', + base: __dirname, + routes: [ + { path: '/', component: Home, name: 'home' }, + { path: '/default', component: Default, name: 'default' }, + { path: '/sync', component: Sync, name: 'sync' }, + { path: '/async', component: Async, name: 'async' } + ] +}) + +router.onError((err) => { + console.log('Router.onError:', err) +}) + +// Promise same as: +// router.beforeEach(async (to, from, next) => { throw new Error('Async error') }) +router.beforeEach((to, from, next) => { + if (to.name === 'async') { + return new Promise((resolve, reject) => { + reject(new Error('Async error')) + }) + } + + next() +}) + +router.beforeEach((to, from, next) => { + if (to.name === 'sync') { + throw new Error('Sync error') + } + + next() +}) + +new Vue({ + router, + template: ` +
+
+ Open console +
+ /home + /default + /sync + /async +

+ +
+ ` +}).$mount('#app') diff --git a/examples/error-handling/index.html b/examples/error-handling/index.html new file mode 100644 index 000000000..ba4c1585d --- /dev/null +++ b/examples/error-handling/index.html @@ -0,0 +1,6 @@ + + +← Examples index +
+ + diff --git a/examples/index.html b/examples/index.html index 9fcb249da..78cc7de73 100644 --- a/examples/index.html +++ b/examples/index.html @@ -26,6 +26,7 @@

Vue Router Examples

  • Discrete Components
  • Nested Routers
  • Keepalive View
  • +
  • Error handling
  • From 58e4d6f8acf328b89415b891ccd98a25529791eb Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 21:24:28 +0300 Subject: [PATCH 07/12] chore: add more components for error-handling demo --- examples/error-handling/app.js | 118 +++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 27 deletions(-) diff --git a/examples/error-handling/app.js b/examples/error-handling/app.js index e93a3671f..75a39256e 100644 --- a/examples/error-handling/app.js +++ b/examples/error-handling/app.js @@ -3,42 +3,90 @@ import VueRouter from 'vue-router' Vue.use(VueRouter) +// eslint-disable-next-line no-unused-vars +let asyncMode = false + +const makeError = (msg) => { + if (asyncMode) { + return new Promise((resolve, reject) => { + reject(new Error(msg)) + }) + } + + throw new Error(msg) +} + // Components const Home = { template: '
    Home
    ' } -const Default = { template: '
    Default
    ' } -const Sync = { template: '
    Sync
    ' } -const Async = { template: '
    Async
    ' } +const BeforeEach = { template: '
    BeforeEach
    ' } +const AfterEach = { template: '
    AfterEach
    ' } +const BeforeEnter = { + template: '
    BeforeRouteEnter
    ', + beforeRouteEnter () { + return makeError('component.BeforeRouteEnter') + } +} +const BeforeUpdate = { + template: '
    BeforeRouteUpdate
    ', + beforeRouteUpdate () { + return makeError('component.BeforeRouteUpdate') + }, + mounted () { + const currentId = +this.$route.params.id || 1 + console.log(`change params.id from ${currentId} to ${currentId + 1}`) + this.$router.push({ + name: 'component.beforeRouteUpdate', + params: { id: currentId + 1 } + }) + } +} +const BeforeLeave = { + template: '
    BeforeRouteLeave
    ', + data () { + return { + canLeave: false + } + }, + beforeRouteLeave (to, from, next) { + if (from.name === 'component.beforeRouteLeave' && !this.canLeave) { + this.canLeave = true + console.log('click twice to leave route') + return makeError('component.beforeRouteLeave') + } + + next() + } +} const router = new VueRouter({ - mode: 'history', base: __dirname, routes: [ { path: '/', component: Home, name: 'home' }, - { path: '/default', component: Default, name: 'default' }, - { path: '/sync', component: Sync, name: 'sync' }, - { path: '/async', component: Async, name: 'async' } + { path: '/before-enter', component: BeforeEnter, name: 'component.beforeRouteEnter' }, + { path: '/before-update/:id', component: BeforeUpdate, name: 'component.beforeRouteUpdate' }, + { path: '/before-leave', component: BeforeLeave, name: 'component.beforeRouteLeave' }, + { path: '/before-each', component: BeforeEach, name: 'router.beforeEach' }, + { path: '/after-each', component: AfterEach, name: 'router.afterEach' } ] }) router.onError((err) => { - console.log('Router.onError:', err) + console.log( + '%c Router.onError - ' + (asyncMode ? 'async' : 'sync'), + 'background: #fff; color: #000', + err.message + ) }) -// Promise same as: -// router.beforeEach(async (to, from, next) => { throw new Error('Async error') }) -router.beforeEach((to, from, next) => { - if (to.name === 'async') { - return new Promise((resolve, reject) => { - reject(new Error('Async error')) - }) - } - - next() +router.afterEach(() => { + return makeError('router.afterEach') }) +// Promise same as: +// router.beforeEach(async (to, from, next) => { throw new Error('Async error') }) router.beforeEach((to, from, next) => { - if (to.name === 'sync') { - throw new Error('Sync error') + if (to.name === 'router.beforeEach') { + return makeError('router.beforeEach') } next() @@ -46,16 +94,32 @@ router.beforeEach((to, from, next) => { new Vue({ router, + data () { + return { + asyncMode: false + } + }, + watch: { + asyncMode (val) { + asyncMode = val + } + }, template: `
    -
    - Open console +

    Error Handling

    + + Open console - {{ asyncMode ? 'async' : 'sync' }} (click) + +
    +
      +
    • /home
    • +
    • /beforeEach
    • +
    • /afterEach
    • +
    • /beforeRouteEnter
    • +
    • /beforeRouteUpdate
    • +
    • /beforeRouteLeave
    • +

    - /home - /default - /sync - /async -

    ` From 283ca28c2f58eb6a7177a487be3c8a248ff4dd3b Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 22:02:57 +0300 Subject: [PATCH 08/12] chore: update support async/await for guard --- src/history/base.js | 46 ++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/history/base.js b/src/history/base.js index cf3737ce1..74d2d1805 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -86,24 +86,13 @@ export class History { confirmTransition (route: Route, onComplete: Function, onAbort?: Function) { const current = this.current - const abort = err => { - if (isError(err)) { - if (this.errorCbs.length) { - this.errorCbs.forEach(cb => { cb(err) }) - } else { - warn(false, 'uncaught error during route navigation:') - console.error(err) - } - } - onAbort && onAbort(err) - } if ( isSameRoute(route, current) && // in the case the route map has been dynamically appended to route.matched.length === current.matched.length ) { this.ensureURL() - return abort() + return this._abort(null, onAbort) } const { @@ -128,14 +117,14 @@ export class History { this.pending = route const iterator = (hook: NavigationGuard, next) => { if (this.pending !== route) { - return abort() + return this._abort(null, onAbort) } try { const hookResponse = hook(route, current, (to: any) => { if (to === false || isError(to)) { // next(false) -> abort navigation, ensure current URL this.ensureURL(true) - abort(to) + this._abort(to, onAbort) } else if ( typeof to === 'string' || (typeof to === 'object' && ( @@ -144,7 +133,7 @@ export class History { )) ) { // next('/') or next({ path: '/' }) -> redirect - abort() + this._abort(null, onAbort) if (typeof to === 'object' && to.replace) { this.replace(to) } else { @@ -158,10 +147,10 @@ export class History { // Support async/await in guard (#2833) if (hookResponse instanceof Promise) { - hookResponse.catch(err => abort(err)) + hookResponse.catch(e => this._abort(e, onAbort)) } } catch (e) { - abort(e) + this._abort(e, onAbort) } } @@ -174,7 +163,7 @@ export class History { const queue = enterGuards.concat(this.router.resolveHooks) runQueue(queue, iterator, () => { if (this.pending !== route) { - return abort() + return this._abort(null, onAbort) } this.pending = null onComplete(route) @@ -192,9 +181,28 @@ export class History { this.current = route this.cb && this.cb(route) this.router.afterHooks.forEach(hook => { - hook && hook(route, prev) + if (hook) { + const hookResponse = hook(route, prev) + + // Support async/await in guard (#2833) + if (hookResponse instanceof Promise) { + hookResponse.catch(err => this._abort(err)) + } + } }) } + + _abort (err: any, cb: ?Function) { + if (isError(err)) { + if (this.errorCbs.length) { + this.errorCbs.forEach(cb => { cb(err) }) + } else { + warn(false, 'uncaught error during route navigation:') + console.error(err) + } + } + cb && cb(err) + } } function normalizeBase (base: ?string): string { From 843689dcc5a48f4d6aa2ec386220d9894bcdf3d6 Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 22:03:51 +0300 Subject: [PATCH 09/12] chore: set asyncMode default true --- examples/error-handling/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/error-handling/app.js b/examples/error-handling/app.js index 75a39256e..b474780b6 100644 --- a/examples/error-handling/app.js +++ b/examples/error-handling/app.js @@ -4,7 +4,7 @@ import VueRouter from 'vue-router' Vue.use(VueRouter) // eslint-disable-next-line no-unused-vars -let asyncMode = false +let asyncMode = true const makeError = (msg) => { if (asyncMode) { @@ -96,7 +96,7 @@ new Vue({ router, data () { return { - asyncMode: false + asyncMode } }, watch: { @@ -107,7 +107,7 @@ new Vue({ template: `

    Error Handling

    - + Open console - {{ asyncMode ? 'async' : 'sync' }} (click)
    From e8b4024896cb23fcbdf7e1c672b3ada37c02f489 Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Sun, 30 Jun 2019 22:04:47 +0300 Subject: [PATCH 10/12] chore(test): coverage async/await - beforeEach, afterEach, beforeResolve --- test/unit/specs/error-handling.spec.js | 55 ++++++++++++++++++++------ 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/test/unit/specs/error-handling.spec.js b/test/unit/specs/error-handling.spec.js index 03c2cd3f0..7f459756e 100644 --- a/test/unit/specs/error-handling.spec.js +++ b/test/unit/specs/error-handling.spec.js @@ -54,19 +54,52 @@ describe('error handling', () => { }) // #2833 - it('async router.beforeEach, handle onError', () => { - const router = new VueRouter() - const err = new Error('foo') - const spy = jasmine.createSpy('error') - router.onError(spy) + // async/await => router.beforeEach(async () => { throw err }) + // Promise => router.beforeEach(() => new Promise((resolve, reject) => reject(err))) + describe('async/await, handle onError', () => { + describe('Global', () => { + let router, err, spy - router.push('/') - router.beforeEach(async () => { throw err }) + beforeEach(() => { + router = new VueRouter() + err = new Error('foo') + spy = jasmine.createSpy('error') + router.onError(spy) + }) + + const promiseError = () => new Promise((resolve, reject) => { + reject(err) + }) + + it('beforeEach', () => { + router.beforeEach(() => promiseError()) + + router.push('/foo', () => { + fail('onError function did not receive an error') + }, () => { + expect(spy).toHaveBeenCalledWith(err) + }) + }) + + it('afterEach', () => { + router.afterEach(() => promiseError()) + + router.push('/foo', () => { + Vue.nextTick(() => expect(spy).toHaveBeenCalledWith(err)) + }, () => { + fail('onError function did not receive an error') + }) + }) + + it('beforeResolve', () => { + router.beforeResolve(() => promiseError()) - router.push('/foo', () => { - fail('onError function did not receive an error') - }, () => { - expect(spy).toHaveBeenCalledWith(err) + router.push('/foo', () => { + fail('onError function did not receive an error') + }, () => { + expect(spy).toHaveBeenCalledWith(err) + }) + }) }) }) }) From 8cd27c08b6ca3040a70e6b47bee0723e91538fac Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Mon, 1 Jul 2019 13:06:07 +0300 Subject: [PATCH 11/12] chore(test): add e2e for error-handling demo --- examples/error-handling/app.js | 19 ++++++-- examples/error-handling/index.html | 3 +- test/e2e/specs/error-handling.js | 71 ++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 test/e2e/specs/error-handling.js diff --git a/examples/error-handling/app.js b/examples/error-handling/app.js index b474780b6..19942a67a 100644 --- a/examples/error-handling/app.js +++ b/examples/error-handling/app.js @@ -6,6 +6,8 @@ Vue.use(VueRouter) // eslint-disable-next-line no-unused-vars let asyncMode = true +const logEl = document.querySelector('.log code') + const makeError = (msg) => { if (asyncMode) { return new Promise((resolve, reject) => { @@ -59,6 +61,7 @@ const BeforeLeave = { } const router = new VueRouter({ + mode: 'history', base: __dirname, routes: [ { path: '/', component: Home, name: 'home' }, @@ -71,8 +74,11 @@ const router = new VueRouter({ }) router.onError((err) => { + const modeName = asyncMode ? 'async' : 'sync' + logEl.innerText = `${modeName}: ${err.message}` + console.log( - '%c Router.onError - ' + (asyncMode ? 'async' : 'sync'), + '%c Router.onError - ' + modeName, 'background: #fff; color: #000', err.message ) @@ -99,6 +105,11 @@ new Vue({ asyncMode } }, + computed: { + nameMode () { + return this.asyncMode ? 'async' : 'sync' + } + }, watch: { asyncMode (val) { asyncMode = val @@ -107,8 +118,8 @@ new Vue({ template: `

    Error Handling

    - - Open console - {{ asyncMode ? 'async' : 'sync' }} (click) + + Open console - {{ nameMode }} (click)
      @@ -120,7 +131,7 @@ new Vue({
    • /beforeRouteLeave

    - +
    ` }).$mount('#app') diff --git a/examples/error-handling/index.html b/examples/error-handling/index.html index ba4c1585d..93f84ad00 100644 --- a/examples/error-handling/index.html +++ b/examples/error-handling/index.html @@ -1,6 +1,7 @@ ← Examples index -
    +

    +

    router.onError()

    diff --git a/test/e2e/specs/error-handling.js b/test/e2e/specs/error-handling.js new file mode 100644 index 000000000..25417e057 --- /dev/null +++ b/test/e2e/specs/error-handling.js @@ -0,0 +1,71 @@ +const bsStatus = require('../browserstack-send-status') + +const PAGE_NAME = 'error-handling' +const BASE_PAGE = `http://localhost:8080/${PAGE_NAME}` + +module.exports = { + ...bsStatus(), + + '@tags': ['history'], + + 'named routes': function (browser) { + browser + .url(BASE_PAGE + '/') + .waitForElementVisible('#app', 1000) + .assert.count('li a', 6) + // assert correct href with base + .assert.attributeContains('li:nth-child(1) a', 'href', `/${PAGE_NAME}/`) + .assert.attributeContains('li:nth-child(2) a', 'href', `/${PAGE_NAME}/before-each`) + .assert.attributeContains('li:nth-child(3) a', 'href', `/${PAGE_NAME}/after-each`) + .assert.attributeContains('li:nth-child(4) a', 'href', `/${PAGE_NAME}/before-enter`) + .assert.attributeContains('li:nth-child(5) a', 'href', `/${PAGE_NAME}/before-update/1`) + .assert.attributeContains('li:nth-child(6) a', 'href', `/${PAGE_NAME}/before-leave`) + .assert.attributeContains('strong', 'mode', 'async') + .assert.containsText('.log code', 'async: router.afterEach') + .assert.containsText('.view', 'Home') + + // Error on enter (global) + .click('li:nth-child(2) a') + .assert.urlEquals(`${BASE_PAGE}/`) + .assert.containsText('.log code', 'async: router.beforeEach') + .assert.containsText('.view', 'Home') + + // Error on leave (global) + .click('li:nth-child(3) a') + .assert.urlEquals(`${BASE_PAGE}/after-each`) + .assert.containsText('.log code', 'async: router.afterEach') + .assert.containsText('.view', 'AfterEach') + + // Error on enter (component) + .click('li:nth-child(4) a') + .assert.urlEquals(`${BASE_PAGE}/after-each`) + .assert.containsText('.log code', 'async: component.BeforeRouteEnter') + .assert.containsText('.view', 'AfterEach') + + // Error on change route (component) + // mounted change route.id to 2 + .click('li:nth-child(5) a') + .assert.urlEquals(`${BASE_PAGE}/before-update/1`) + .assert.containsText('.log code', 'async: component.BeforeRouteUpdate') + .assert.containsText('.view', 'BeforeRouteUpdate') + + // Error on leave route (component) + .click('li:nth-child(6) a') + .assert.urlEquals(`${BASE_PAGE}/before-leave`) + .assert.containsText('.log code', 'async: router.afterEach') + .assert.containsText('.view', 'BeforeRouteLeave') + + // Click twice to leave the route + .click('li:nth-child(1) a') + .assert.urlEquals(`${BASE_PAGE}/before-leave`) + .assert.containsText('.log code', 'async: component.beforeRouteLeave') + .assert.containsText('.view', 'BeforeRouteLeave') + + .click('li:nth-child(1) a') + .assert.urlEquals(`${BASE_PAGE}/`) + .assert.containsText('.log code', 'async: router.afterEach') + .assert.containsText('.view', 'Home') + + .end() + } +} From 3b763e04a238e0aa439be3fcbf15aecd829ac313 Mon Sep 17 00:00:00 2001 From: Alexey Khruhsch Date: Mon, 1 Jul 2019 13:23:25 +0300 Subject: [PATCH 12/12] chore(test): change name of runner --- test/e2e/specs/error-handling.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/specs/error-handling.js b/test/e2e/specs/error-handling.js index 25417e057..7986abdbc 100644 --- a/test/e2e/specs/error-handling.js +++ b/test/e2e/specs/error-handling.js @@ -8,7 +8,7 @@ module.exports = { '@tags': ['history'], - 'named routes': function (browser) { + [BASE_PAGE]: function (browser) { browser .url(BASE_PAGE + '/') .waitForElementVisible('#app', 1000)