Repository: jhipster/jhipster-vuejs
Pull request #459 (2019-10-01 05:27:18)

update vue bootstrap and other deps
* Update vue-boostrap to latest final version and update configuration
* Update Fa
* Update smaller 3rd party dependencies

Will have a look later at date-fns as there is now a final stable release available

-   Please make sure the below checklist is followed for Pull Requests.

-   [ ] [Travis tests](https://travis-ci.org/jhipster/jhipster-vuejs/pull_requests) are green
-   [ ] Tests are added where necessary
-   [ ] Documentation is added/updated where necessary
-   [ ] Coding Rules & Commit Guidelines as per our [CONTRIBUTING.md document](https://github.com/jhipster/jhipster-vuejs/blob/master/CONTRIBUTING.md) are followed

<!--
Please also reference the issue number in a commit message to [automatically close the related Github issue](https://help.github.com/articles/closing-issues-via-commit-messages/)

Note: It is also possible to add `[skip ci]` to your commit message to skip Travis tests
-->


atomfrede: Looks like I have missed something, seems not to work as expected, althought updating manually all dependencies worked fine
atomfrede: Updating `vue2-filters` to `0,7.x` breaks the while typescript typesystem (e.g. `TS2344: Type 'JhiLogs' does not satisfy the constraint 'Vue'`) so I would suggest we keep it at `0.6.0` for now.
hdurix: @atomfrede thanks! Could you rebase to the latest master version to check the CI build?
atomfrede: @hdurix Done. Let's see how it goes :+1: 
pascalgrimaud: It won't pass, as we're currently trying to fix the last failures
pascalgrimaud: @atomfrede : as the CI is finally green, can you rebase to check if everything is good plz ? 
atomfrede: Will try to have look at the failing e2e. They might be related to updating vue-boostrap althought I couldn't reproduce it locally when I updated it.
pascalgrimaud: what I can suggest, is to split the upgrade:
- vue lib
- boostrap lib

So you will know exactly where it comes from.
atomfrede: Good idea, will first have a look if the e2e test fail locally (I guess) but they should be quite easy to fix I hope as manual tests for that worked correctly. Hopefully I have some spare time later today.
pascalgrimaud: I plan to do a new release of vue.js soon, as we really need one !
The last release was few months ago

If you manage to fix this and are confident, we'll include this to the release
atomfrede: Sure, we will have that fixed and ready for the new release :+1: 

Patch:
diff --git a/.eslintignore b/.eslintignore
index bfd41c0..ef4c90e 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,3 +3,4 @@ generators/**/templates
 node_modules
 travis
 docs
+test/templates
\ No newline at end of file
diff --git a/README.md b/README.md
index 6be430d..6786907 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,8 @@
 # JHipster-vuejs
 [![NPM version][npm-image]][npm-url] [![Azure DevOps Build Status][azure-devops-image]][azure-devops-url-main] [![Dependency Status][daviddm-image]][daviddm-url] [![Downloads][npmcharts-image]][npmcharts-url]
-> ## ⚠️ Status: in development
-> JHipster-vuejs, a Vue.js blueprint for JHipster. It will use [Vue.js](https://vuejs.org/) as the frontend library.
 
 <div align="center">
-  <a href="http://www.jhipster.tech/">
+  <a href="https://www.jhipster.tech/">
     <img src="https://github.com/jhipster/jhipster-artwork/blob/master/logos/JHipster%20RGB-small100x25px.png?raw=true">
   </a>
   <a href="https://vuejs.org/">
@@ -14,11 +12,11 @@
 
 # Introduction
 
-This is a [JHipster](http://www.jhipster.tech/) blueprint.
+This is a [JHipster](https://www.jhipster.tech/) blueprint.
 
 # Prerequisites
 
-As this is a [JHipster](http://www.jhipster.tech/) blueprint, we expect you have JHipster and its related tools already installed:
+As this is a [JHipster](https://www.jhipster.tech/) blueprint, we expect you have JHipster and its related tools already installed:
 
 - [Installing JHipster](https://www.jhipster.tech/installation/)
 
@@ -61,6 +59,14 @@ To use this blueprint, run
 jhipster --blueprints vuejs
 ```
 
+## Create a new component page
+
+To create a new Vue.js empty page, run
+
+```bash
+jhipster --blueprint vuejs page
+```
+
 
 ## Running local Blueprint version for development
 
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index c2f4820..7663ede 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -75,7 +75,7 @@ jobs:
           #----------------------------------------------------------------------
           - task: NodeTool@0
             inputs:
-                versionSpec: '10.16.3'
+                versionSpec: '12.13.0'
             displayName: 'TOOLS: install Node.js'
           - script: |
                 if [[ $JHI_JDK = '11' ]]; then
diff --git a/cli/commands.js b/cli/commands.js
new file mode 100644
index 0000000..531f195
--- /dev/null
+++ b/cli/commands.js
@@ -0,0 +1,24 @@
+/**
+ * Copyright 2013-2019 the original author or authors from the JHipster project.
+ *
+ * This file is part of the JHipster project, see https://www.jhipster.tech/
+ * for more information.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    page: {
+        blueprint: 'generator-jhipster-vuejs',
+        desc: 'Create a new VueJS page.'
+    }
+};
diff --git a/generators/client/files.js b/generators/client/files.js
index 8e0a6bc..85b5fea 100644
--- a/generators/client/files.js
+++ b/generators/client/files.js
@@ -163,6 +163,7 @@ const vueFiles = {
                 'shared/date/filters.ts',
                 'shared/sort/sorts.ts',
                 'shared/alert/alert.service.ts',
+                'shared/alert/alert.mixin.ts',
                 'shared/data/data-utils.service.ts',
                 'shared/jhi-item-count.component.ts',
                 'shared/jhi-item-count.vue',
diff --git a/generators/client/templates/vue/package.json.ejs b/generators/client/templates/vue/package.json.ejs
index 7b79e0d..0ca3644 100644
--- a/generators/client/templates/vue/package.json.ejs
+++ b/generators/client/templates/vue/package.json.ejs
@@ -27,12 +27,12 @@ limitations under the License.
     "node_modules"
   ],
   "dependencies": {
-    "@fortawesome/fontawesome-svg-core": "1.2.19",
-    "@fortawesome/free-solid-svg-icons": "5.9.0",
-    "@fortawesome/vue-fontawesome": "0.1.6",
+    "@fortawesome/fontawesome-svg-core": "1.2.25",
+    "@fortawesome/free-solid-svg-icons": "5.11.2",
+    "@fortawesome/vue-fontawesome": "0.1.8",
     "axios": "0.19.0",
     "bootstrap": "4.3.1",
-    "bootstrap-vue": "2.0.0-rc.26",
+    "bootstrap-vue": "2.0.4",
     <%_ if (clientTheme !== 'none') { _%>
     "bootswatch": "4.3.1",
     <%_ } _%>
@@ -45,12 +45,12 @@ limitations under the License.
     "vue": "2.6.10",
     "vue-class-component": "7.0.2",
     "vue-cookie": "1.1.4",
-    "vue-i18n": "8.12.0",
-    "vue-property-decorator": "8.2.1",
-    "vue-router": "3.0.7",
+    "vue-i18n": "8.15.0",
+    "vue-property-decorator": "8.2.2",
+    "vue-router": "3.1.3",
     "vue2-filters": "0.6.0",
     "vuelidate": "0.7.4",
-    "vuex": "3.1.1"
+    "vuex": "3.1.2"
   },
   "devDependencies": {
 <%_ if (protractorTests) { _%>
diff --git a/generators/client/templates/vue/src/main/webapp/app/admin/user-management/user-management.component.ts.ejs b/generators/client/templates/vue/src/main/webapp/app/admin/user-management/user-management.component.ts.ejs
index 36eaa5e..bd6c920 100644
--- a/generators/client/templates/vue/src/main/webapp/app/admin/user-management/user-management.component.ts.ejs
+++ b/generators/client/templates/vue/src/main/webapp/app/admin/user-management/user-management.component.ts.ejs
@@ -2,11 +2,10 @@ import { Component, Inject } from 'vue-property-decorator';
 import { mixins } from 'vue-class-component';
 import Vue2Filters from 'vue2-filters';
 import UserManagementService from './user-management.service';
-import AlertService from '@/shared/alert/alert.service';
+import AlertMixin from '@/shared/alert/alert.mixin';
 
 @Component
-export default class <%=jhiPrefixCapitalized%>UserManagementComponent extends mixins(Vue2Filters.mixin) {
-  @Inject('alertService') private alertService: () => AlertService;
+export default class <%=jhiPrefixCapitalized%>UserManagementComponent extends mixins(Vue2Filters.mixin, AlertMixin) {
   @Inject('userService') private userManagementService: () => UserManagementService;
   public error = '';
   public success = '';
@@ -20,23 +19,6 @@ export default class <%=jhiPrefixCapitalized%>UserManagementComponent extends mi
   public totalItems = 0;
   public removeId: <% if (pkType === 'String' || pkType === 'UUID') { %>string<% } else { %>number<% } %> = null;
 
-  public dismissCountDown: number = this.$store.getters.dismissCountDown;
-  public dismissSecs: number = this.$store.getters.dismissSecs;
-  public alertType: string = this.$store.getters.alertType;
-  public alertMessage: any = this.$store.getters.alertMessage;
-
-  public getAlertFromStore() {
-    this.dismissCountDown = this.$store.getters.dismissCountDown;
-    this.dismissSecs = this.$store.getters.dismissSecs;
-    this.alertType = this.$store.getters.alertType;
-    this.alertMessage = this.$store.getters.alertMessage;
-  }
-
-  public countDownChanged(dismissCountDown: number) {
-    this.alertService().countDownChanged(dismissCountDown);
-    this.getAlertFromStore();
-  }
-
   public mounted(): void {
     this.loadAll();
   }
@@ -117,6 +99,9 @@ export default class <%=jhiPrefixCapitalized%>UserManagementComponent extends mi
 
   public prepareRemove(instance): void {
     this.removeId = instance.login;
+    if (<any>this.$refs.removeUser) {
+      (<any>this.$refs.removeUser).show();
+    }
   }
 
   public closeDialog() : void {
diff --git a/generators/client/templates/vue/src/main/webapp/app/admin/user-management/user-management.vue.ejs b/generators/client/templates/vue/src/main/webapp/app/admin/user-management/user-management.vue.ejs
index 764bf8d..e12a3df 100644
--- a/generators/client/templates/vue/src/main/webapp/app/admin/user-management/user-management.vue.ejs
+++ b/generators/client/templates/vue/src/main/webapp/app/admin/user-management/user-management.vue.ejs
@@ -68,8 +68,7 @@
                                 <b-button v-on:click="prepareRemove(user)"
                                        variant="danger"
                                        class="btn btn-sm delete"
-                                       :disabled="username === user.login"
-                                       v-b-modal.removeUser>
+                                       :disabled="username === user.login">
                                     <font-awesome-icon icon="times"></font-awesome-icon>
                                     <span class="d-none d-md-inline" v-text="$t('entity.action.delete')">Delete</span>
                                 </b-button>
diff --git a/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.vue.ejs b/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.vue.ejs
index 71fda1c..73a5990 100644
--- a/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.vue.ejs
+++ b/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.vue.ejs
@@ -20,7 +20,6 @@
                 <b-nav-item-dropdown
                     id="entity-menu"
                     v-if="authenticated"
-                    :class="{'router-link-active': subIsActive('/entity')}"
                     active-class="active" class="pointer">
                     <span slot="button-content" class="navbar-dropdown-menu">
                         <font-awesome-icon icon="th-list" />
diff --git a/generators/client/templates/vue/src/main/webapp/app/shared/alert/alert.mixin.ts.ejs b/generators/client/templates/vue/src/main/webapp/app/shared/alert/alert.mixin.ts.ejs
new file mode 100644
index 0000000..1a6f53b
--- /dev/null
+++ b/generators/client/templates/vue/src/main/webapp/app/shared/alert/alert.mixin.ts.ejs
@@ -0,0 +1,24 @@
+import { Component, Inject, Vue } from 'vue-property-decorator';
+import AlertService from '@/shared/alert/alert.service';
+
+@Component
+export default class AlertMixin extends Vue  {
+  @Inject('alertService') protected alertService: () => AlertService;
+
+  public dismissCountDown: number = this.$store.getters.dismissCountDown;
+  public dismissSecs: number = this.$store.getters.dismissSecs;
+  public alertType: string = this.$store.getters.alertType;
+  public alertMessage: any = this.$store.getters.alertMessage;
+
+  public getAlertFromStore() {
+    this.dismissCountDown = this.$store.getters.dismissCountDown;
+    this.dismissSecs = this.$store.getters.dismissSecs;
+    this.alertType = this.$store.getters.alertType;
+    this.alertMessage = this.$store.getters.alertMessage;
+  }
+
+  public countDownChanged(dismissCountDown: number) {
+    this.alertService().countDownChanged(dismissCountDown);
+    this.getAlertFromStore();
+  }
+}
diff --git a/generators/client/templates/vue/src/main/webapp/app/shared/config/config-bootstrap-vue.ts.ejs b/generators/client/templates/vue/src/main/webapp/app/shared/config/config-bootstrap-vue.ts.ejs
index fe89038..7e59b23 100644
--- a/generators/client/templates/vue/src/main/webapp/app/shared/config/config-bootstrap-vue.ts.ejs
+++ b/generators/client/templates/vue/src/main/webapp/app/shared/config/config-bootstrap-vue.ts.ejs
@@ -1,47 +1,50 @@
-import bForm from 'bootstrap-vue/es/components/form/form';
-import bFormInput from 'bootstrap-vue/es/components/form-input/form-input';
-import bFormCheckbox from 'bootstrap-vue/es/components/form-checkbox/form-checkbox';
-import bFormGroup from 'bootstrap-vue/es/components/form-group/form-group';
-import bProgress from 'bootstrap-vue/es/components/progress/progress';
-import bProgressBar from 'bootstrap-vue/es/components/progress/progress-bar';
-import bPagination from 'bootstrap-vue/es/components/pagination/pagination';
-import bButton from 'bootstrap-vue/es/components/button/button';
-import bNavbar from 'bootstrap-vue/es/components/navbar/navbar';
-import bNavbarNav from 'bootstrap-vue/es/components/navbar/navbar-nav';
-import bNavbarBrand from 'bootstrap-vue/es/components/navbar/navbar-brand';
-import bNavbarToggle from 'bootstrap-vue/es/components/navbar/navbar-toggle';
-import bNavItem from 'bootstrap-vue/es/components/nav/nav-item';
-import bNavItemDropdown from 'bootstrap-vue/es/components/nav/nav-item-dropdown';
-import bCollapse from 'bootstrap-vue/es/components/collapse/collapse';
-import bBadge from 'bootstrap-vue/es/components/badge/badge';
-import bDropdown from 'bootstrap-vue/es/components/dropdown/dropdown';
-import bDropdownItem from 'bootstrap-vue/es/components/dropdown/dropdown-item';
-import bLink from 'bootstrap-vue/es/components/link/link';
-import bAlert from 'bootstrap-vue/es/components/alert/alert';
-import bModal from 'bootstrap-vue/es/components/modal/modal';
-import bModalDirective from 'bootstrap-vue/es/directives/modal/modal';
+import {
+  BForm,
+  BFormInput,
+  BFormCheckbox,
+  BFormGroup,
+  BProgress,
+  BProgressBar,
+  BPagination,
+  BButton,
+  BNavbar,
+  BNavbarNav,
+  BNavbarBrand,
+  BNavbarToggle,
+  BNavItem,
+  BNavItemDropdown,
+  BCollapse,
+  BBadge,
+  BDropdown,
+  BDropdownItem,
+  BLink,
+  BAlert,
+  BModal,
+  VBModal
+} from 'bootstrap-vue';
 
 export function initBootstrapVue(vue) {
-    vue.component('b-badge', bBadge);
-    vue.component('b-dropdown', bDropdown);
-    vue.component('b-dropdown-item', bDropdownItem);
-    vue.component('b-link', bLink);
-    vue.component('b-alert', bAlert);
-    vue.component('b-modal', bModal);
-    vue.component('b-button', bButton);
-    vue.component('b-navbar', bNavbar);
-    vue.component('b-navbar-nav', bNavbarNav);
-    vue.component('b-navbar-brand', bNavbarBrand);
-    vue.component('b-navbar-toggle', bNavbarToggle);
-    vue.component('b-pagination', bPagination);
-    vue.component('b-progress', bProgress);
-    vue.component('b-progress-bar', bProgressBar);
-    vue.component('b-form', bForm);
-    vue.component('b-form-input', bFormInput);
-    vue.component('b-form-group', bFormGroup);
-    vue.component('b-form-checkbox', bFormCheckbox);
-    vue.component('b-collapse', bCollapse);
-    vue.component('b-nav-item', bNavItem);
-    vue.component('b-nav-item-dropdown', bNavItemDropdown);
-    vue.directive('b-modal', bModalDirective);
+  vue.component('b-badge', BBadge);
+  vue.component('b-dropdown', BDropdown);
+  vue.component('b-dropdown-item', BDropdownItem);
+  vue.component('b-link', BLink);
+  vue.component('b-alert', BAlert);
+  vue.component('b-modal', BModal);
+  vue.component('b-button', BButton);
+  vue.component('b-navbar', BNavbar);
+  vue.component('b-navbar-nav', BNavbarNav);
+  vue.component('b-navbar-brand', BNavbarBrand);
+  vue.component('b-navbar-toggle', BNavbarToggle);
+  vue.component('b-pagination', BPagination);
+  vue.component('b-progress', BProgress);
+  vue.component('b-progress-bar', BProgressBar);
+  vue.component('b-form', BForm);
+  vue.component('b-form-input', BFormInput);
+  vue.component('b-form-group', BFormGroup);
+  vue.component('b-form-checkbox', BFormCheckbox);
+  vue.component('b-collapse', BCollapse);
+  vue.component('b-nav-item', BNavItem);
+  vue.component('b-nav-item-dropdown', BNavItemDropdown);
+  vue.component('b-modal', BModal);
+  vue.directive('b-modal', VBModal);
 }
diff --git a/generators/common/templates/README.md.ejs b/generators/common/templates/README.md.ejs
index ea5bb82..5f7f098 100644
--- a/generators/common/templates/README.md.ejs
+++ b/generators/common/templates/README.md.ejs
@@ -317,21 +317,21 @@ To configure CI for your project, run the ci-cd sub-generator (`jhipster ci-cd`)
 [Running tests page]: <%= DOCUMENTATION_ARCHIVE_URL %>/running-tests/
 [Code quality page]: <%= DOCUMENTATION_ARCHIVE_URL %>/code-quality/
 [Setting up Continuous Integration]: <%= DOCUMENTATION_ARCHIVE_URL %>/setting-up-ci/
-<% if (testFrameworks.includes("gatling")) { %>[Gatling]: http://gatling.io/<% } %>
+<% if (testFrameworks.includes("gatling")) { %>[Gatling]: https://gatling.io/<% } %>
 <%_ if (!skipClient) {_%>
 [Node.js]: https://nodejs.org/
 [Yarn]: https://yarnpkg.org/
 [Webpack]: https://webpack.github.io/
 [Vue CLI]: https://cli.vuejs.org/
-[BrowserSync]: http://www.browsersync.io/
+[BrowserSync]: https://www.browsersync.io/
 [Jest]: https://facebook.github.io/jest/
-[Jasmine]: http://jasmine.github.io/2.0/introduction.html
-[Protractor]: http://www.protractortest.org/
-[Leaflet]: http://leafletjs.com/
-[DefinitelyTyped]: http://definitelytyped.org/
+[Jasmine]: https://jasmine.github.io/2.0/introduction.html
+[Protractor]: https://www.protractortest.org/
+[Leaflet]: https://leafletjs.com/
+[DefinitelyTyped]: https://definitelytyped.org/
 <%_ } _%>
 <%_ if (enableSwaggerCodegen) { _%>
 [OpenAPI-Generator]: https://openapi-generator.tech
-[Swagger-Editor]: http://editor.swagger.io
+[Swagger-Editor]: https://editor.swagger.io
 [Doing API-First development]: <%= DOCUMENTATION_ARCHIVE_URL %>/doing-api-first-development/
 <%_ } _%>
diff --git a/generators/entity-client/templates/vue/src/main/webapp/app/entities/entity.component.ts.ejs b/generators/entity-client/templates/vue/src/main/webapp/app/entities/entity.component.ts.ejs
index ff21997..9868a4b 100644
--- a/generators/entity-client/templates/vue/src/main/webapp/app/entities/entity.component.ts.ejs
+++ b/generators/entity-client/templates/vue/src/main/webapp/app/entities/entity.component.ts.ejs
@@ -3,15 +3,14 @@ import { mixins } from 'vue-class-component';
 import { Component, Inject } from 'vue-property-decorator';
 import Vue2Filters from 'vue2-filters';
 import { I<%= entityAngularName %> } from '@/shared/model/<%= entityModelFileName %>.model';
-import AlertService from '@/shared/alert/alert.service';
+import AlertMixin from '@/shared/alert/alert.mixin';
 <% if (fieldsContainBlob) { %>
 import JhiDataUtils from '@/shared/data/data-utils.service';
 <% } %>
 import <%= entityAngularName %>Service from './<%= entityFileName %>.service';
 
 @Component
-export default class <%= entityAngularName %> extends <% if (fieldsContainBlob) { %>mixins(JhiDataUtils, Vue2Filters.mixin)<% } else { %> mixins(Vue2Filters.mixin)<% } %> {
-  @Inject('alertService') private alertService: () => AlertService;
+export default class <%= entityAngularName %> extends <% if (fieldsContainBlob) { %>mixins(JhiDataUtils, Vue2Filters.mixin, AlertMixin)<% } else { %> mixins(Vue2Filters.mixin, AlertMixin)<% } %> {
   @Inject('<%= entityInstance %>Service') private <%= entityInstance %>Service: () => <%= entityAngularName %>Service;
   <%_ if (searchEngine === 'elasticsearch') { _%>
   public currentSearch = '';
@@ -29,22 +28,6 @@ export default class <%= entityAngularName %> extends <% if (fieldsContainBlob)
   public <%= entityInstancePlural %>: I<%= entityAngularName %>[] = [];
 
   public isFetching = false;
-  public dismissCountDown: number = this.$store.getters.dismissCountDown;
-  public dismissSecs: number = this.$store.getters.dismissSecs;
-  public alertType: string = this.$store.getters.alertType;
-  public alertMessage: any = this.$store.getters.alertMessage;
-
-  public getAlertFromStore() {
-    this.dismissCountDown = this.$store.getters.dismissCountDown;
-    this.dismissSecs = this.$store.getters.dismissSecs;
-    this.alertType = this.$store.getters.alertType;
-    this.alertMessage = this.$store.getters.alertMessage;
-  }
-
-  public countDownChanged(dismissCountDown: number) {
-    this.alertService().countDownChanged(dismissCountDown);
-    this.getAlertFromStore();
-  }
 
   public mounted(): void {
     this.retrieveAll<%= entityAngularName %>s();
diff --git a/generators/page/files.js b/generators/page/files.js
new file mode 100644
index 0000000..b6a660d
--- /dev/null
+++ b/generators/page/files.js
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2013-2019 the original author or authors from the JHipster project.
+ *
+ * This file is part of the JHipster project, see https://www.jhipster.tech/
+ * for more information.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+const constants = require('generator-jhipster/generators/generator-constants');
+const _ = require('lodash');
+const utils = require('../utils');
+
+/* Constants use throughout */
+const CLIENT_TEST_SRC_DIR = constants.CLIENT_TEST_SRC_DIR;
+const VUE_DIR = 'src/main/webapp/app/';
+const CLIENT_VUE_TEMPLATES_DIR = 'vue';
+
+const vueFiles = {
+    client: [
+        {
+            path: VUE_DIR,
+            templates: [
+                {
+                    file: 'pages/page.vue',
+                    renameTo: generator => `pages/${generator.pageFolderName}/${generator.pageFolderName}.vue`
+                },
+                {
+                    file: 'pages/page.service.ts',
+                    renameTo: generator => `pages/${generator.pageFolderName}/${generator.pageFolderName}.service.ts`
+                },
+                {
+                    file: 'pages/page.component.ts',
+                    renameTo: generator => `pages/${generator.pageFolderName}/${generator.pageFolderName}.component.ts`
+                },
+            ]
+        }
+    ],
+    test: [
+        {
+            path: CLIENT_TEST_SRC_DIR,
+            templates: [
+                {
+                    file: 'spec/app/pages/page.component.spec.ts',
+                    renameTo: generator => `spec/app/pages/${generator.pageFolderName}/${generator.pageFolderName}.component.spec.ts`
+                },
+                {
+                    file: 'spec/app/pages/page.service.spec.ts',
+                    renameTo: generator => `spec/app/pages/${generator.pageFolderName}/${generator.pageFolderName}.service.spec.ts`
+                }
+            ]
+        },
+        {
+            condition: generator => generator.protractorTests,
+            path: CLIENT_TEST_SRC_DIR,
+            templates: [
+                {
+                    file: 'e2e/pages/page.page-object.ts',
+                    renameTo: generator => `e2e/pages/${generator.pageFolderName}/${generator.pageFolderName}.page-object.ts`
+                },
+                {
+                    file: 'e2e/pages/page.spec.ts',
+                    renameTo: generator => `e2e/pages/${generator.pageFolderName}/${generator.pageFolderName}.spec.ts`
+                }
+            ]
+        }
+    ]
+};
+
+
+module.exports = {
+    writeFiles
+};
+
+function writeFiles() {
+    if (this.skipClient) return;
+
+    this.pageFolderName = this.pageName.toLowerCase();
+    this.pageInstance = _.lowerFirst(this.pageName);
+
+    // write client side files for Vue.js
+    this.writeFilesToDisk(vueFiles, this, false, `${CLIENT_VUE_TEMPLATES_DIR}`);
+
+    // Add page paths to routing system
+    utils.addPageToRouterImport(this, this.pageName, this.pageFolderName);
+    utils.addPageToRouter(this, this.pageName, this.pageFolderName);
+
+    // Add page services to main
+    utils.addPageServiceToMainImport(this, this.pageName, this.pageFolderName);
+    utils.addPageServiceToMain(this, this.pageName, this.pageInstance);
+
+    // Add tests to protractor conf
+    if (this.protractorTests) {
+        utils.addPageProtractorConf(this, this.pageFolderName);
+    }
+}
diff --git a/generators/page/index.js b/generators/page/index.js
new file mode 100644
index 0000000..3246c31
--- /dev/null
+++ b/generators/page/index.js
@@ -0,0 +1,61 @@
+/**
+ * Copyright 2013-2019 the original author or authors from the JHipster project.
+ *
+ * This file is part of the JHipster project, see https://www.jhipster.tech/
+ * for more information.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+const EntityClientGenerator = require('generator-jhipster/generators/entity-client');
+const jhipsterUtils = require('generator-jhipster/generators/utils');
+const chalk = require('chalk');
+const prompts = require('./prompts');
+const writeFiles = require('./files').writeFiles;
+
+module.exports = class extends EntityClientGenerator {
+    constructor(args, opts) {
+        super(args, Object.assign({ fromBlueprint: true }, opts)); // fromBlueprint variable is important
+        // Get missing configuration
+        const configuration = jhipsterUtils.getAllJhipsterConfig(null, true);
+        this.skipClient = configuration.skipClient;
+        this.clientPackageManager = configuration.clientPackageManager;
+        this.enableTranslation = configuration.enableTranslation;
+        this.protractorTests = configuration.testFrameworks.includes('protractor');
+    }
+
+    get prompting() {
+        // The prompting phase is being overriden so that we can ask our own questions
+        return {
+            askForPage: prompts.askForPage
+        };
+    }
+
+    get writing() {
+        return {
+            writeAdditionalFile() {
+                writeFiles.call(this);
+            }
+        };
+    }
+
+    get end() {
+        return {
+            end() {
+                if (!this.options['skip-install'] && !this.skipClient) {
+                    this.rebuildClient();
+                }
+                this.log(chalk.bold.green(`Page ${this.pageName} generated successfully.`));
+            }
+        };
+    }
+};
diff --git a/generators/page/prompts.js b/generators/page/prompts.js
new file mode 100644
index 0000000..c590131
--- /dev/null
+++ b/generators/page/prompts.js
@@ -0,0 +1,42 @@
+/**
+ * Copyright 2013-2019 the original author or authors from the JHipster project.
+ *
+ * This file is part of the JHipster project, see https://www.jhipster.tech/
+ * for more information.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    askForPage
+};
+
+function askForPage(meta) {
+    if (!meta && this.existingProject) return;
+
+    const prompts = {
+        type: 'input',
+        name: 'pageName',
+        message: 'What is the name of your page?',
+        default: 'MyPage',
+        validate: input => (/^([A-Z][a-zA-Z]*)$/.test(input) ? true : 'This is not a valid page name (ex: MyPage).'),
+    };
+
+    if (meta) return prompts; // eslint-disable-line consistent-return
+
+    const done = this.async();
+
+    this.prompt(prompts).then((prompt) => {
+        this.pageName = prompt.pageName;
+        done();
+    });
+}
diff --git a/generators/page/templates/vue/src/main/webapp/app/pages/page.component.ts.ejs b/generators/page/templates/vue/src/main/webapp/app/pages/page.component.ts.ejs
new file mode 100644
index 0000000..6881de1
--- /dev/null
+++ b/generators/page/templates/vue/src/main/webapp/app/pages/page.component.ts.ejs
@@ -0,0 +1,15 @@
+import { Component, Inject, Vue } from 'vue-property-decorator';
+import <%= pageName %>Service from './<%= pageFolderName %>.service';
+
+@Component
+export default class <%= pageName %> extends Vue {
+  @Inject('<%= pageInstance %>Service') private <%= pageInstance %>Service: () => <%= pageName %>Service;
+
+  public mounted(): void {
+    this.init();
+  }
+
+  public init(): void {
+    this.<%= pageInstance %>Service().method();
+  }
+}
diff --git a/generators/page/templates/vue/src/main/webapp/app/pages/page.service.ts.ejs b/generators/page/templates/vue/src/main/webapp/app/pages/page.service.ts.ejs
new file mode 100644
index 0000000..70980f8
--- /dev/null
+++ b/generators/page/templates/vue/src/main/webapp/app/pages/page.service.ts.ejs
@@ -0,0 +1,6 @@
+export default class <%= pageName %>Service {
+    public method(): boolean {
+        // This method was generated
+        return true;
+    }
+}
diff --git a/generators/page/templates/vue/src/main/webapp/app/pages/page.vue.ejs b/generators/page/templates/vue/src/main/webapp/app/pages/page.vue.ejs
new file mode 100644
index 0000000..7f657f3
--- /dev/null
+++ b/generators/page/templates/vue/src/main/webapp/app/pages/page.vue.ejs
@@ -0,0 +1,8 @@
+<template>
+    <div>
+        <h2 id="page-heading">This page was generated, please edit!</h2>
+    </div>
+</template>
+
+<script lang="ts" src="./<%= pageFolderName %>.component.ts">
+</script>
\ No newline at end of file
diff --git a/generators/utils.js b/generators/utils.js
index 40cb5a3..80fcabe 100644
--- a/generators/utils.js
+++ b/generators/utils.js
@@ -22,6 +22,7 @@ const chalk = require('chalk');
 
 const CLIENT_MAIN_SRC_DIR = constants.CLIENT_MAIN_SRC_DIR;
 const CLIENT_WEBPACK_DIR = constants.CLIENT_WEBPACK_DIR;
+const CLIENT_TEST_SRC_DIR = constants.CLIENT_TEST_SRC_DIR;
 
 module.exports = {
     updateLanguagesInConfig,
@@ -31,7 +32,12 @@ module.exports = {
     addEntityToRouterImport,
     addEntityToRouter,
     addEntityServiceToMainImport,
-    addEntityServiceToMain
+    addEntityServiceToMain,
+    addPageToRouterImport,
+    addPageToRouter,
+    addPageServiceToMainImport,
+    addPageServiceToMain,
+    addPageProtractorConf
 };
 
 function updateLanguagesInConfig(generator) {
@@ -122,7 +128,7 @@ function addEntityToMenu(generator, entityName, translationKey, className) {
             needle: 'jhipster-needle-add-entity-to-menu',
             splicable: [
                 // prettier-ignore
-                `<b-dropdown-item to="/entity/${entityName}">
+                `<b-dropdown-item to="/${entityName}">
                         <font-awesome-icon icon="asterisk" />
                         <span ${menuI18nTitle}>${className}</span>
                     </b-dropdown-item>`
@@ -178,25 +184,25 @@ function addEntityToRouter(generator, entityName, entityFileName, entityAngularN
                     // prettier-ignore
                     `|,
                         |    {
-                        |      path: '/entity/${entityFileName}',
+                        |      path: '/${entityFileName}',
                         |      name: '${entityAngularName}',
                         |      component: ${entityAngularName},
                         |      meta: { authorities: ['ROLE_USER'] }
                         |    },
                         |    {
-                        |      path: '/entity/${entityFileName}/new',
+                        |      path: '/${entityFileName}/new',
                         |      name: '${entityAngularName}Create',
                         |      component: ${entityAngularName}Update,
                         |      meta: { authorities: ['ROLE_USER'] }
                         |    },
                         |    {
-                        |      path: '/entity/${entityFileName}/:${entityName}Id/edit',
+                        |      path: '/${entityFileName}/:${entityName}Id/edit',
                         |      name: '${entityAngularName}Edit',
                         |      component: ${entityAngularName}Update,
                         |      meta: { authorities: ['ROLE_USER'] }
                         |    },
                         |    {
-                        |      path: '/entity/${entityFileName}/:${entityName}Id/view',
+                        |      path: '/${entityFileName}/:${entityName}Id/view',
                         |      name: '${entityAngularName}View',
                         |      component: ${entityAngularName}Details,
                         |      meta: { authorities: ['ROLE_USER'] }
@@ -214,13 +220,13 @@ function addEntityToRouter(generator, entityName, entityFileName, entityAngularN
                     // prettier-ignore
                     `|,
                         |    {
-                        |      path: '/entity/${entityFileName}',
+                        |      path: '/${entityFileName}',
                         |      name: '${entityAngularName}',
                         |      component: ${entityAngularName},
                         |      meta: { authorities: ['ROLE_USER'] }
                         |    },
                         |    {
-                        |      path: '/entity/${entityFileName}/:${entityName}Id/view',
+                        |      path: '/${entityFileName}/:${entityName}Id/view',
                         |      name: '${entityAngularName}View',
                         |      component: ${entityAngularName}Details,
                         |      meta: { authorities: ['ROLE_USER'] }
@@ -259,3 +265,77 @@ function addEntityServiceToMain(generator, entityName, className) {
         generator
     );
 }
+
+function addPageToRouterImport(generator, pageName, pageFolderName) {
+    jhipsterUtils.rewriteFile(
+        {
+            file: `${CLIENT_MAIN_SRC_DIR}/app/router/index.ts`,
+            needle: 'jhipster-needle-add-entity-to-router-import',
+            splicable: [generator.stripMargin(
+                // prettier-ignore
+                `|// prettier-ignore
+                |const ${pageName} = () => import('../pages/${pageFolderName}/${pageFolderName}.vue');`
+            )]
+        },
+        generator
+    );
+}
+
+function addPageToRouter(generator, pageName, pageFolderName) {
+    jhipsterUtils.rewriteFile(
+        {
+            file: `${CLIENT_MAIN_SRC_DIR}/app/router/index.ts`,
+            needle: 'jhipster-needle-add-entity-to-router',
+            splicable: [generator.stripMargin(
+                // prettier-ignore
+                `|,
+                |    {
+                |      path: '/pages/${pageFolderName}',
+                |      name: '${pageName}',
+                |      component: ${pageName},
+                |      meta: { authorities: ['ROLE_USER'] }
+                |    }`
+            )]
+        },
+        generator
+    );
+}
+
+function addPageServiceToMainImport(generator, pageName, pageFolderName) {
+    jhipsterUtils.rewriteFile(
+        {
+            file: `${CLIENT_MAIN_SRC_DIR}/app/main.ts`,
+            needle: 'jhipster-needle-add-entity-service-to-main-import',
+            splicable: [generator.stripMargin(
+                // prettier-ignore
+                `|import ${pageName}Service from '@/pages/${pageFolderName}/${pageFolderName}.service';`
+            )]
+        },
+        generator
+    );
+}
+
+function addPageServiceToMain(generator, pageName, pageInstance) {
+    jhipsterUtils.rewriteFile(
+        {
+            file: `${CLIENT_MAIN_SRC_DIR}/app/main.ts`,
+            needle: 'jhipster-needle-add-entity-service-to-main',
+            splicable: [generator.stripMargin(
+                // prettier-ignore
+                `|${pageInstance}Service: () => new ${pageName}Service(),`
+            )]
+        },
+        generator
+    );
+}
+
+function addPageProtractorConf(generator, pageFolderName) {
+    jhipsterUtils.rewriteFile(
+        {
+            file: `${CLIENT_TEST_SRC_DIR}/protractor.conf.js`,
+            needle: 'jhipster-needle-add-protractor-tests',
+            splicable: [generator.stripMargin('\'./e2e/pages/**/*.spec.ts\',')]
+        },
+        generator
+    );
+}
diff --git a/package-lock.json b/package-lock.json
index ab350a8..722d5c3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -95,14 +95,14 @@
       }
     },
     "@types/node": {
-      "version": "10.14.21",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.21.tgz",
-      "integrity": "sha512-nuFlRdBiqbF+PJIEVxm2jLFcQWN7q7iWEJGsBV4n7v1dbI9qXB8im2pMMKMCUZe092sQb5SQft2DHfuQGK5hqQ=="
+      "version": "10.17.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.5.tgz",
+      "integrity": "sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA=="
     },
     "@types/qs": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.5.3.tgz",
-      "integrity": "sha512-Jugo5V/1bS0fRhy2z8+cUAHEyWOATaz4rbyLVvcFs7+dXp5HfwpEwzF1Q11bB10ApUqHf+yTauxI0UXQDwGrbA=="
+      "version": "6.9.0",
+      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.0.tgz",
+      "integrity": "sha512-c4zji5CjWv1tJxIZkz1oUtGcdOlsH3aza28Nqmm+uNDWBRHoMsjooBEN4czZp1V3iXPihE/VRUOBqg+4Xq0W4g=="
     },
     "acorn": {
       "version": "6.1.0",
@@ -344,6 +344,22 @@
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
       "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
     },
+    "aws-sdk": {
+      "version": "2.533.0",
+      "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.533.0.tgz",
+      "integrity": "sha512-OSe7C0jnBdgfzedOtK+TgBEwtJaaZovm+Q2fbqIlfhUWg3rhhkt3oLyQ9bRD30/CFaunLhLr/8HAAN+/x+DWAA==",
+      "requires": {
+        "buffer": "4.9.1",
+        "events": "1.1.1",
+        "ieee754": "1.1.13",
+        "jmespath": "0.15.0",
+        "querystring": "0.2.0",
+        "sax": "1.2.1",
+        "url": "0.10.3",
+        "uuid": "3.3.2",
+        "xml2js": "0.4.19"
+      }
+    },
     "aws-sign2": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -430,6 +446,11 @@
         }
       }
     },
+    "base64-js": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+      "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
+    },
     "bcrypt-pbkdf": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -481,9 +502,9 @@
       "dev": true
     },
     "boolean": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/boolean/-/boolean-1.0.0.tgz",
-      "integrity": "sha512-IB1lgIywn37N9Aff8CciCblVpMUflgL42vyxPUH0IvaDdIi/QwBHKv1lq/HOkATHCfa7c4MbMYJ7Bo7hGuoI+w=="
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/boolean/-/boolean-2.0.3.tgz",
+      "integrity": "sha512-iHzXeFCXWrpjYE7DToXGCBPGZf0eVISqzL+4sgrOSYEKXnb59WHPFvGTTyCj6zJ/MuuLAxEn8zPkrTHHzlt3IA=="
     },
     "boxen": {
       "version": "1.3.0",
@@ -541,6 +562,16 @@
       "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
       "dev": true
     },
+    "buffer": {
+      "version": "4.9.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+      "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+      "requires": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4",
+        "isarray": "^1.0.0"
+      }
+    },
     "buffer-alloc": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
