Creation of first tests, commands, and flow
gitea/hedera-web/pipeline/pr-4922-vueMigration This commit looks good Details

This commit is contained in:
William Buezas 2024-10-16 14:08:10 -03:00
parent bbaa6f936e
commit 9450be744a
13 changed files with 293 additions and 123 deletions

View File

@ -6,6 +6,12 @@ module.exports = defineConfig({
supportFile: 'src/test/cypress/support/index.js',
fixturesFolder: 'src/test/cypress/fixtures',
specPattern: 'src/test/cypress/integration/**/*.spec.js',
viewportHeight: 660,
viewportWidth: 1240,
experimentalMemoryManagement: true,
numTestsKeptInMemory: 0,
video: false,
screenshotOnRunFailure: false,
setupNodeEvents(on, config) {
// implement node event listeners here
}

View File

@ -69,8 +69,10 @@
"scripts": {
"front": "webpack serve --open",
"back": "cd ../vn-database && myvc start && cd ../salix && gulp backOnly",
"cy:open": "cypress open",
"test:e2e": "cypress run",
"cy:open": "cd ../salix && gulp docker && cd ../hedera-web && cypress open",
"test:e2e": "cd ../salix && gulp docker && cd ../hedera-web && cypress run",
"cy:open-mindshore": "cd ../salix && gulp docker && cd ../hedera-web-mindshore && cypress open",
"test:e2e-mindshore": "cd ../salix && gulp docker && cd ../hedera-web-mindshore && cypress run",
"build": "rm -rf build/ ; webpack",
"clean": "rm -rf build/",
"lint": "eslint --ext .js,.vue ./"

View File

@ -12,7 +12,10 @@ export default function useNotify() {
Notify.create({
message: i18n.global.t(message),
type,
icon: icon || defaultIcons[type]
icon: icon || defaultIcons[type],
attrs: {
'data-testid': `${type}Notify`
}
});
};

View File

@ -88,7 +88,13 @@ const logoutSupplantedUser = async () => {
<div class="user-info">
<div>
<span id="user-name">{{ mainUser?.nickname }}</span>
<QBtn flat icon="logout" alt="_Exit" @click="logout()" />
<QBtn
flat
icon="logout"
alt="_Exit"
@click="logout()"
data-testid="logoutButton"
/>
</div>
<div v-if="supplantedUser" id="supplant" class="supplant">
<span id="supplanted">

View File

@ -15,7 +15,12 @@ const { t } = useI18n();
</script>
<template>
<QCard v-if="viewMode === 'grid'" v-ripple class="catalog-card">
<QCard
v-if="viewMode === 'grid'"
v-ripple
class="catalog-card"
data-testid="catalogCardGrid"
>
<VnImg
storage="catalog"
size="200x200"
@ -23,7 +28,11 @@ const { t } = useI18n();
height="210px"
rounded="bottom"
/>
<div class="column" style="height: 205px; padding: 10px">
<div
class="column"
style="height: 205px; padding: 10px"
data-testid="catalogCardGridBody"
>
<div class="column" style="margin-bottom: auto">
<div class="text-subtitle2 ellipsis-2-lines">
{{ item.item }}
@ -98,7 +107,7 @@ const { t } = useI18n();
</div>
</div>
</QCard>
<CardList v-else class="vn-w-sm">
<CardList v-else class="vn-w-sm" data-testid="catalogCardList">
<template #prepend>
<VnImg
storage="catalog"

View File

@ -19,6 +19,7 @@
@click="redirectToBasket()"
rounded
no-caps
data-testid="catalogGoToBasketButton"
>
<QTooltip>
{{ t('shoppingCart') }}
@ -36,7 +37,7 @@
</div>
</Teleport>
<div style="padding-bottom: 5em">
<QDrawer v-model="rightDrawerOpen" side="right" :width="250">
<QDrawer v-model="rightDrawerOpen" side="right" :width="250" persistent>
<div class="q-pa-md">
<div class="basket-info q-gutter-y-sm">
<span v-if="order?.nickname">{{ order.nickname }}</span>
@ -49,7 +50,12 @@
})
}}
</span>
<QBtn rounded no-caps @click="redirectToCheckout()">
<QBtn
rounded
no-caps
@click="redirectToCheckout()"
data-testid="orderModifyButton"
>
{{ t('modify') }}
</QBtn>
</div>
@ -74,6 +80,7 @@
:class="{ active: category == cat.id }"
:key="cat.id"
@click="selectedCategory = cat.id"
data-testid="catalogCategoryButton"
>
<img :src="`statics/category/${cat.code}.svg`" />
<QTooltip>{{ cat.name }}</QTooltip>
@ -91,6 +98,7 @@
:options="itemFamilies"
:disable="!category"
:label="t('family')"
data-testid="catalogFamilySelect"
/>
<VnSelect
v-model="selectedColor"
@ -243,6 +251,7 @@
flat
dense
@click="onAddLotClick(lot)"
data-testid="addItemQuantityButton"
>
<QTooltip>{{ t('add') }}</QTooltip>
</QBtn>
@ -267,6 +276,7 @@
flat
color="white"
@click="onConfirmClick()"
data-testid="catalogAddToBasketButton"
>
<QTooltip>{{ t('confirm') }}</QTooltip>
</QBtn>

