My first e2e test and modifications to client to support it
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
{
|
{
|
||||||
"pluginsFile": "tests/e2e/plugins/index.js"
|
"pluginsFile": "tests/e2e/plugins/index.js",
|
||||||
}
|
"baseUrl": "http://localhost:8080",
|
||||||
|
"env": {
|
||||||
|
"adminusername": "manager",
|
||||||
|
"adminpassword": "l3tm3in"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,12 +49,6 @@ CURRENT TODOs
|
|||||||
|
|
||||||
@@@@@@@@@@@ ROADMAP STAGE 2:
|
@@@@@@@@@@@ ROADMAP STAGE 2:
|
||||||
|
|
||||||
todo: update all dependencies
|
|
||||||
- Widget form: After update now the controls show broken rule color for some reason and dirty checking isn't working as save doesn't enabled
|
|
||||||
- better test other stuff too, just did a quickie (looks like it's an issue with the rule processor for forms adn the dirty checking or input event)
|
|
||||||
- No errors in console, just acting weird
|
|
||||||
- Actually, it *knows* it's dirty because I get unsaved changes error, just doesn't enable the save button and displays as if there are broken rules but no text to go with
|
|
||||||
|
|
||||||
todo: Client automated testing
|
todo: Client automated testing
|
||||||
- Need several as basis for all future, make sure it's right.
|
- Need several as basis for all future, make sure it's right.
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"test:unit": "vue-cli-service test:unit",
|
"test:unit": "vue-cli-service test:unit",
|
||||||
"test:e2e": "vue-cli-service test:e2e",
|
"test:e2e": "vue-cli-service test:e2e",
|
||||||
|
"test:front": "vue-cli-service test:e2e --url http://localhost:8080",
|
||||||
"lint": "vue-cli-service lint",
|
"lint": "vue-cli-service lint",
|
||||||
"myLint": "npm run lint"
|
"myLint": "npm run lint"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,13 +19,13 @@
|
|||||||
:prepend-icon="item.icon"
|
:prepend-icon="item.icon"
|
||||||
:value="false"
|
:value="false"
|
||||||
:key="item.key"
|
:key="item.key"
|
||||||
|
:data-cy="item.testid"
|
||||||
>
|
>
|
||||||
<template v-slot:activator>
|
<template v-slot:activator>
|
||||||
<!--group activator -->
|
<!--group activator -->
|
||||||
<v-list-item-title>{{ item.title }}</v-list-item-title>
|
<v-list-item-title>{{ item.title }}</v-list-item-title>
|
||||||
</template>
|
</template>
|
||||||
<!-- TOP LEVEL HOLDER SUBITEMS -->
|
<!-- TOP LEVEL HOLDER SUBITEMS -->
|
||||||
|
|
||||||
<template v-for="subitem in item.navItems">
|
<template v-for="subitem in item.navItems">
|
||||||
<template v-if="!subitem.route">
|
<template v-if="!subitem.route">
|
||||||
<!-- SECOND LEVEL HOLDER -->
|
<!-- SECOND LEVEL HOLDER -->
|
||||||
@@ -64,7 +64,10 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<!-- SECOND LEVEL ACTION -->
|
<!-- SECOND LEVEL ACTION -->
|
||||||
<div class="pl-3" :key="subitem.key">
|
<div class="pl-3" :key="subitem.key">
|
||||||
<v-list-item :to="subitem.route">
|
<v-list-item
|
||||||
|
:to="subitem.route"
|
||||||
|
:data-cy="'nav' + subitem.route"
|
||||||
|
>
|
||||||
<v-list-item-action>
|
<v-list-item-action>
|
||||||
<v-icon v-if="subitem.icon">{{ subitem.icon }}</v-icon>
|
<v-icon v-if="subitem.icon">{{ subitem.icon }}</v-icon>
|
||||||
</v-list-item-action>
|
</v-list-item-action>
|
||||||
@@ -107,7 +110,10 @@
|
|||||||
fixed
|
fixed
|
||||||
app
|
app
|
||||||
>
|
>
|
||||||
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
|
<v-app-bar-nav-icon
|
||||||
|
@click.stop="drawer = !drawer"
|
||||||
|
data-cy="navicon"
|
||||||
|
></v-app-bar-nav-icon>
|
||||||
<v-toolbar-title style="width: 300px" class="ml-0 pl-4">
|
<v-toolbar-title style="width: 300px" class="ml-0 pl-4">
|
||||||
<v-icon>{{ appBar.icon }}</v-icon
|
<v-icon>{{ appBar.icon }}</v-icon
|
||||||
>
|
>
|
||||||
@@ -132,7 +138,7 @@
|
|||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-menu bottom float-left>
|
<v-menu bottom float-left>
|
||||||
<template v-slot:activator="{ on }">
|
<template v-slot:activator="{ on }">
|
||||||
<v-btn text icon v-on="on">
|
<v-btn text icon v-on="on" data-cy="contextmenu">
|
||||||
<v-icon>fa-ellipsis-v</v-icon>
|
<v-icon>fa-ellipsis-v</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
@@ -152,6 +158,7 @@
|
|||||||
:disabled="item.disabled"
|
:disabled="item.disabled"
|
||||||
@click="clickMenuItem(item)"
|
@click="clickMenuItem(item)"
|
||||||
v-bind:class="{ 'hidden-sm-and-up': item.surface }"
|
v-bind:class="{ 'hidden-sm-and-up': item.surface }"
|
||||||
|
:data-cy="item.key"
|
||||||
>
|
>
|
||||||
<v-list-item-action>
|
<v-list-item-action>
|
||||||
<v-icon
|
<v-icon
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
/* Xeslint-disable */
|
/* Xeslint-disable */
|
||||||
|
|
||||||
function addNavItem(title, icon, route, navItems, key) {
|
function addNavItem(title, icon, route, navItems, key, testid) {
|
||||||
|
if (!testid) {
|
||||||
|
testid = route;
|
||||||
|
}
|
||||||
window.$gz.store.commit("addNavItem", {
|
window.$gz.store.commit("addNavItem", {
|
||||||
title,
|
title,
|
||||||
icon,
|
icon,
|
||||||
route,
|
route,
|
||||||
navItems,
|
navItems,
|
||||||
key: key
|
key: key,
|
||||||
|
testid: testid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +161,8 @@ export default function initialize() {
|
|||||||
"fa-home",
|
"fa-home",
|
||||||
undefined,
|
undefined,
|
||||||
sub,
|
sub,
|
||||||
key++
|
key++,
|
||||||
|
"home"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +205,8 @@ export default function initialize() {
|
|||||||
"fa-address-book",
|
"fa-address-book",
|
||||||
undefined,
|
undefined,
|
||||||
sub,
|
sub,
|
||||||
key++
|
key++,
|
||||||
|
"customer"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +393,8 @@ export default function initialize() {
|
|||||||
"fa-toolbox",
|
"fa-toolbox",
|
||||||
undefined,
|
undefined,
|
||||||
sub,
|
sub,
|
||||||
key++
|
key++,
|
||||||
|
"service"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,7 +474,8 @@ export default function initialize() {
|
|||||||
"fa-box",
|
"fa-box",
|
||||||
undefined,
|
undefined,
|
||||||
sub,
|
sub,
|
||||||
key++
|
key++,
|
||||||
|
"inventory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,7 +496,8 @@ export default function initialize() {
|
|||||||
"fa-store",
|
"fa-store",
|
||||||
"/vendors",
|
"/vendors",
|
||||||
[],
|
[],
|
||||||
key++
|
key++,
|
||||||
|
"vendor"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,7 +525,8 @@ export default function initialize() {
|
|||||||
"fa-calculator",
|
"fa-calculator",
|
||||||
undefined,
|
undefined,
|
||||||
sub,
|
sub,
|
||||||
key++
|
key++,
|
||||||
|
"accounting"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +612,8 @@ export default function initialize() {
|
|||||||
"fa-user-tie",
|
"fa-user-tie",
|
||||||
undefined,
|
undefined,
|
||||||
sub,
|
sub,
|
||||||
key++
|
key++,
|
||||||
|
"administration"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,7 +679,8 @@ export default function initialize() {
|
|||||||
"fa-server",
|
"fa-server",
|
||||||
undefined,
|
undefined,
|
||||||
sub,
|
sub,
|
||||||
key++
|
key++,
|
||||||
|
"operations"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,7 +700,8 @@ export default function initialize() {
|
|||||||
"fa-vial",
|
"fa-vial",
|
||||||
"/widgets",
|
"/widgets",
|
||||||
[],
|
[],
|
||||||
key++
|
key++,
|
||||||
|
"widgets"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,7 +743,8 @@ export default function initialize() {
|
|||||||
"fa-home",
|
"fa-home",
|
||||||
undefined,
|
undefined,
|
||||||
sub,
|
sub,
|
||||||
key++
|
key++,
|
||||||
|
"homecustomer"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
62
ayanova/tests/e2e/specs/jwt-example.js
Normal file
62
ayanova/tests/e2e/specs/jwt-example.js
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// login just once using API
|
||||||
|
let user;
|
||||||
|
|
||||||
|
before(function fetchUser() {
|
||||||
|
cy.request("POST", "http://localhost:7575/api/v8/Auth", {
|
||||||
|
username: Cypress.env("adminusername"),
|
||||||
|
password: Cypress.env("adminpassword")
|
||||||
|
})
|
||||||
|
.its("body")
|
||||||
|
.then(res => {
|
||||||
|
user = res;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// but set the user before visiting the page
|
||||||
|
// so the app thinks it is already authenticated
|
||||||
|
beforeEach(function setUser() {
|
||||||
|
cy.visit("/", {
|
||||||
|
onBeforeLoad(win) {
|
||||||
|
// and before the page finishes loading
|
||||||
|
// set the user object in local storage
|
||||||
|
win.localStorage.setItem("user", JSON.stringify(user));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// the page should be opened and the user should be logged in
|
||||||
|
});
|
||||||
|
describe("The home page", () => {
|
||||||
|
it("Successfully loads the home page", () => {
|
||||||
|
cy.visit("/");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("JWT", () => {
|
||||||
|
it("makes authenticated request", () => {
|
||||||
|
// we can make authenticated request ourselves
|
||||||
|
// since we know the token
|
||||||
|
cy.request({
|
||||||
|
url: "http://localhost:7575/api/v8/User/1",
|
||||||
|
auth: {
|
||||||
|
bearer: user.token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.its("body")
|
||||||
|
.should("deep.equal", [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
username: "test",
|
||||||
|
firstName: "Test",
|
||||||
|
lastName: "User"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("is logged in", () => {
|
||||||
|
cy.contains("Hi Test!").should("be.visible");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows loaded user", () => {
|
||||||
|
// this user information came from authenticated XHR call
|
||||||
|
cy.contains("li", "Test User").should("be.visible");
|
||||||
|
});
|
||||||
|
});
|
||||||
29
ayanova/tests/e2e/specs/login-logout.js
Normal file
29
ayanova/tests/e2e/specs/login-logout.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// https://docs.cypress.io/api/introduction/api.html
|
||||||
|
|
||||||
|
describe("Login", () => {
|
||||||
|
it("Successfully logs in navigate and log out", () => {
|
||||||
|
cy.visit("/login");
|
||||||
|
|
||||||
|
cy.get("input[name=username]")
|
||||||
|
.clear()
|
||||||
|
.type(Cypress.env("adminusername"));
|
||||||
|
|
||||||
|
// {enter} causes the form to submit
|
||||||
|
cy.get("input[name=password]")
|
||||||
|
.clear()
|
||||||
|
.type(`${Cypress.env("adminpassword")}{enter}`);
|
||||||
|
|
||||||
|
// we should be redirected to /dashboard
|
||||||
|
cy.url().should("include", "/home-dashboard");
|
||||||
|
|
||||||
|
//navigate and confirm
|
||||||
|
//open nav and home menu
|
||||||
|
cy.get("[data-cy=navicon]").click();
|
||||||
|
cy.get("[data-cy=home]").click();
|
||||||
|
cy.get("[data-cy='nav/home-user-settings']").click();
|
||||||
|
cy.url().should("include", "/home-user-settings");
|
||||||
|
cy.get("[data-cy=contextmenu]").click();
|
||||||
|
cy.get("[data-cy='app:logout']").click();
|
||||||
|
cy.url().should("include", "/login");
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user