@@ -691,9 +722,9 @@
       "dev": true
     },
     "chevrotain": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-6.2.0.tgz",
-      "integrity": "sha512-wA/7Py7CrNWe4vgAkvA2S+mQcW7jIERkB/FWAexqsdIRPVvEXdu4T8f3XWI8EMMQtkb3sJo3DHmafy+gbCPzTQ==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-6.5.0.tgz",
+      "integrity": "sha512-BwqQ/AgmKJ8jcMEjaSnfMybnKMgGTrtDKowfTP3pX4jwVy0kNjRsT/AP6h+wC3+3NC+X8X15VWBnTCQlX+wQFg==",
       "requires": {
         "regexp-to-ast": "0.4.0"
       }
@@ -752,6 +783,11 @@
       "resolved": "https://registry.npmjs.org/cli-list/-/cli-list-0.2.0.tgz",
       "integrity": "sha1-fmc+4N05phGkhkduU/PGs5QctYI="
     },
+    "cli-spinners": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz",
+      "integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ=="
+    },
     "cli-table": {
       "version": "0.3.1",
       "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
@@ -913,9 +949,9 @@
       "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y="
     },
     "colors": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
-      "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg=="
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
     },
     "colorspace": {
       "version": "1.1.2",
@@ -1011,9 +1047,9 @@
       "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
     },
     "core-js": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.3.2.tgz",