View File

@ -1,60 +1,10 @@
describe('User flow 1', () => {
// 1- Loguear como empleado
// 2- Ir a la sección de pedidos pendientes
// 3- Crear un pedido
beforeEach(() => {
cy.changeLanguage('es');
});
const checkoutNextStep = () => {
cy.get('[data-testid="checkoutStepperRightButton"]')
.should('be.visible')
.click();
};
it('should success', () => {
// 1- Loguear como empleado
cy.loginFlow('employee');
// 2- Ir a la sección de pedidos pendientes
cy.visit('/#/ecomerce/pending');
cy.get('[data-testid="pendingOrdersNewOrder"]').should('exist');
cy.get('[data-testid="pendingOrdersNewOrder"]').click();
// 3- Crear un pedido
cy.url().should('contain', '/#/ecomerce/checkout');
cy.get('[data-testid="checkoutStepper"]').should('exist');
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Quieres recibir o recoger el pedido?'
);
cy.get('[aria-label="Recibir en mi tienda"]').click();
checkoutNextStep();
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Qué día quieres recibir el pedido?'
);
checkoutNextStep();
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Dónde quieres recibir el pedido?'
);
cy.get('[data-testid="checkoutAddressStep"]').within(() => {
cy.get('label:first').click();
});
checkoutNextStep();
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Cómo quieres recibir el pedido?'
);
cy.get('[data-testid="agencyStepSelect"]').should('exist');
cy.selectOption('[data-testid="agencyStepSelect"]', 'Other agency');
checkoutNextStep();
checkoutNextStep();
cy.url().should('contain', '/#/ecomerce/catalog');
cy.get('.q-notification__message:first').should(
'have.text',
'¡Pedido cargado en la cesta!'
);
describe('User flow: Login, create a new order, add item to basket', () => {
it('success', () => {
// 2- Loguear como empleado
cy.login('employee');
// 2- Crear una orden
cy.CreateOrderReceiveFlow();
// 3- Filtrar items y agregar item al carrito
cy.AddItemToBasketFlow();
});
});

View File

@ -0,0 +1,16 @@
describe('CatalogView', () => {
beforeEach(() => {
// 1- Loguear usuario
cy.login('employee');
// 2- Crear una orden
cy.CreateOrderReceiveFlow();
});
it('Adds item to basket', () => cy.AddItemToBasketFlow());
it('Goes to basket', () => {
cy.get('[data-testid="catalogGoToBasketButton"]').should('exist');
cy.get('[data-testid="catalogGoToBasketButton"]').click();
cy.url().should('contain', '/#/ecomerce/basket');
});
});

View File

@ -0,0 +1,22 @@
Cypress.Commands.add('AddItemToBasketFlow', () => {
// 1- Seleccionar categoría
cy.get('[data-testid="catalogCategoryButton"]').should('exist');
cy.get('[data-testid="catalogCategoryButton"]:first').click();
// 2- Seleccionar familia
cy.get('[data-testid="catalogFamilySelect"]').should('exist');
cy.selectOption('[data-testid="catalogFamilySelect"]', 'Anthurium');
cy.getValue('[data-testid="catalogFamilySelect"]').should(
'equal',
'Anthurium'
);
cy.get('[data-testid="catalogFamilySelect"]').should('exist');
// 3- Seleccionar item
cy.get('[data-testid="catalogCardGridBody"]').should('exist');
cy.get('[data-testid="catalogCardGridBody"]:first').click();
// 4- Añadir item al carrito
cy.get('[data-testid="addItemQuantityButton"]').should('exist');
cy.get('[data-testid="addItemQuantityButton"]:first').click();
cy.get('[data-testid="catalogAddToBasketButton"]').should('exist');
cy.get('[data-testid="catalogAddToBasketButton"]').click();
cy.get('[data-testid="positiveNotify"]').should('include.text', 'Añadido');
});