-      "integrity": "sha512-S1FfZpeBchkhyoY76YAdFzKS4zz9aOK7EeFaNA2aJlyXyA+sgqz6xdxmLPGXEAf0nF44MVN1kSjrA9Kt3ATDQg=="
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.4.0.tgz",
+      "integrity": "sha512-lQxb4HScV71YugF/X28LtePZj9AB7WqOpcB+YztYxusvhrgZiQXPmCYfPC5LHsw/+ScEtDbXU3xbqH3CjBRmYA=="
     },
     "core-util-is": {
       "version": "1.0.2",
@@ -1147,6 +1183,14 @@
       "resolved": "https://registry.npmjs.org/default-uid/-/default-uid-1.0.0.tgz",
       "integrity": "sha1-/O+p359axAyJFtkS3R/hFGqjxZ4="
     },
+    "defaults": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
+      "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+      "requires": {
+        "clone": "^1.0.2"
+      }
+    },
     "define-properties": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -1893,6 +1937,11 @@
       "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
       "dev": true
     },
+    "events": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+      "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
+    },
     "execa": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
@@ -2102,9 +2151,9 @@
       "dev": true
     },
     "fast-safe-stringify": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
-      "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg=="
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
+      "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA=="
     },
     "fecha": {
       "version": "2.3.3",
@@ -2349,10 +2398,11 @@
       }
     },
     "generator-jhipster": {
-      "version": "6.4.1",
-      "resolved": "https://registry.npmjs.org/generator-jhipster/-/generator-jhipster-6.4.1.tgz",
-      "integrity": "sha512-TO/OLaH/cGz/Agag3WXCe774LEwJ//cxBd72AhZTmvCd1Y0TduSzx+KNIYJqWznGXV2qUyPSyobg6OzQ/43eMA==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/generator-jhipster/-/generator-jhipster-6.5.0.tgz",
+      "integrity": "sha512-8NTHSSNqW3Vngz3P+DyL+/1n38Z6LBM5JQj4CY6HBZFxZsSuLHORCpdlnN0b6d5hjGZtASzMSKkN8l/bpE7ZRA==",
       "requires": {
+        "aws-sdk": "2.533.0",
         "axios": "0.19.0",
         "chalk": "2.4.2",
         "commander": "2.19.0",
@@ -2363,23 +2413,25 @@
         "glob": "7.1.3",
         "gulp-filter": "5.1.0",
         "insight": "0.10.1",
-        "jhipster-core": "5.0.0",
+        "jhipster-core": "6.0.1",
         "js-object-pretty-print": "0.3.0",
         "js-yaml": "3.13.1",
         "lodash": "4.17.13",
         "meow": "5.0.0",
         "mkdirp": "0.5.1",
+        "ora": "3.4.0",
         "os-locale": "3.1.0",
         "parse-gitignore": "1.0.1",
         "pluralize": "7.0.0",
         "prettier": "1.16.4",
+        "progress": "2.0.3",
         "randexp": "0.5.3",
         "semver": "5.6.0",
         "shelljs": "0.8.3",
         "sync-request": "6.0.0",
         "tabtab": "2.2.2",
         "through2": "3.0.1",
-        "uuid": "3.3.2",
+        "uuid": "3.3.3",
         "yeoman-environment": "2.3.4",
         "yeoman-generator": "3.2.0",
         "yo": "3.1.0"
@@ -2395,24 +2447,6 @@
             "supports-color": "^5.3.0"
           }
         },
-        "chevrotain": {
-          "version": "6.2.0",
-          "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-6.2.0.tgz",
-          "integrity": "sha512-wA/7Py7CrNWe4vgAkvA2S+mQcW7jIERkB/FWAexqsdIRPVvEXdu4T8f3XWI8EMMQtkb3sJo3DHmafy+gbCPzTQ==",
-          "requires": {
-            "regexp-to-ast": "0.4.0"
-          }
-        },
-        "fs-extra": {
-          "version": "8.1.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
-          "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
-          "requires": {
-            "graceful-fs": "^4.2.0",
-            "jsonfile": "^4.0.0",
-            "universalify": "^0.1.0"
-          }
-        },
         "glob": {
           "version": "7.1.3",
           "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
@@ -2426,29 +2460,6 @@
             "path-is-absolute": "^1.0.0"
           }
         },
-        "graceful-fs": {
-          "version": "4.2.2",
-          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
-          "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q=="
-        },
-        "jhipster-core": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/jhipster-core/-/jhipster-core-5.0.0.tgz",
-          "integrity": "sha512-pAkFqICz0IU5jpWDUGN3KHiXWE/HFpp7vVz53M5w5XmjeBOCEln2kMigYBH9j6PLkr7txAzcfSIf57Tzx2QUWw==",
-          "requires": {
-            "chevrotain": "6.2.0",
-            "fs-extra": "8.1.0",
-            "lodash": "4.17.15",
-            "winston": "3.2.1"
-          },
-          "dependencies": {
-            "lodash": {
-              "version": "4.17.15",
-              "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-              "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
-            }
-          }
-        },
         "prettier": {
           "version": "1.16.4",
           "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz",
@@ -2485,6 +2496,11 @@
           "requires": {
             "readable-stream": "2 || 3"
           }
+        },
+        "uuid": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
+          "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
         }
       }
     },