View File

@ -0,0 +1,23 @@
describe('CheckoutStepper', () => {
beforeEach(() => {
cy.login('employee');
});
it('Creates new order to receive', () => cy.CreateOrderReceiveFlow());
it('Creates new pickup order', () => cy.CreateOrderPickupFlow());
it('Modifies an order', () => {
cy.CreateOrderReceiveFlow();
cy.get('[data-testid="orderModifyButton"]').click();
cy.get('[data-testid="warningNotify"]').should(
'include.text',
'Recuerda que si vuelves a configurar el pedido los precios o cantidades de tus artículos podrían cambiar'
);
cy.CreateOrderPickup(false);
cy.get('[data-testid="positiveNotify"]').should(
'include.text',
'Pedido actualizado'
);
});
});

View File

@ -0,0 +1,95 @@
const checkoutNextStep = () => {
cy.get('[data-testid="checkoutStepperRightButton"]')
.should('be.visible')
.click();
};
Cypress.Commands.add('CreateOrderReceive', () => {
cy.get('[data-testid="checkoutStepper"]').should('exist');
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Quieres recibir o recoger el pedido?'
);
cy.get('[aria-label="Recibir en mi tienda"]').click();
checkoutNextStep();
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Qué día quieres recibir el pedido?'
);
checkoutNextStep();
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Dónde quieres recibir el pedido?'
);
cy.get('[data-testid="checkoutAddressStep"]').within(() => {
cy.get('label:first').click();
});
checkoutNextStep();
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Cómo quieres recibir el pedido?'
);
cy.get('[data-testid="agencyStepSelect"]').should('exist');
cy.selectOption('[data-testid="agencyStepSelect"]', 'Other agency');
checkoutNextStep();
checkoutNextStep();
cy.url().should('contain', '/#/ecomerce/catalog');
});
Cypress.Commands.add('CreateOrderReceiveFlow', (changeLanguage = false) => {
if (changeLanguage) cy.changeLanguageFlow('es');
cy.visit('/#/ecomerce/pending');
cy.get('[data-testid="pendingOrdersNewOrder"]').should('exist');
cy.get('[data-testid="pendingOrdersNewOrder"]').click();
cy.CreateOrderReceive();
cy.get('.q-notification__message:first').should(
'have.text',
'¡Pedido cargado en la cesta!'
);
});
Cypress.Commands.add('CreateOrderPickup', () => {
cy.get('[data-testid="checkoutStepper"]').should('exist');
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Quieres recibir o recoger el pedido?'
);
cy.get('[aria-label="Recoger en almacén"]').click();
checkoutNextStep();
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿Qué día quieres recibir el pedido?'
);
checkoutNextStep();
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿A qué dirección quieres asociar el pedido? (Opcional)'
);
cy.get('[data-testid="checkoutAddressStep"]').within(() => {
cy.get('label:first').click();
});
checkoutNextStep();
cy.get('[data-testid="checkoutStepper"]').should(
'contain',
'¿En qué almacén quieres recoger tu pedido?'
);
cy.get('[data-testid="pickupStepSelect"]').should('exist');
cy.selectOption('[data-testid="pickupStepSelect"]', 'Teleportation device');
checkoutNextStep();
checkoutNextStep();
cy.url().should('contain', '/#/ecomerce/catalog');
});
Cypress.Commands.add('CreateOrderPickupFlow', (changeLanguage = false) => {
if (changeLanguage) cy.changeLanguageFlow('es');
cy.visit('/#/ecomerce/pending');
cy.get('[data-testid="pendingOrdersNewOrder"]').should('exist');
cy.get('[data-testid="pendingOrdersNewOrder"]').click();
cy.CreateOrderPickup();
cy.get('.q-notification__message:first').should(
'have.text',
'¡Pedido cargado en la cesta!'
);
});

View File