@@ -2583,17 +2599,17 @@
       "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs="
     },
     "global-agent": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.2.tgz",
-      "integrity": "sha512-cLv8MW4Pydwx2BH4I0eA5nc9g8k/x6/k66u/rRH7FqMTyyZMO+o3bRbbX6Yb4mrUa9QnLnJJLzSiS0+2oGbqUw==",
+      "version": "2.1.6",
+      "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.6.tgz",
+      "integrity": "sha512-fL+xfraAlc1MXU8Gs0DAg/eHH+H1CjxbK+BLU3Qt55dAVMAQ8fH8k/UrLwV4A+Vk/hl/TePWuTxFnqJzCV1/Kw==",
       "requires": {
-        "boolean": "^1.0.0",
-        "core-js": "^3.2.1",
+        "boolean": "^2.0.3",
+        "core-js": "^3.4.0",
         "es6-error": "^4.1.1",
         "matcher": "^2.0.0",
-        "roarr": "^2.14.1",
+        "roarr": "^2.14.4",
         "semver": "^6.3.0",
-        "serialize-error": "^4.1.0"
+        "serialize-error": "^5.0.0"
       },
       "dependencies": {
         "semver": {
@@ -2857,6 +2873,11 @@
         "safer-buffer": ">= 2.1.2 < 3"
       }
     },
+    "ieee754": {
+      "version": "1.1.13",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
+    },
     "ignore": {
       "version": "3.3.10",
       "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
@@ -3295,11 +3316,11 @@
       }
     },
     "jhipster-core": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/jhipster-core/-/jhipster-core-5.0.0.tgz",
-      "integrity": "sha512-pAkFqICz0IU5jpWDUGN3KHiXWE/HFpp7vVz53M5w5XmjeBOCEln2kMigYBH9j6PLkr7txAzcfSIf57Tzx2QUWw==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/jhipster-core/-/jhipster-core-6.0.1.tgz",
+      "integrity": "sha512-YQN9V74F/AtnYQV00kaISBMzuRKID92To07220m2bzDhc59X3RsioZiqhV0ESIK3DTdI6QSVIuhVIgM/Z1XgCA==",
       "requires": {
-        "chevrotain": "6.2.0",
+        "chevrotain": "6.5.0",
         "fs-extra": "8.1.0",
         "lodash": "4.17.15",
         "winston": "3.2.1"
@@ -3316,9 +3337,9 @@
           }
         },
         "graceful-fs": {
-          "version": "4.2.2",
-          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
-          "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q=="
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
         },
         "lodash": {
           "version": "4.17.15",
@@ -3327,6 +3348,11 @@
         }
       }
     },
+    "jmespath": {
+      "version": "0.15.0",
+      "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
+      "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc="
+    },
     "js-object-pretty-print": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/js-object-pretty-print/-/js-object-pretty-print-0.3.0.tgz",
@@ -4317,6 +4343,44 @@
         "wordwrap": "~1.0.0"
       }
     },
+    "ora": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz",
+      "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==",
+      "requires": {
+        "chalk": "^2.4.2",
+        "cli-cursor": "^2.1.0",
+        "cli-spinners": "^2.0.0",
+        "log-symbols": "^2.2.0",
+        "strip-ansi": "^5.2.0",
+        "wcwidth": "^1.0.1"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
     "os-homedir": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
@@ -4734,8 +4798,7 @@
     "progress": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
-      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
-      "dev": true
+      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
     },
     "promise": {
       "version": "8.0.3",
@@ -4789,6 +4852,11 @@
         "strict-uri-encode": "^1.0.0"
       }
     },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
+    },
     "quick-lru": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
@@ -5114,11 +5182,11 @@
       }
     },
     "roarr": {
-      "version": "2.14.1",
-      "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.14.1.tgz",
-      "integrity": "sha512-Fhm9shQ8JhpjFnOT7bgxKR7Xcg1Tq+0/Tdy+bloB4sUxxAib4MZDMJ6AjUBRE+798l2MnhhF2JTqbqx1+/kRyQ==",
+      "version": "2.14.4",
+      "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.14.4.tgz",
+      "integrity": "sha512-QMzRAQGZFPgnx4nNWp4Q+WHfiZh2HTSEjNaxFLrEIj3PmcQ1GHL5OjaaIyF9ybUDD2aZ9t3Awc/obrRPils9ng==",
       "requires": {
-        "boolean": "^1.0.0",
+        "boolean": "^2.0.3",
         "detect-node": "^2.0.4",
         "globalthis": "^1.0.0",
         "json-stringify-safe": "^5.0.1",
@@ -5194,6 +5262,11 @@
       "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==",
       "dev": true
     },
+    "sax": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
+      "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
+    },
     "scoped-regex": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/scoped-regex/-/scoped-regex-1.0.0.tgz",
@@ -5231,11 +5304,11 @@
       }
     },
     "serialize-error": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-4.1.0.tgz",
-      "integrity": "sha512-5j9GgyGsP9vV9Uj1S0lDCvlsd+gc2LEPVK7HHHte7IyPwOD4lVQFeaX143gx3U5AnoCi+wbcb3mvaxVysjpxEw==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz",
+      "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==",
       "requires": {
-        "type-fest": "^0.3.0"
+        "type-fest": "^0.8.0"
       }
     },
     "set-blocking": {
@@ -6077,9 +6150,9 @@
       },
       "dependencies": {
         "@types/node": {
-          "version": "8.10.54",
-          "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.54.tgz",
-          "integrity": "sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg=="
+          "version": "8.10.59",
+          "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz",
+          "integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ=="
         }
       }
     },
@@ -6240,9 +6313,9 @@
       "dev": true
     },
     "type-fest": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz",
-      "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ=="
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
     },
     "typedarray": {
       "version": "0.0.6",
@@ -6368,6 +6441,22 @@
       "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
       "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
     },
+    "url": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
+      "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
+        }
+      }
+    },
     "url-parse-lax": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
@@ -6469,6 +6558,14 @@
         "foreachasync": "^3.0.0"
       }
     },
+    "wcwidth": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+      "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
+      "requires": {
+        "defaults": "^1.0.3"
+      }
+    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -6638,6 +6735,20 @@
       "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
       "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ="
     },
+    "xml2js": {
+      "version": "0.4.19",
+      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+      "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+      "requires": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~9.0.1"
+      }
+    },
+    "xmlbuilder": {
+      "version": "9.0.7",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+      "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
+    },
     "xmlcreate": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz",