@ -0,0 +1,69 @@
// Login view commands
Cypress.Commands.add('login', user => {
cy.request({
method: 'POST',
url: '/api/Accounts/login',
body: {
user,
password: 'nightmare'
}
}).then(response => {
window.localStorage.setItem('token', response.body.token);
cy.request({
method: 'GET',
url: '/api/VnUsers/ShareToken',
headers: {
Authorization: window.localStorage.getItem('token')
}
}).then(({ body }) => {
window.localStorage.setItem(
'tokenMultimedia',
body.multimediaToken.id
);
});
});
});
Cypress.Commands.add('logout', user => {
cy.request({
method: 'POST',
url: '/api/Accounts/logout',
headers: {
Authorization: window.localStorage.getItem('token')
}
}).then(response => {
localStorage.clear();
sessionStorage.clear();
});
});
Cypress.Commands.add('loginFlow', (user, visitLogin = true) => {
if (visitLogin) cy.visit('/#/login');
cy.get('[data-testid="loginUserInput"]').type(user);
cy.getValue('[data-testid="loginUserInput"]').should('equal', user);
cy.get('[data-testid="loginPasswordInput"]').type('nightmare');
cy.getValue('[data-testid="loginPasswordInput"]').should(
'equal',
'nightmare'
);
cy.get('button[type="submit"]').click();
cy.url().should('contain', '/#/cms/home');
});
Cypress.Commands.add('waitForElement', (element, timeout = 5000) => {
cy.get(element, { timeout }).should('be.visible');
});
Cypress.Commands.add('changeLanguage', language => {
const languagesOrder = ['en', 'es', 'ca', 'fr', 'pt'];
const index = languagesOrder.indexOf(language);
cy.waitForElement('[data-testid="switchLanguage"]');
cy.get('[data-testid="switchLanguage"]').click();
cy.get('.q-menu .q-item').eq(index).click(); // Selecciona y hace clic en el tercer elemento "index" de la lista
});
Cypress.Commands.add('changeLanguageFlow', language => {
cy.visit('/#/login');
cy.changeLanguage(language);
});

View File

@ -24,65 +24,24 @@
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
Cypress.Commands.add('login', user => {
cy.request({
method: 'POST',
url: '/api/Accounts/login',
body: {
user,
password: 'nightmare'
}
}).then(response => {
window.localStorage.setItem('token', response.body.token);
cy.request({
method: 'GET',
url: '/api/VnUsers/ShareToken',
headers: {
Authorization: window.localStorage.getItem('token')
}
}).then(({ body }) => {
window.localStorage.setItem(
'tokenMultimedia',
body.multimediaToken.id
);
});
});
});
import '../integration/catalog/CatalogViewCommands'; // CatalogView component commands
import '../integration/login/LoginViewCommands'; // LoginView component commands
import '../integration/checkout/CheckoutStepperCommands'; // CheckoutStepper component commands
Cypress.Commands.add('loginFlow', user => {
cy.visit('/#/login');
cy.get('[data-testid="loginUserInput"]').type(user);
cy.get('[data-testid="loginPasswordInput"]').type('nightmare');
cy.get('button[type="submit"]').click();
cy.url().should('contain', '/#/cms/home');
});
Cypress.Commands.add('logout', user => {
cy.request({
method: 'POST',
url: 'Accounts/logout'
}).then(response => {
localStorage.clear();
sessionStorage.clear();
});
});
Cypress.Commands.add('waitForElement', (element, timeout = 5000) => {
cy.get(element, { timeout }).should('be.visible');
});
Cypress.Commands.add('changeLanguage', language => {
const languagesOrder = ['en', 'es', 'ca', 'fr', 'pt'];
const index = languagesOrder.indexOf(language);
cy.visit('/#/login');
cy.waitForElement('[data-testid="switchLanguage"]');
cy.get('[data-testid="switchLanguage"]').click();
cy.get('.q-menu .q-item').eq(index).click(); // Selecciona y hace clic en el tercer elemento "index" de la lista
});
// Fill Inputs
// Common commands
Cypress.Commands.add('selectOption', (selector, option) => {
cy.waitForElement(selector);
cy.get(selector).click();
cy.get('.q-menu .q-item').contains(option).click();
});
Cypress.Commands.add('getValue', selector => {
cy.get(selector).then($el => {
if ($el.find('.q-checkbox__inner').length > 0) {
// retornar el valor del atributo aria-checked
return cy.get(selector).invoke('attr', 'aria-checked');
} else {
return cy.get(selector).invoke('val');
}
});
});