@@ -7921,9 +8032,9 @@
           }
         },
         "yeoman-environment": {
-          "version": "2.5.0",
-          "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.5.0.tgz",
-          "integrity": "sha512-RCxVKbSiW1o0l5C7dkGvG4BHmI4dfSA50pcBU9VQ2AOUErgGdCtfU+bLM6g7NV9iA2uxFGFYv6iJArhmWzRouA==",
+          "version": "2.6.0",
+          "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.6.0.tgz",
+          "integrity": "sha512-Hl0LBs9/mKun8XyJ6gFiUNhZwjN/eezn+E9IFWz6KtXg/3wsnztF2lgtE8eIjfhWYtvY4yMq9iizi1Ei5JJ+7A==",
           "requires": {
             "chalk": "^2.4.1",
             "cross-spawn": "^6.0.5",
diff --git a/package.json b/package.json
index b8d1187..3515bbb 100644
--- a/package.json
+++ b/package.json
@@ -25,11 +25,11 @@
     "chalk": "2.4.1",
     "ejs": "2.6.1",
     "eslint-config-airbnb": "17.1.0",
-    "generator-jhipster": "6.4.1",
+    "generator-jhipster": "6.5.0",
     "glob": "7.1.2",
     "gulp-filter": "5.1.0",
     "insight": "0.10.1",
-    "jhipster-core": "5.0.0",
+    "jhipster-core": "6.0.1",
     "js-yaml": "3.13.1",
     "lodash": "4.17.13",
     "meow": "5.0.0",


Test patch:
diff --git a/generators/client/templates/vue/src/test/javascript/e2e/page-objects/navbar-page.ts.ejs b/generators/client/templates/vue/src/test/javascript/e2e/page-objects/navbar-page.ts.ejs
index 070a6f0..85341b3 100644
--- a/generators/client/templates/vue/src/test/javascript/e2e/page-objects/navbar-page.ts.ejs
+++ b/generators/client/templates/vue/src/test/javascript/e2e/page-objects/navbar-page.ts.ejs
@@ -88,7 +88,7 @@ async getRegisterPage() {
   }
 
   async clickOnEntity(entityName: string) {
-    await click(this.selector.$(`.dropdown-item[href="/entity/${entityName}"]`));
+    await click(this.selector.$(`.dropdown-item[href="/${entityName}"]`));
   }
 
   async getEntityPage(entityName: string) {
diff --git a/generators/client/templates/vue/src/test/javascript/protractor.conf.js.ejs b/generators/client/templates/vue/src/test/javascript/protractor.conf.js.ejs
index 70a9f69..c0604b3 100644
--- a/generators/client/templates/vue/src/test/javascript/protractor.conf.js.ejs
+++ b/generators/client/templates/vue/src/test/javascript/protractor.conf.js.ejs
@@ -4,8 +4,8 @@ exports.config = {
   specs: [
     './e2e/modules/account/**/*.spec.ts',
     './e2e/modules/administration/**/*.spec.ts',
-    './e2e/entities/**/*.spec.ts'
     /* jhipster-needle-add-protractor-tests - JHipster will add protractors tests here */
+    './e2e/entities/**/*.spec.ts'
   ],
 
   capabilities: {
diff --git a/generators/page/templates/vue/src/test/javascript/e2e/pages/page.page-object.ts.ejs b/generators/page/templates/vue/src/test/javascript/e2e/pages/page.page-object.ts.ejs
new file mode 100644
index 0000000..f39ec9f
--- /dev/null
+++ b/generators/page/templates/vue/src/test/javascript/e2e/pages/page.page-object.ts.ejs
@@ -0,0 +1,23 @@
+<%#
+ Copyright 2013-2019 the original author or authors from the JHipster project.
+
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+import {by, element, ElementFinder} from 'protractor';
+
+export default class <%= pageName %>ComponentsPage {
+  title: ElementFinder = element(by.id('page-heading'));
+}
\ No newline at end of file
diff --git a/generators/page/templates/vue/src/test/javascript/e2e/pages/page.spec.ts.ejs b/generators/page/templates/vue/src/test/javascript/e2e/pages/page.spec.ts.ejs
new file mode 100644
index 0000000..b223339
--- /dev/null
+++ b/generators/page/templates/vue/src/test/javascript/e2e/pages/page.spec.ts.ejs
@@ -0,0 +1,47 @@
+<%#
+ Copyright 2013-2019 the original author or authors from the JHipster project.
+
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+/* tslint:disable no-unused-expression */
+import { browser } from 'protractor';
+
+import NavBarPage from './../../page-objects/navbar-page';
+import <%= pageName %>ComponentsPage from './<%= pageFolderName %>.page-object';
+
+const expect = chai.expect;
+
+describe('<%= pageName %> e2e test', () => {
+  let navBarPage: NavBarPage;
+  let page: <%= pageName %>ComponentsPage;
+
+  before(async () => {
+    await browser.get('/');
+    navBarPage = new NavBarPage();
+    await navBarPage.login('admin', 'admin');
+  });
+
+  after(async () => {
+    await navBarPage.autoSignOut();
+  });
+
+  it('should load <%= pageName %>', async () => {
+    page = new <%= pageName %>ComponentsPage();
+    await browser.get('/pages/<%= pageFolderName %>');
+
+    expect(await page.title.getText()).not.to.be.empty;
+  });
+});
diff --git a/generators/page/templates/vue/src/test/javascript/spec/app/pages/page.component.spec.ts.ejs b/generators/page/templates/vue/src/test/javascript/spec/app/pages/page.component.spec.ts.ejs
new file mode 100644
index 0000000..a2b65bd
--- /dev/null
+++ b/generators/page/templates/vue/src/test/javascript/spec/app/pages/page.component.spec.ts.ejs
@@ -0,0 +1,66 @@
+<%#
+ Copyright 2013-2019 the original author or authors from the JHipster project.
+
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+import { createLocalVue, shallowMount, Wrapper } from '@vue/test-utils';
+import sinon, { SinonStubbedInstance } from 'sinon';
+
+import * as config from '@/shared/config/config';
+import <%= pageName %>Component from '@/pages/<%= pageFolderName %>/<%= pageFolderName %>.vue';
+import <%= pageName %>Class from '@/pages/<%= pageFolderName %>/<%= pageFolderName %>.component';
+import <%= pageName %>Service from '@/pages/<%= pageFolderName %>/<%= pageFolderName %>.service';
+
+const localVue = createLocalVue();
+
+config.initVueApp(localVue);
+<%_ if (enableTranslation) { _%>
+const i18n = config.initI18N(localVue);
+<%_ } _%>
+const store = config.initVueXStore(localVue);
+
+describe('Component Tests', () => {
+  describe('<%= pageName %> Component', () => {
+    let wrapper: Wrapper<<%= pageName %>Class>;
+    let comp: <%= pageName %>Class;
+    let <%= pageInstance %>ServiceStub: SinonStubbedInstance<<%= pageName %>Service>;
+
+    beforeEach(() => {
+      <%= pageInstance %>ServiceStub = sinon.createStubInstance<<%= pageName %>Service>(<%= pageName %>Service);
+
+      wrapper = shallowMount<<%= pageName %>Class>(<%= pageName %>Component, {
+        store,
+        <%_ if (enableTranslation) { _%>
+        i18n,
+        <%_ } _%>
+        localVue,
+        provide: {
+          <%= pageInstance %>Service: () => <%= pageInstance %>ServiceStub
+        }
+      });
+      comp = wrapper.vm;
+    });
+
+    it('should be a Vue instance', () => {
+      expect(wrapper.isVueInstance()).toBeTruthy();
+    });
+
+    it('Should call "method" on init', async () => {
+      // THEN
+      expect(<%= pageInstance %>ServiceStub.method.called).toBeTruthy();
+    });
+  });
+});
diff --git a/generators/page/templates/vue/src/test/javascript/spec/app/pages/page.service.spec.ts.ejs b/generators/page/templates/vue/src/test/javascript/spec/app/pages/page.service.spec.ts.ejs
new file mode 100644
index 0000000..e83a773
--- /dev/null
+++ b/generators/page/templates/vue/src/test/javascript/spec/app/pages/page.service.spec.ts.ejs
@@ -0,0 +1,32 @@
+<%#
+ Copyright 2013-2019 the original author or authors from the JHipster project.
+
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+import <%= pageName %>Service from '@/pages/<%= pageFolderName %>/<%= pageFolderName %>.service';
+
+describe('<%= pageName %> Service', () => {
+  let service: <%= pageName %>Service;
+  beforeEach(() => {
+    service = new <%= pageName %>Service();
+  });
+
+  describe('Service methods', () => {
+    it('should call "method"', async () => {
+      expect(service.method()).toBeTruthy();
+    });
+  });
+});
diff --git a/test/page.spec.js b/test/page.spec.js
new file mode 100644
index 0000000..ee35a01
--- /dev/null
+++ b/test/page.spec.js
@@ -0,0 +1,68 @@
+const path = require('path');
+const fse = require('fs-extra');
+const assert = require('yeoman-assert');
+const helpers = require('yeoman-test');
+const constants = require('generator-jhipster/generators/generator-constants');
+
+const CLIENT_MAIN_SRC_DIR = constants.CLIENT_MAIN_SRC_DIR;
+const CLIENT_TEST_SRC_DIR = constants.CLIENT_TEST_SRC_DIR;
+const CLIENT_SPEC_SRC_DIR = `${CLIENT_TEST_SRC_DIR}spec/`;
+const pageName = 'MyTestPage';
+const pageFolderName = 'mytestpage';
+const pageInstance = 'myTestPage';
+
+describe('Subgenerator page of Vue.js JHipster blueprint', () => {
+    describe('Create page', () => {
+        before((done) => {
+            helpers
+                .run(require.resolve('../generators/page'))
+                .inTmpDir((dir) => {
+                    fse.copySync(path.join(__dirname, '../test/templates/vuejs-default'), dir);
+                })
+                .withOptions({
+                    'from-cli': true,
+                    skipInstall: true,
+                    blueprint: 'vuejs',
+                    skipChecks: true
+                })
+                .withPrompts({
+                    pageName
+                })
+                .on('end', done);
+        });
+
+        it('creates expected files', () => {
+            assert.file([
+                `${CLIENT_MAIN_SRC_DIR}app/pages/${pageFolderName}/${pageFolderName}.vue`,
+                `${CLIENT_MAIN_SRC_DIR}app/pages/${pageFolderName}/${pageFolderName}.service.ts`,
+                `${CLIENT_MAIN_SRC_DIR}app/pages/${pageFolderName}/${pageFolderName}.component.ts`,
+                `${CLIENT_SPEC_SRC_DIR}app/pages/${pageFolderName}/${pageFolderName}.component.spec.ts`,
+                `${CLIENT_SPEC_SRC_DIR}app/pages/${pageFolderName}/${pageFolderName}.service.spec.ts`,
+                `${CLIENT_TEST_SRC_DIR}e2e/pages/${pageFolderName}/${pageFolderName}.page-object.ts`,
+                `${CLIENT_TEST_SRC_DIR}e2e/pages/${pageFolderName}/${pageFolderName}.spec.ts`
+            ]);
+        });
+        it('add page path, service and protractor config', () => {
+            assert.fileContent(
+                `${CLIENT_MAIN_SRC_DIR}/app/router/index.ts`,
+                `const ${pageName} = () => import('../pages/${pageFolderName}/${pageFolderName}.vue');`
+            );
+            assert.fileContent(
+                `${CLIENT_MAIN_SRC_DIR}/app/router/index.ts`,
+                `path: '/pages/${pageFolderName}',`
+            );
+            assert.fileContent(
+                `${CLIENT_MAIN_SRC_DIR}/app/main.ts`,
+                `import ${pageName}Service from '@/pages/${pageFolderName}/${pageFolderName}.service';`
+            );
+            assert.fileContent(
+                `${CLIENT_MAIN_SRC_DIR}/app/main.ts`,
+                `${pageInstance}Service: () => new ${pageName}Service(),`
+            );
+            assert.fileContent(
+                `${CLIENT_TEST_SRC_DIR}/protractor.conf.js`,
+                '\'./e2e/pages/**/*.spec.ts\','
+            );
+        });
+    });
+});
diff --git a/test/templates/vuejs-default/src/main/webapp/app/main.ts b/test/templates/vuejs-default/src/main/webapp/app/main.ts
new file mode 100644
index 0000000..216671b
--- /dev/null
+++ b/test/templates/vuejs-default/src/main/webapp/app/main.ts
@@ -0,0 +1,90 @@
+// The Vue build version to load with the `import` command
+// (runtime-only or standalone) has been set in webpack.common with an alias.
+import Vue from 'vue';
+import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
+import App from './app.vue';
+import Vue2Filters from 'vue2-filters';
+import router from './router';
+import * as config from './shared/config/config';
+import * as bootstrapVueConfig from './shared/config/config-bootstrap-vue';
+import JhiItemCountComponent from './shared/jhi-item-count.vue';
+import AuditsService from './admin/audits/audits.service';
+
+import HealthService from './admin/health/health.service';
+import MetricsService from './admin/metrics/metrics.service';
+import LogsService from './admin/logs/logs.service';
+import ActivateService from './account/activate/activate.service';
+import RegisterService from './account/register/register.service';
+import UserManagementService from '@/admin/user-management/user-management.service';
+
+import LoginService from './account/login.service';
+import AccountService from './account/account.service';
+
+import '../content/scss/vendor.scss';
+import AlertService from '@/shared/alert/alert.service';
+import TranslationService from '@/locale/translation.service';
+import ConfigurationService from '@/admin/configuration/configuration.service';
+
+// jhipster-needle-add-entity-service-to-main-import - JHipster will import entities services here
+
+Vue.config.productionTip = false;
+config.initVueApp(Vue);
+config.initFortAwesome(Vue);
+bootstrapVueConfig.initBootstrapVue(Vue);
+Vue.use(Vue2Filters);
+Vue.component('font-awesome-icon', FontAwesomeIcon);
+Vue.component('jhi-item-count', JhiItemCountComponent);
+
+const i18n = config.initI18N(Vue);
+const store = config.initVueXStore(Vue);
+
+const alertService = new AlertService(store);
+const translationService = new TranslationService(store, i18n);
+const loginService = new LoginService();
+const accountService = new AccountService(store, translationService, router);
+
+router.beforeEach((to, from, next) => {
+  if (!to.matched.length) {
+    next('/not-found');
+  }
+
+  if (to.meta && to.meta.authorities && to.meta.authorities.length > 0) {
+    if (!accountService.hasAnyAuthority(to.meta.authorities)) {
+      sessionStorage.setItem('requested-url', to.fullPath);
+      next('/forbidden');
+    } else {
+      next();
+    }
+  } else {
+    // no authorities, so just proceed
+    next();
+  }
+});
+
+/* tslint:disable */
+new Vue({
+  el: '#app',
+  components: { App },
+  template: '<App/>',
+  router,
+  provide: {
+    loginService: () => loginService,
+    activateService: () => new ActivateService(),
+    registerService: () => new RegisterService(),
+    userService: () => new UserManagementService(),
+
+    auditsService: () => new AuditsService(),
+
+    healthService: () => new HealthService(),
+
+    configurationService: () => new ConfigurationService(),
+    logsService: () => new LogsService(),
+    metricsService: () => new MetricsService(),
+    alertService: () => alertService,
+    translationService: () => translationService,
+    // jhipster-needle-add-entity-service-to-main - JHipster will import entities services here
+    accountService: () => accountService
+  },
+  i18n,
+  store
+});
diff --git a/test/templates/vuejs-default/src/main/webapp/app/router/index.ts b/test/templates/vuejs-default/src/main/webapp/app/router/index.ts
new file mode 100644
index 0000000..0606c53
--- /dev/null
+++ b/test/templates/vuejs-default/src/main/webapp/app/router/index.ts
@@ -0,0 +1,146 @@
+import Vue from 'vue';
+import Component from 'vue-class-component';
+Component.registerHooks([
+  'beforeRouteEnter',
+  'beforeRouteLeave',
+  'beforeRouteUpdate' // for vue-router 2.2+
+]);
+import Router from 'vue-router';
+const Home = () => import('../core/home/home.vue');
+const Error = () => import('../core/error/error.vue');
+const Register = () => import('../account/register/register.vue');
+const Activate = () => import('../account/activate/activate.vue');
+const ResetPasswordInit = () => import('../account/reset-password/init/reset-password-init.vue');
+const ResetPasswordFinish = () => import('../account/reset-password/finish/reset-password-finish.vue');
+const ChangePassword = () => import('../account/change-password/change-password.vue');
+const Settings = () => import('../account/settings/settings.vue');
+const JhiUserManagementComponent = () => import('../admin/user-management/user-management.vue');
+const JhiUserManagementViewComponent = () => import('../admin/user-management/user-management-view.vue');
+const JhiUserManagementEditComponent = () => import('../admin/user-management/user-management-edit.vue');
+const JhiConfigurationComponent = () => import('../admin/configuration/configuration.vue');
+const JhiDocsComponent = () => import('../admin/docs/docs.vue');
+const JhiHealthComponent = () => import('../admin/health/health.vue');
+const JhiLogsComponent = () => import('../admin/logs/logs.vue');
+const JhiAuditsComponent = () => import('../admin/audits/audits.vue');
+const JhiMetricsComponent = () => import('../admin/metrics/metrics.vue');
+/* tslint:disable */
+// jhipster-needle-add-entity-to-router-import - JHipster will import entities to the router here
+
+Vue.use(Router);
+
+// prettier-ignore
+export default new Router({
+  mode: 'history',
+  routes: [
+    {
+      path: '/',
+      name: 'Home',
+      component: Home
+    },
+    {
+      path: '/forbidden',
+      name: 'Forbidden',
+      component: Error,
+      meta: { error403: true }
+    },
+    {
+      path: '/not-found',
+      name: 'NotFound',
+      component: Error,
+      meta: { error404: true }
+    },
+    {
+      path: '/register',
+      name: 'Register',
+      component: Register
+    },
+    {
+      path: '/activate',
+      name: 'Activate',
+      component: Activate
+    },
+    {
+      path: '/reset/request',
+      name: 'ResetPasswordInit',
+      component: ResetPasswordInit
+    },
+    {
+      path: '/reset/finish',
+      name: 'ResetPasswordFinish',
+      component: ResetPasswordFinish
+    },
+    {
+      path: '/account/password',
+      name: 'ChangePassword',
+      component: ChangePassword,
+      meta: { authorities: ['ROLE_USER'] }
+    },
+    {
+      path: '/account/settings',
+      name: 'Settings',
+      component: Settings,
+      meta: { authorities: ['ROLE_USER'] }
+    },
+    {
+      path: '/admin/user-management',
+      name: 'JhiUser',
+      component: JhiUserManagementComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    },
+    {
+      path: '/admin/user-management/new',
+      name: 'JhiUserCreate',
+      component: JhiUserManagementEditComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    },
+    {
+      path: '/admin/user-management/:userId/edit',
+      name: 'JhiUserEdit',
+      component: JhiUserManagementEditComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    },
+    {
+      path: '/admin/user-management/:userId/view',
+      name: 'JhiUserView',
+      component: JhiUserManagementViewComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    },
+    {
+      path: '/admin/docs',
+      name: 'JhiDocsComponent',
+      component: JhiDocsComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    },
+    {
+      path: '/admin/audits',
+      name: 'JhiAuditsComponent',
+      component: JhiAuditsComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    },
+    {
+      path: '/admin/jhi-health',
+      name: 'JhiHealthComponent',
+      component: JhiHealthComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    },
+    {
+      path: '/admin/logs',
+      name: 'JhiLogsComponent',
+      component: JhiLogsComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    },
+    {
+      path: '/admin/jhi-metrics',
+      name: 'JhiMetricsComponent',
+      component: JhiMetricsComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    },
+    {
+      path: '/admin/jhi-configuration',
+      name: 'JhiConfigurationComponent',
+      component: JhiConfigurationComponent,
+      meta: { authorities: ['ROLE_ADMIN'] }
+    }
+    // jhipster-needle-add-entity-to-router - JHipster will add entities to the router here
+  ]
+});
diff --git a/test/templates/vuejs-default/src/test/javascript/protractor.conf.js b/test/templates/vuejs-default/src/test/javascript/protractor.conf.js
new file mode 100644
index 0000000..a4f3f82
--- /dev/null
+++ b/test/templates/vuejs-default/src/test/javascript/protractor.conf.js
@@ -0,0 +1,63 @@
+exports.config = {
+    allScriptsTimeout: 20000,
+
+    specs: [
+        './e2e/modules/account/**/*.spec.ts',
+        './e2e/modules/administration/**/*.spec.ts',
+        /* jhipster-needle-add-protractor-tests - JHipster will add protractors tests here */
+        './e2e/entities/**/*.spec.ts'
+    ],
+
+    capabilities: {
+        browserName: 'chrome',
+        chromeOptions: {
+            args: process.env.JHI_E2E_HEADLESS
+                ? ['--headless', '--disable-gpu', '--window-size=800,600']
+                : ['--disable-gpu', '--window-size=800,600']
+        }
+    },
+
+    directConnect: true,
+
+    baseUrl: 'http://localhost:8080/',
+
+    framework: 'mocha',
+
+    SELENIUM_PROMISE_MANAGER: false,
+
+    mochaOpts: {
+        reporter: 'spec',
+        slow: 3000,
+        ui: 'bdd',
+        timeout: 60000
+    },
+
+    beforeLaunch() {
+        require('ts-node').register({
+            project: './tsconfig.e2e.json'
+        });
+    },
+
+    onPrepare() {
+        // @ts-ignore
+        browser.driver
+            .manage()
+            .window()
+            .setSize(1280, 1024);
+        // @ts-ignore
+        browser.ignoreSynchronization = true;
+        // Disable animations
+        // @ts-ignore
+        browser.executeScript('document.body.className += " notransition";');
+        const chai = require('chai');
+        const chaiAsPromised = require('chai-as-promised');
+        chai.use(chaiAsPromised);
+        // @ts-ignore
+        global.chai = chai;
+    },
+
+    params: {
+        waitTimeoutInMillis: 10000,
+        logWaitErrors: false
+    }
+};