Cypress initial config and tests #90
|
@ -68,7 +68,8 @@ module.exports = {
|
|||
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
|
||||
// https://github.com/prettier/eslint-config-prettier#installation
|
||||
// usage with Prettier, provided by 'eslint-config-prettier'.
|
||||
'prettier'
|
||||
'prettier',
|
||||
'plugin:cypress/recommended'
|
||||
],
|
||||
rules: {
|
||||
semi: 'off',
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
const { defineConfig } = require('cypress');
|
||||
|
||||
module.exports = defineConfig({
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:8080/',
|
||||
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) {
|
||||
on('after:spec', (spec, results) => {
|
||||
console.log('Finished running', spec.relative);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
|
@ -19,6 +19,7 @@
|
|||
"babel-loader": "^9.1.0",
|
||||
"bundle-loader": "^0.5.6",
|
||||
"css-loader": "^5.2.7",
|
||||
"cypress": "^13.15.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-standard": "^17.0.0",
|
||||
|
@ -53,6 +54,7 @@
|
|||
"@quasar/extras": "^1.0.0",
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "^3.6.5",
|
||||
"eslint-plugin-cypress": "^2.13.3",
|
||||
"js-yaml": "^3.12.1",
|
||||
"mootools": "^1.5.2",
|
||||
"pinia": "^2.0.11",
|
||||
|
@ -67,6 +69,11 @@
|
|||
"scripts": {
|
||||
"front": "webpack serve --open",
|
||||
"back": "cd ../vn-database && myvc start && cd ../salix && gulp backOnly",
|
||||
"resetDatabase": "cd ../salix && gulp docker",
|
||||
"cy:open": "npm run resetDatabase && cd ../hedera-web && cypress open",
|
||||
"test:e2e": "npm run resetDatabase && cd ../hedera-web && cypress run",
|
||||
|
||||
"cy:open-mindshore": "npm run resetDatabase && cd ../hedera-web-mindshore && cypress open",
|
||||
"test:e2e-mindshore": "npm run resetDatabase && cd ../hedera-web-mindshore && cypress run",
|
||||
jsegarra
commented
si definimos este script, no podemos usarlo en el resto? si definimos este script, no podemos usarlo en el resto?
wbuezas
commented
Si, claro que se puede, ahí lo apliqué. Commit: Si, claro que se puede, ahí lo apliqué.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/40444ac46a8fe7d223684268a313ca0432af5ecf
|
||||
"build": "rm -rf build/ ; webpack",
|
||||
"clean": "rm -rf build/",
|
||||
"lint": "eslint --ext .js,.vue ./"
|
||||
|
|
|
@ -240,6 +240,7 @@ defineExpose({
|
|||
flat
|
||||
:disabled="!showBottomActions && !updatedColumns.length"
|
||||
@click="submit()"
|
||||
data-testid="formDefaultSaveButton"
|
||||
>
|
||||
<QTooltip>{{ t('save') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
|
|
@ -91,6 +91,7 @@ async function confirm() {
|
|||
@click="confirm()"
|
||||
unelevated
|
||||
autofocus
|
||||
data-testid="confirmDialogButton"
|
||||
/>
|
||||
</QCardActions>
|
||||
</QCard>
|
||||
|
|
|
@ -71,6 +71,7 @@ onMounted(() => {
|
|||
is-outlined
|
||||
:clearable="false"
|
||||
class="searchbar"
|
||||
data-testid="searchBar"
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="search" class="cursor-pointer" @click="search()" />
|
||||
|
|
|
@ -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`
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ const appStore = useAppStore();
|
|||
const refreshContentKey = ref(0);
|
||||
const { mainUser, supplantedUser } = storeToRefs(userStore);
|
||||
const {
|
||||
customTitle,
|
||||
menuTitle,
|
||||
subtitle,
|
||||
useRightDrawer,
|
||||
|
@ -58,7 +59,7 @@ const logoutSupplantedUser = async () => {
|
|||
@click="toggleLeftDrawer"
|
||||
/>
|
||||
<QToolbarTitle>
|
||||
{{ menuTitle }}
|
||||
{{ customTitle || menuTitle }}
|
||||
<div v-if="subtitle" class="subtitle text-caption">
|
||||
{{ subtitle }}
|
||||
</div>
|
||||
|
@ -76,16 +77,34 @@ const logoutSupplantedUser = async () => {
|
|||
</QBtn>
|
||||
</QToolbar>
|
||||
</QHeader>
|
||||
<QDrawer v-model="leftDrawerOpen" :width="250" show-if-above>
|
||||
<QDrawer
|
||||
v-model="leftDrawerOpen"
|
||||
:width="250"
|
||||
show-if-above
|
||||
data-testid="layoutMenuDrawer"
|
||||
>
|
||||
<QToolbar class="logo">
|
||||
<img src="statics/logo-dark.svg" />
|
||||
</QToolbar>
|
||||
<div class="user-info">
|
||||
<div>
|
||||
<span id="user-name">{{ mainUser?.nickname }}</span>
|
||||
<QBtn flat icon="logout" alt="_Exit" @click="logout()" />
|
||||
<span id="user-name" data-testid="layoutUserName">
|
||||
{{ mainUser?.nickname }}
|
||||
</span>
|
||||
<QBtn
|
||||
flat
|
||||
icon="logout"
|
||||
alt="_Exit"
|
||||
@click="logout()"
|
||||
data-testid="logoutButton"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="supplantedUser" id="supplant" class="supplant">
|
||||
<div
|
||||
v-if="supplantedUser"
|
||||
id="supplant"
|
||||
class="supplant"
|
||||
data-testid="layoutSupplantedUserName"
|
||||
>
|
||||
<span id="supplanted">
|
||||
{{ supplantedUser?.nickname }}
|
||||
</span>
|
||||
|
|
|
@ -115,6 +115,7 @@ onMounted(() => fetchLanguagesSql());
|
|||
:label="t('nickname')"
|
||||
@keyup.enter="updateUserNickname(data.nickname)"
|
||||
@blur="updateUserNickname(data.nickname)"
|
||||
data-testid="configViewNickname"
|
||||
/>
|
||||
<VnSelect
|
||||
v-model="data.lang"
|
||||
|
|
|
@ -90,24 +90,39 @@ onMounted(() => getCountries());
|
|||
@on-data-saved="goBack()"
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<VnInput v-model="data.nickname" :label="t('name')" />
|
||||
<VnInput v-model="data.street" :label="t('address')" />
|
||||
<VnInput v-model="data.city" :label="t('city')" />
|
||||
<VnInput
|
||||
v-model="data.nickname"
|
||||
:label="t('name')"
|
||||
data-testid="addressFormNickname"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.street"
|
||||
:label="t('address')"
|
||||
data-testid="addressFormStreet"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.city"
|
||||
:label="t('city')"
|
||||
data-testid="addressFormCity"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.postalCode"
|
||||
type="number"
|
||||
:label="t('postalCode')"
|
||||
data-testid="addressFormPostcode"
|
||||
/>
|
||||
<VnSelect
|
||||
v-model="data.countryFk"
|
||||
:label="t('country')"
|
||||
:options="countriesOptions"
|
||||
@update:model-value="data.provinceFk = null"
|
||||
data-testid="addressFormCountry"
|
||||
/>
|
||||
<VnSelect
|
||||
v-model="data.provinceFk"
|
||||
:label="t('province')"
|
||||
:options="provincesOptions"
|
||||
data-testid="addressFormProvince"
|
||||
/>
|
||||
</template>
|
||||
</VnForm>
|
||||
|
|
|
@ -98,6 +98,7 @@ onMounted(async () => {
|
|||
@click="goToAddressDetails()"
|
||||
rounded
|
||||
no-caps
|
||||
data-testid="newAddressBtn"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('addAddress') }}
|
||||
|
@ -109,6 +110,7 @@ onMounted(async () => {
|
|||
class="rounded-borders shadow-1 shadow-transition"
|
||||
separator
|
||||
:rows="addresses"
|
||||
data-testid="addressCardList"
|
||||
>
|
||||
<CardList
|
||||
v-for="(address, index) in addresses"
|
||||
|
@ -156,6 +158,7 @@ onMounted(async () => {
|
|||
flat
|
||||
rounded
|
||||
@click.stop="goToAddressDetails(address.id)"
|
||||
data-testid="editAddressBtn"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('editAddress') }}
|
||||
|
|
|
@ -44,11 +44,13 @@ const onSearch = data => (items.value = data || []);
|
|||
empty-icon="refresh"
|
||||
:loading="loading"
|
||||
:rows="items"
|
||||
data-testid="itemsViewList"
|
||||
>
|
||||
<CardList
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
:clickable="false"
|
||||
data-testid="itemsViewCard"
|
||||
jsegarra
commented
y si le concatenamos el indice? y si le concatenamos el indice?
|
||||
>
|
||||
<template #prepend>
|
||||
<VnImg
|
||||
|
|
|
@ -106,6 +106,7 @@ onMounted(async () => {
|
|||
v-model="data.title"
|
||||
:label="t('title')"
|
||||
:clearable="false"
|
||||
data-testid="newsTitleInput"
|
||||
/>
|
||||
<div class="row justify-between q-gutter-x-md">
|
||||
<VnSelect
|
||||
|
@ -115,12 +116,14 @@ onMounted(async () => {
|
|||
option-value="name"
|
||||
:options="newsTags"
|
||||
class="col"
|
||||
data-testid="newsTagSelect"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.priority"
|
||||
:label="t('priority')"
|
||||
:clearable="false"
|
||||
class="col"
|
||||
data-testid="newsPriorityInput"
|
||||
/>
|
||||
</div>
|
||||
<QEditor
|
||||
|
|
|
@ -64,6 +64,7 @@ onMounted(async () => getNews());
|
|||
:to="{ name: 'adminNewsDetails' }"
|
||||
rounded
|
||||
no-caps
|
||||
data-testid="addNewBtn"
|
||||
>
|
||||
<QTooltip>{{ t('addNew') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -74,6 +75,7 @@ onMounted(async () => getNews());
|
|||
v-for="(newsItem, index) in news"
|
||||
:key="index"
|
||||
:to="{ name: 'adminNewsDetails', params: { id: newsItem.id } }"
|
||||
data-testid="newsCard"
|
||||
>
|
||||
<template #prepend>
|
||||
<VnImg
|
||||
|
@ -106,6 +108,7 @@ onMounted(async () => getNews());
|
|||
() => deleteNew(newsItem.id, index)
|
||||
)
|
||||
"
|
||||
data-testid="deleteNewBtn"
|
||||
>
|
||||
<QTooltip>{{ t('remove') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
|
|
@ -153,6 +153,7 @@ onMounted(async () => getImageCollections());
|
|||
option-label="desc"
|
||||
option-value="name"
|
||||
:options="imageCollections"
|
||||
data-testid="photoCollectionSelect"
|
||||
/>
|
||||
<QUploader
|
||||
ref="fileUploaderRef"
|
||||
|
@ -164,13 +165,19 @@ onMounted(async () => getImageCollections());
|
|||
bordered
|
||||
hide-upload-btn
|
||||
@added="onFilesAdded"
|
||||
data-testid="photoUploader"
|
||||
>
|
||||
<template #list="scope">
|
||||
<QList v-if="addedFiles.length" separator>
|
||||
<QList
|
||||
v-if="addedFiles.length"
|
||||
separator
|
||||
data-testid="photoUploaderList"
|
||||
>
|
||||
<QItem
|
||||
v-for="(file, index) in scope.files"
|
||||
:key="file.__key"
|
||||
class="flex full-width row items-center justify-center"
|
||||
data-testid="photoUploaderItem"
|
||||
>
|
||||
<img
|
||||
:src="file.__img.src"
|
||||
|
@ -204,6 +211,7 @@ onMounted(async () => getImageCollections());
|
|||
].icon
|
||||
"
|
||||
size="sm"
|
||||
data-testid="photoUploaderItemsStatusIcon"
|
||||
>
|
||||
<QTooltip>
|
||||
{{
|
||||
|
@ -229,6 +237,7 @@ onMounted(async () => getImageCollections());
|
|||
round
|
||||
icon="delete"
|
||||
@click="removeFile(file, index)"
|
||||
data-testid="photoUploaderItemsDeleteBtn"
|
||||
>
|
||||
<QTooltip>{{ t('remove') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -248,6 +257,7 @@ onMounted(async () => getImageCollections());
|
|||
no-caps
|
||||
flat
|
||||
@click="clearFiles()"
|
||||
data-testid="photoUploaderClearBtn"
|
||||
/>
|
||||
<QBtn
|
||||
:label="t('uploadFiles')"
|
||||
|
@ -256,6 +266,7 @@ onMounted(async () => getImageCollections());
|
|||
flat
|
||||
:disable="!isSubmitable"
|
||||
@click="onSubmit(data)"
|
||||
data-testid="photoUploadSubmitBtn"
|
||||
/>
|
||||
</template>
|
||||
</VnForm>
|
||||
|
|
|
@ -47,6 +47,7 @@ const supplantUser = async user => {
|
|||
search-field="user"
|
||||
@on-search="onSearch"
|
||||
@on-search-error="users = []"
|
||||
data-testid="usersViewSearchBar"
|
||||
/>
|
||||
</Teleport>
|
||||
<QPage class="vn-w-xs">
|
||||
|
@ -56,11 +57,13 @@ const supplantUser = async user => {
|
|||
empty-icon="refresh"
|
||||
:loading="loading"
|
||||
:rows="users"
|
||||
data-testid="usersViewList"
|
||||
>
|
||||
<CardList
|
||||
v-for="(user, index) in users"
|
||||
:key="index"
|
||||
:to="{ name: 'accessLog', params: { id: user.id } }"
|
||||
data-testid="userViewCard"
|
||||
>
|
||||
<template #content>
|
||||
<span class="text-bold q-mb-sm">
|
||||
|
@ -75,6 +78,7 @@ const supplantUser = async user => {
|
|||
flat
|
||||
rounded
|
||||
@click.stop.prevent="supplantUser(user.name)"
|
||||
data-testid="usersViewSupplantUserBtn"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('Impersonate user') }}
|
||||
|
|
|
@ -122,6 +122,7 @@ const fetchData = async () => {
|
|||
:to="{ name: 'confirm', params: { id: orderId } }"
|
||||
rounded
|
||||
no-caps
|
||||
data-testid="basketToConfirmBtn"
|
||||
>
|
||||
<QTooltip>{{ t('checkout') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
@ -278,7 +288,14 @@
|
|||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { inject, onBeforeMount, ref, computed, watch } from 'vue';
|
||||
import {
|
||||
inject,
|
||||
onBeforeMount,
|
||||
ref,
|
||||
computed,
|
||||
watch,
|
||||
onBeforeUnmount
|
||||
} from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import VnImg from 'src/components/ui/VnImg.vue';
|
||||
|
@ -880,29 +897,31 @@ const onConfirmClick = async params => {
|
|||
|
||||
const refreshTitle = () => {
|
||||
const { meta } = route;
|
||||
let title = t(meta.title);
|
||||
const title = t(meta.title);
|
||||
let subtitle;
|
||||
let customTitle;
|
||||
|
||||
if (selectedCategory.value) {
|
||||
const _category = categories.value.find(
|
||||
i => i.id === selectedCategory.value
|
||||
);
|
||||
if (_category) {
|
||||
title = _category.name;
|
||||
const categoryName = _category.name;
|
||||
customTitle = categoryName;
|
||||
|
||||
if (selectedType.value) {
|
||||
const _type = itemFamilies.value.find(
|
||||
i => i.id === selectedType.value
|
||||
);
|
||||
if (_type) {
|
||||
subtitle = title;
|
||||
title = _type.name;
|
||||
subtitle = categoryName;
|
||||
customTitle = _type.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appStore.$patch({ title, subtitle });
|
||||
appStore.$patch({ title, subtitle, customTitle });
|
||||
};
|
||||
|
||||
const onViewModeClick = () => {
|
||||
|
@ -955,6 +974,8 @@ onBeforeMount(async () => {
|
|||
selectedCategory.value = Number(route.params.category);
|
||||
if (route.params.type) selectedType.value = Number(route.params.type);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => appStore.resetCustomTitle());
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -30,7 +30,7 @@ const currentStep = ref('method');
|
|||
const id = route.params.id;
|
||||
const orderForm = ref({
|
||||
method: 'AGENCY',
|
||||
date: '',
|
||||
date: formatDate(Date.vnNew(), 'YYYY/MM/DD'),
|
||||
address: ''
|
||||
});
|
||||
|
||||
|
@ -322,6 +322,7 @@ onMounted(async () => {
|
|||
:flat="isMobile"
|
||||
contracted
|
||||
class="default-radius stepper-container"
|
||||
data-testid="checkoutStepper"
|
||||
>
|
||||
<QStep
|
||||
v-for="(step, stepIndex) in steps[orderForm.method]"
|
||||
|
@ -374,6 +375,7 @@ onMounted(async () => {
|
|||
<QList
|
||||
v-if="step.name === 'address'"
|
||||
class="vn-w-xs q-gutter-y-sm column"
|
||||
data-testid="checkoutAddressStep"
|
||||
>
|
||||
<span class="text-h6 step-title">
|
||||
{{
|
||||
|
@ -417,6 +419,7 @@ onMounted(async () => {
|
|||
option-label="description"
|
||||
option-value="id"
|
||||
:options="agencies"
|
||||
data-testid="agencyStepSelect"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
@ -431,6 +434,7 @@ onMounted(async () => {
|
|||
option-label="description"
|
||||
option-value="id"
|
||||
:options="warehouses"
|
||||
data-testid="pickupStepSelect"
|
||||
/>
|
||||
</div>
|
||||
<!-- Confirm step -->
|
||||
|
@ -457,6 +461,7 @@ onMounted(async () => {
|
|||
icon="arrow_back"
|
||||
dense
|
||||
class="left-navigation-button"
|
||||
data-testid="checkoutStepperLeftButton"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t(`${step.backButtonLabel || 'back'}`) }}
|
||||
|
@ -471,6 +476,7 @@ onMounted(async () => {
|
|||
"
|
||||
dense
|
||||
class="right-navigation-button"
|
||||
data-testid="checkoutStepperRightButton"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t(`${step.nextButtonLabel || 'next'}`) }}
|
||||
|
|
|
@ -73,6 +73,7 @@ const onConfirmPay = async () => {
|
|||
@click="onPayClick()"
|
||||
rounded
|
||||
no-caps
|
||||
data-testid="makePaymentButton"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('makePayment') }}
|
||||
|
@ -124,6 +125,7 @@ const onConfirmPay = async () => {
|
|||
v-model="showAmountToPayDialog"
|
||||
message=" "
|
||||
:promise="onConfirmPay"
|
||||
data-testid="payAmountDialog"
|
||||
>
|
||||
<template #customHTML>
|
||||
<VnInput
|
||||
|
@ -133,6 +135,7 @@ const onConfirmPay = async () => {
|
|||
type="number"
|
||||
min="0"
|
||||
:max="debt * -1"
|
||||
data-testid="payAmountInput"
|
||||
>
|
||||
<template #append>€</template>
|
||||
</VnInput>
|
||||
|
|
|
@ -71,6 +71,7 @@ onMounted(async () => {
|
|||
<template>
|
||||
<Teleport v-if="isHeaderMounted" to="#actions">
|
||||
<QBtn
|
||||
data-testid="pendingOrdersNewOrder"
|
||||
:to="{ name: 'checkout' }"
|
||||
icon="add_shopping_cart"
|
||||
:label="t('newOrder')"
|
||||
|
@ -83,11 +84,16 @@ onMounted(async () => {
|
|||
</QBtn>
|
||||
</Teleport>
|
||||
<QPage class="vn-w-sm">
|
||||
<VnList :rows="orders" :loading="loading">
|
||||
<VnList
|
||||
:rows="orders"
|
||||
:loading="loading"
|
||||
data-testid="pendingOrdersList"
|
||||
>
|
||||
<CardList
|
||||
v-for="(order, index) in orders"
|
||||
:key="index"
|
||||
:to="{ name: 'basket', params: { id: order.id } }"
|
||||
data-testid="pendingOrderCard"
|
||||
>
|
||||
<template #content>
|
||||
<QItemLabel class="text-bold q-mb-sm">
|
||||
|
@ -110,6 +116,7 @@ onMounted(async () => {
|
|||
() => removeOrder(order.id, index)
|
||||
)
|
||||
"
|
||||
data-testid="pendingOrderCardDelete"
|
||||
>
|
||||
<QTooltip>{{ t('deleteOrder') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -118,6 +125,7 @@ onMounted(async () => {
|
|||
flat
|
||||
rounded
|
||||
@click.stop.prevent="loadOrder(order.id)"
|
||||
data-testid="addOrderToBasket"
|
||||
>
|
||||
<QTooltip>{{ t('loadOrderIntoCart') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
|
|
@ -111,7 +111,7 @@ const deleteRow = id => {
|
|||
</QCardSection>
|
||||
<QSeparator v-if="showItems" inset />
|
||||
<QList v-for="(row, index) in rows" :key="index">
|
||||
<QItem v-if="row">
|
||||
<QItem v-if="row" data-testid="basketItemRow">
|
||||
<QItemSection v-if="canDeleteItems" avatar>
|
||||
<QBtn
|
||||
icon="delete"
|
||||
|
|
|
@ -47,7 +47,7 @@ onMounted(() => {
|
|||
|
||||
const onLogin = async () => {
|
||||
await userStore.fetchUser();
|
||||
await router.push('/');
|
||||
await router.push({ name: 'home' });
|
||||
};
|
||||
|
||||
const login = async () => {
|
||||
|
@ -69,14 +69,21 @@ const loginAsGuest = async () => {
|
|||
</div>
|
||||
<QForm @submit="login()" class="q-gutter-y-md">
|
||||
<div class="q-gutter-y-sm">
|
||||
<QInput v-model="email" :label="$t('user')" autofocus />
|
||||
<QInput
|
||||
v-model="email"
|
||||
:label="$t('user')"
|
||||
autofocus
|
||||
data-testid="loginUserInput"
|
||||
/>
|
||||
<QInput
|
||||
v-model="password"
|
||||
:label="$t('password')"
|
||||
:type="!showPwd ? 'password' : 'text'"
|
||||
data-testid="loginPasswordInput"
|
||||
>
|
||||
<template #append>
|
||||
<QIcon
|
||||
data-testid="showPasswordIcon"
|
||||
:name="showPwd ? 'visibility_off' : 'visibility'"
|
||||
class="cursor-pointer"
|
||||
@click="showPwd = !showPwd"
|
||||
|
@ -85,12 +92,14 @@ const loginAsGuest = async () => {
|
|||
</QInput>
|
||||
<div class="row justify-between text-center">
|
||||
<QCheckbox
|
||||
data-testid="rememberCheckbox"
|
||||
v-model="remember"
|
||||
:label="$t('remindMe')"
|
||||
dense
|
||||
class="col"
|
||||
/>
|
||||
<QSelect
|
||||
data-testid="switchLanguage"
|
||||
v-model="selectedLocaleValue"
|
||||
:options="localeOptions"
|
||||
:label="t('language')"
|
||||
|
@ -117,6 +126,7 @@ const loginAsGuest = async () => {
|
|||
</div>
|
||||
<div class="justify-center">
|
||||
<QBtn
|
||||
data-testid="loginAsGuestButton"
|
||||
@click="loginAsGuest()"
|
||||
:label="$t('logInAsGuest')"
|
||||
class="full-width"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { route } from 'quasar/wrappers';
|
||||
import { useAppStore } from 'stores/app';
|
||||
import { useUserStore } from 'stores/user';
|
||||
jsegarra
commented
IR a remember-password no va, ❌ IR a remember-password no va, ❌
|
||||
import {
|
||||
createRouter,
|
||||
createMemoryHistory,
|
||||
|
@ -36,6 +37,20 @@ export default route(function (/* { store, ssrContext } */) {
|
|||
)
|
||||
});
|
||||
|
||||
Router.beforeEach((to, from, next) => {
|
||||
const userStore = useUserStore();
|
||||
|
||||
if (
|
||||
!userStore.storage.getItem('token') &&
|
||||
to.name !== 'login' &&
|
||||
!userStore.isGuest
|
||||
) {
|
||||
return next({ name: 'login' });
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
Router.afterEach((to, from) => {
|
||||
if (from.name === to.name) return;
|
||||
const app = useAppStore();
|
||||
|
|
|
@ -10,6 +10,7 @@ const { t } = i18n.global;
|
|||
|
||||
export const useAppStore = defineStore('hedera', {
|
||||
state: () => ({
|
||||
customTitle: null,
|
||||
title: null,
|
||||
subtitle: null,
|
||||
imageUrl: '',
|
||||
|
@ -160,6 +161,10 @@ export const useAppStore = defineStore('hedera', {
|
|||
i18n.global.locale.value = _locale;
|
||||
this.siteLang = _locale;
|
||||
localStorage.setItem('siteLang', _locale);
|
||||
},
|
||||
|
||||
resetCustomTitle() {
|
||||
this.customTitle = null;
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
|
|
|
@ -22,16 +22,16 @@ export const useUserStore = defineStore('user', () => {
|
|||
const tokenConfig = ref(null);
|
||||
let router;
|
||||
|
||||
const loggedIn = computed(() => !!token.value);
|
||||
const storage = computed(() =>
|
||||
keepLogin.value ? localStorage : sessionStorage
|
||||
);
|
||||
const isLoggedIn = computed(() => !!storage.value.getItem(TOKEN));
|
||||
|
||||
const init = async _router => {
|
||||
router = _router;
|
||||
isGuest.value = localStorage.getItem('hederaGuest') || false;
|
||||
await getToken();
|
||||
if (!loggedIn.value) {
|
||||
if (!isLoggedIn.value) {
|
||||
const autoLoginStatus = await tryAutoLogin();
|
||||
if (!autoLoginStatus) {
|
||||
router.push({ name: 'login' });
|
||||
|
@ -285,7 +285,6 @@ export const useUserStore = defineStore('user', () => {
|
|||
watch(
|
||||
[mainUser, supplantedUser],
|
||||
() => (user.value = supplantedUser.value || mainUser.value),
|
||||
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
|
@ -300,7 +299,7 @@ export const useUserStore = defineStore('user', () => {
|
|||
intervalId,
|
||||
isCheckingToken,
|
||||
tokenConfig,
|
||||
loggedIn,
|
||||
isLoggedIn,
|
||||
storage,
|
||||
getToken,
|
||||
getTokenMultimedia,
|
||||
|
|
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 36 KiB |
|
@ -0,0 +1,25 @@
|
|||
describe('User flow: Login, create a new order, add item to basket and go to confirm view', () => {
|
||||
before(() => {
|
||||
cy.resetDB();
|
||||
});
|
||||
|
||||
it('success', () => {
|
||||
// 1- Loguear como empleado
|
||||
cy.login('employee');
|
||||
// 2- Crear una orden
|
||||
cy.createOrderReceiveFlow();
|
||||
// 3- Filtrar items y agregar item al carrito
|
||||
cy.addItemToBasketFlow();
|
||||
// 4- Ir al carrito
|
||||
cy.dataCy('catalogGoToBasketButton').should('exist');
|
||||
cy.dataCy('catalogGoToBasketButton').click();
|
||||
cy.url().should('contain', '/#/ecomerce/basket');
|
||||
// 5- Verificar que el item se agregó al carrito
|
||||
cy.dataCy('basketItemRow').should('exist');
|
||||
cy.dataCy('basketItemRow').should('have.length', 1);
|
||||
// 6- Ir a la vista de confirmación
|
||||
cy.dataCy('basketToConfirmBtn').should('exist');
|
||||
cy.dataCy('basketToConfirmBtn').click();
|
||||
cy.url().should('contain', '/#/ecomerce/confirm');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,26 @@
|
|||
describe('NewsView', () => {
|
||||
beforeEach(() => {
|
||||
cy.login('developer');
|
||||
cy.visit('/#/admin/items');
|
||||
});
|
||||
|
||||
it('shows empty state', () => {
|
||||
cy.dataCy('itemsViewList').should('exist');
|
||||
cy.dataCy('itemsViewList').should(
|
||||
'contain',
|
||||
'Introduce un término de búsqueda'
|
||||
);
|
||||
cy.dataCy('itemsViewCard').should('not.exist');
|
||||
});
|
||||
|
||||
it('search for an item', () => {
|
||||
cy.dataCy('searchBar').should('exist');
|
||||
cy.dataCy('searchBar').find('input').type('Bolas de madera{enter}');
|
||||
cy.dataCy('itemsViewList').should(
|
||||
'not.contain',
|
||||
'Introduce un término de búsqueda'
|
||||
);
|
||||
cy.dataCy('itemsViewCard').should('exist');
|
||||
cy.dataCy('itemsViewCard').should('contain', 'Bolas de madera');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,42 @@
|
|||
describe('NewsView', () => {
|
||||
before(() => {
|
||||
cy.resetDB();
|
||||
jsegarra
commented
Este comando lo veo bien, pero cuando sea un before:run https://docs.cypress.io/api/node-events/before-run-api Este comando lo veo bien, pero cuando sea un before:run https://docs.cypress.io/api/node-events/before-run-api
No entiendo la necesidad de hacerlo en cada test, e incluso CatalogView lo tiene 2 veces. Es para que al tirarlo de manera individual, se refresque?
wbuezas
commented
Entiendo lo que comentas, en base a esto, se te ocurre alguna alternativa para poder ejecutar diferentes tests sin que fallen los siguientes por haber creado / modificado data previamente? Entiendo lo que comentas, en base a esto, se te ocurre alguna alternativa para poder ejecutar diferentes tests sin que fallen los siguientes por haber creado / modificado data previamente?
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login('developer');
|
||||
cy.visit('/#/news/news');
|
||||
});
|
||||
|
||||
it('should delete a new', () => {
|
||||
cy.dataCy('newsCard').should('exist');
|
||||
cy.dataCy('newsCard').should('have.length', 3);
|
||||
cy.dataCy('newsCard')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.dataCy('deleteNewBtn').click();
|
||||
});
|
||||
cy.setConfirmDialog();
|
||||
cy.checkNotify('positive', 'Datos guardados');
|
||||
cy.dataCy('newsCard').should('have.length', 2);
|
||||
});
|
||||
|
||||
it('should create a new', () => {
|
||||
cy.dataCy('addNewBtn').should('exist');
|
||||
cy.dataCy('addNewBtn').click();
|
||||
cy.dataCy('formDefaultSaveButton').should('exist');
|
||||
cy.dataCy('formDefaultSaveButton').should('be.disabled');
|
||||
cy.dataCy('newsTitleInput').should('exist');
|
||||
cy.dataCy('newsTitleInput').find('input').type('Test new');
|
||||
jsegarra
commented
podemos hacer cy.dataCy(lo que sea).find('input') podemos hacer cy.dataCy(lo que sea).find('input')
Lo he tirado y en verde
wbuezas
commented
Concuerdo con la propuesta, aplicada. Commmit: Concuerdo con la propuesta, aplicada.
Commmit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/f70b98b514741336dba895a5900ff45ef6bc68bd
|
||||
cy.dataCy('newsTagSelect').should('exist');
|
||||
cy.selectOption('[data-testid="newsTagSelect"]', 'Curso');
|
||||
cy.dataCy('newsPriorityInput').should('exist');
|
||||
cy.dataCy('newsPriorityInput').find('input').type('2');
|
||||
cy.dataCy('formDefaultSaveButton').should('not.be.disabled');
|
||||
cy.dataCy('formDefaultSaveButton').click();
|
||||
cy.checkNotify('positive', 'Datos guardados');
|
||||
cy.dataCy('newsCard').should('exist');
|
||||
cy.dataCy('newsCard').should('contain', 'Test new');
|
||||
cy.dataCy('newsCard').should('contain', '2');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,80 @@
|
|||
describe('Photo Uploader Component', () => {
|
||||
beforeEach(() => {
|
||||
cy.login('developer');
|
||||
cy.visit('/#/admin/photos');
|
||||
});
|
||||
|
||||
const uploadFile = fileName => {
|
||||
cy.get('.q-uploader__input').selectFile(fileName);
|
||||
};
|
||||
|
||||
it('should display the photo collection select', () => {
|
||||
// Verificar que el select de colección esté presente
|
||||
cy.dataCy('photoCollectionSelect').should('exist');
|
||||
});
|
||||
|
||||
it('should allow selecting a photo collection', () => {
|
||||
// Simular la selección de una colección de fotos
|
||||
cy.selectOption('[data-testid="photoCollectionSelect"]', 'Enlace');
|
||||
cy.getValue('[data-testid="photoCollectionSelect"]').should(
|
||||
'equal',
|
||||
'Enlace'
|
||||
);
|
||||
});
|
||||
|
||||
it('submit button should be disabled if no files are selected', () => {
|
||||
cy.dataCy('photoUploadSubmitBtn').should('be.disabled');
|
||||
});
|
||||
|
||||
it('should allow adding files', () => {
|
||||
cy.dataCy('photoUploaderItem').should('not.exist');
|
||||
uploadFile('src/test/cypress/fixtures/lowres.jpg');
|
||||
cy.dataCy('photoUploaderItem').should('exist');
|
||||
cy.dataCy('photoUploaderItem').should('have.length', 1);
|
||||
});
|
||||
|
||||
it('should remove a file when delete button is clicked', () => {
|
||||
uploadFile('src/test/cypress/fixtures/lowres.jpg');
|
||||
|
||||
cy.dataCy('photoUploaderItem').should('exist');
|
||||
cy.dataCy('photoUploaderItemsDeleteBtn').click();
|
||||
cy.dataCy('photoUploaderItem').should('not.exist');
|
||||
});
|
||||
|
||||
it('should enable the upload button when files are pending', () => {
|
||||
uploadFile('src/test/cypress/fixtures/lowres.jpg');
|
||||
cy.dataCy('photoUploadSubmitBtn').should('not.be.disabled');
|
||||
});
|
||||
|
||||
it('should upload files when submit button is clicked', () => {
|
||||
uploadFile('src/test/cypress/fixtures/lowres.jpg');
|
||||
cy.dataCy('photoUploadSubmitBtn').click();
|
||||
cy.checkNotify('positive', 'Imágenes subidas correctamente');
|
||||
});
|
||||
|
||||
it('should show the correct status icon', () => {
|
||||
uploadFile('src/test/cypress/fixtures/lowres.jpg');
|
||||
cy.dataCy('photoUploaderItemsStatusIcon').should('have.text', 'add');
|
||||
cy.dataCy('photoUploadSubmitBtn').click();
|
||||
cy.dataCy('photoUploaderItemsStatusIcon').should(
|
||||
'have.text',
|
||||
'cloud_done'
|
||||
);
|
||||
});
|
||||
|
||||
it('should clear all files when clear button is clicked', () => {
|
||||
uploadFile('src/test/cypress/fixtures/lowres.jpg');
|
||||
cy.dataCy('photoUploaderItem').should('exist');
|
||||
cy.dataCy('photoUploaderClearBtn').click();
|
||||
cy.dataCy('photoUploaderItem').should('not.exist');
|
||||
});
|
||||
|
||||
it('should display error notification if an upload fails', () => {
|
||||
uploadFile('src/test/cypress/fixtures/low-res.jpg');
|
||||
cy.dataCy('photoUploadSubmitBtn').click();
|
||||
cy.checkNotify(
|
||||
'negative',
|
||||
'Ocurrieron errores al subir alguna de las imágenes'
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
Cypress.Commands.add('userViewSupplant', user => {
|
||||
cy.dataCy('usersViewSearchBar').should('exist');
|
||||
cy.dataCy('usersViewSearchBar').find('input').type(`${user}{enter}`);
|
||||
cy.dataCy('layoutSupplantedUserName').should('not.exist');
|
||||
cy.dataCy('usersViewList').should('not.contain', 'Sin datos');
|
||||
cy.dataCy('userViewCard').should('exist');
|
||||
cy.dataCy('usersViewSupplantUserBtn').click();
|
||||
cy.dataCy('layoutSupplantedUserName').should('exist');
|
||||
cy.dataCy('layoutSupplantedUserName').should('contain', user);
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
describe('UsersView', () => {
|
||||
before(() => {
|
||||
cy.resetDB();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login('adminboss');
|
||||
cy.visit('/#/admin/users');
|
||||
});
|
||||
|
||||
it('should show empty state when entering the view', () => {
|
||||
cy.dataCy('usersViewList').should('contain', 'Sin datos');
|
||||
});
|
||||
|
||||
it('supplants user', () => {
|
||||
cy.userViewSupplant('Bruce Wayne');
|
||||
cy.getSessionStorage('supplantUser').should('equal', 'brucewayne');
|
||||
});
|
||||
|
||||
it('makes actions for the supplanted user', () => {
|
||||
cy.userViewSupplant('Bruce Wayne');
|
||||
cy.wait(100);
|
||||
cy.visit('/#/account/conf');
|
||||
cy.url().should('contain', '/#/account/conf');
|
||||
cy.changeUserNickname('Bruce Wayne', 'New test nickname');
|
||||
cy.dataCy('layoutSupplantedUserName').should(
|
||||
'contain',
|
||||
'New test nickname'
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
Cypress.Commands.add('addItemToBasketFlow', () => {
|
||||
// 1- Seleccionar categoría
|
||||
cy.dataCy('catalogCategoryButton').should('exist');
|
||||
cy.get('[data-testid="catalogCategoryButton"]:first').click();
|
||||
// 2- Seleccionar familia
|
||||
cy.dataCy('catalogFamilySelect').should('exist');
|
||||
cy.selectOption('[data-testid="catalogFamilySelect"]', 'Anthurium');
|
||||
cy.getValue('[data-testid="catalogFamilySelect"]').should(
|
||||
'equal',
|
||||
'Anthurium'
|
||||
);
|
||||
cy.dataCy('catalogFamilySelect').should('exist');
|
||||
// 3- Seleccionar item
|
||||
cy.dataCy('catalogCardGridBody').should('exist');
|
||||
cy.get('[data-testid="catalogCardGridBody"]:first').click();
|
||||
// 4- Añadir item al carrito
|
||||
cy.dataCy('addItemQuantityButton').should('exist');
|
||||
cy.get('[data-testid="addItemQuantityButton"]:first').click();
|
||||
cy.dataCy('catalogAddToBasketButton').should('exist');
|
||||
cy.dataCy('catalogAddToBasketButton').click();
|
||||
cy.checkNotify('positive', 'Añadido');
|
||||
jsegarra
commented
Esta podría ser candidata a irse a un comando global Esta podría ser candidata a irse a un comando global
wbuezas
commented
Command de notify creado y aplicado. Commit: Command de notify creado y aplicado.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/a142ceb1514c08ce169d0841e926f26d1c6b65f0
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
describe('CatalogView', () => {
|
||||
before(() => {
|
||||
cy.resetDB();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login('developer');
|
||||
});
|
||||
|
||||
it('if there is no pending order created and we go to catalog, it should return checkout view', () => {
|
||||
cy.visit('/#/ecomerce/pending');
|
||||
// Comprobamos que no existe ninguna orden pendiente
|
||||
cy.dataCy('pendingOrdersList').should('contain', 'Lista vacía');
|
||||
// Visitamos el catalogo
|
||||
cy.visit('/#/ecomerce/catalog');
|
||||
// Debería redirigirnos al checkout
|
||||
cy.url().should('contain', '/#/ecomerce/checkout');
|
||||
});
|
||||
|
||||
it('if there is a pending order created and we somehow remove order from basket it should return pending orders view', () => {
|
||||
cy.createOrderReceiveFlow();
|
||||
// Una manera de perder la información de la orden es deslogueando
|
||||
cy.logoutFlow();
|
||||
// Volvemos a loguear con el mismo usuario
|
||||
cy.loginFlow('developer');
|
||||
// Visitamos catalog
|
||||
cy.visit('/#/ecomerce/catalog');
|
||||
// Debería redirigirnos a pending orders con un mensaje de advertencia
|
||||
cy.url().should('contain', '/#/ecomerce/pending');
|
||||
cy.checkNotify(
|
||||
'warning',
|
||||
'Por favor carga un pedido pendiente en la cesta o empieza uno nuevo'
|
||||
);
|
||||
});
|
||||
|
||||
it('Adds item to basket and goes to basket', () => {
|
||||
cy.resetDB();
|
||||
cy.login('developer');
|
||||
cy.createOrderReceiveFlow();
|
||||
cy.addItemToBasketFlow();
|
||||
cy.dataCy('catalogGoToBasketButton').should('exist');
|
||||
cy.dataCy('catalogGoToBasketButton').click();
|
||||
cy.url().should('contain', '/#/ecomerce/basket');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,85 @@
|
|||
const checkoutNextStep = () => {
|
||||
cy.dataCy('checkoutStepperRightButton').should('be.visible').click();
|
||||
};
|
||||
|
||||
Cypress.Commands.add('createOrderReceive', () => {
|
||||
cy.dataCy('checkoutStepper').should('exist');
|
||||
cy.dataCy('checkoutStepper').should(
|
||||
'contain',
|
||||
'¿Quieres recibir o recoger el pedido?'
|
||||
);
|
||||
cy.dataCy('Recibir en mi tienda', 'aria-label').click();
|
||||
|
||||
checkoutNextStep();
|
||||
cy.dataCy('checkoutStepper').should(
|
||||
'contain',
|
||||
'¿Qué día quieres recibir el pedido?'
|
||||
);
|
||||
checkoutNextStep();
|
||||
cy.dataCy('checkoutStepper').should(
|
||||
'contain',
|
||||
'¿Dónde quieres recibir el pedido?'
|
||||
);
|
||||
cy.dataCy('checkoutAddressStep').within(() => {
|
||||
cy.get('label:first').click();
|
||||
});
|
||||
checkoutNextStep();
|
||||
cy.dataCy('checkoutStepper').should(
|
||||
'contain',
|
||||
'¿Cómo quieres recibir el pedido?'
|
||||
);
|
||||
cy.dataCy('agencyStepSelect').should('exist');
|
||||
cy.selectOption('[data-testid="agencyStepSelect"]', 'Other agency');
|
||||
checkoutNextStep();
|
||||
checkoutNextStep();
|
||||
cy.url().should('contain', '/#/ecomerce/catalog');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('createOrderReceiveFlow', () => {
|
||||
cy.visit('/#/ecomerce/pending');
|
||||
cy.dataCy('pendingOrdersNewOrder').should('exist');
|
||||
cy.dataCy('pendingOrdersNewOrder').click();
|
||||
cy.createOrderReceive();
|
||||
cy.checkNotify('positive', '¡Pedido cargado en la cesta!');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('createOrderPickup', () => {
|
||||
cy.dataCy('checkoutStepper').should('exist');
|
||||
cy.dataCy('checkoutStepper').should(
|
||||
'contain',
|
||||
'¿Quieres recibir o recoger el pedido?'
|
||||
);
|
||||
cy.dataCy('Recoger en almacén', 'aria-label').click();
|
||||
checkoutNextStep();
|
||||
cy.dataCy('checkoutStepper').should(
|
||||
'contain',
|
||||
'¿Qué día quieres recibir el pedido?'
|
||||
);
|
||||
checkoutNextStep();
|
||||
cy.dataCy('checkoutStepper').should(
|
||||
'contain',
|
||||
'¿A qué dirección quieres asociar el pedido? (Opcional)'
|
||||
);
|
||||
cy.dataCy('checkoutAddressStep').within(() => {
|
||||
cy.get('label:first').click();
|
||||
});
|
||||
checkoutNextStep();
|
||||
cy.dataCy('checkoutStepper').should(
|
||||
'contain',
|
||||
'¿En qué almacén quieres recoger tu pedido?'
|
||||
);
|
||||
cy.dataCy('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.dataCy('pendingOrdersNewOrder').should('exist');
|
||||
cy.dataCy('pendingOrdersNewOrder').click();
|
||||
cy.createOrderPickup();
|
||||
cy.checkNotify('positive', '¡Pedido cargado en la cesta!');
|
||||
});
|
|
@ -0,0 +1,24 @@
|
|||
describe('CheckoutStepper', () => {
|
||||
before(() => {
|
||||
cy.resetDB();
|
||||
});
|
||||
|
||||
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.dataCy('orderModifyButton').click();
|
||||
cy.checkNotify(
|
||||
'warning',
|
||||
'Recuerda que si vuelves a configurar el pedido los precios o cantidades de tus artículos podrían cambiar'
|
||||
);
|
||||
cy.createOrderPickup(false);
|
||||
cy.checkNotify('positive', 'Pedido actualizado');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
Cypress.Commands.add('changeUserNickname', (oldNickname, newNickname) => {
|
||||
cy.dataCy('configViewNickname').find('input').should('exist');
|
||||
|
||||
cy.getValue('input[data-testid="configViewNickname"]').should(
|
||||
'equal',
|
||||
oldNickname
|
||||
);
|
||||
cy.dataCy('configViewNickname').find('input').clear();
|
||||
cy.dataCy('configViewNickname').find('input').type(newNickname);
|
||||
cy.dataCy('configViewNickname').find('input').blur();
|
||||
cy.checkNotify('positive', 'Datos guardados');
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
describe('Changes user nickname', () => {
|
||||
beforeEach(() => {
|
||||
cy.login('brucewayne');
|
||||
cy.visit('/#/account/conf');
|
||||
});
|
||||
|
||||
it('success', () => {
|
||||
cy.changeUserNickname('Bruce Wayne', 'New test nickname');
|
||||
cy.resetDB();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,80 @@
|
|||
describe('PendingOrders', () => {
|
||||
beforeEach(() => {
|
||||
cy.login('developer');
|
||||
cy.visit('/#/account/address-list');
|
||||
});
|
||||
|
||||
const getRandomAddressFormData = () => {
|
||||
const randomString = () => Math.random().toString(36).substring(2, 15);
|
||||
return {
|
||||
nickname: `Nickname-${randomString()}`,
|
||||
street: `Street-${randomString()}`,
|
||||
city: `City-${randomString()}`,
|
||||
postcode: Math.floor(Math.random() * 90000) + 10000
|
||||
};
|
||||
};
|
||||
|
||||
const fillFormWithData = data => {
|
||||
cy.dataCy('addressFormNickname').find('input').click();
|
||||
cy.dataCy('addressFormNickname').find('input').type(data.nickname);
|
||||
cy.dataCy('addressFormStreet').find('input').click();
|
||||
cy.dataCy('addressFormStreet').find('input').type(data.street);
|
||||
cy.dataCy('addressFormCity').find('input').click();
|
||||
cy.dataCy('addressFormCity').find('input').type(data.city);
|
||||
cy.dataCy('addressFormPostcode').find('input').click();
|
||||
cy.dataCy('addressFormPostcode').find('input').type(data.postcode);
|
||||
cy.selectOption('[data-testid="addressFormCountry"]', 'España');
|
||||
cy.selectOption('[data-testid="addressFormProvince"]', 'Province one');
|
||||
};
|
||||
|
||||
const verifyAddressCardData = data => {
|
||||
cy.dataCy('addressCardList')
|
||||
.children()
|
||||
.last()
|
||||
.should('contain', data.nickname);
|
||||
cy.dataCy('addressCardList')
|
||||
.children()
|
||||
.last()
|
||||
.should('contain', data.street);
|
||||
cy.dataCy('addressCardList')
|
||||
.children()
|
||||
.last()
|
||||
.should('contain', data.city);
|
||||
cy.dataCy('addressCardList')
|
||||
.children()
|
||||
.last()
|
||||
.should('contain', data.postcode);
|
||||
};
|
||||
|
||||
it('should create a new address', () => {
|
||||
cy.dataCy('newAddressBtn').should('exist');
|
||||
cy.dataCy('newAddressBtn').click();
|
||||
cy.dataCy('formDefaultSaveButton').should('exist');
|
||||
cy.dataCy('formDefaultSaveButton').should('be.disabled');
|
||||
const addressFormData = getRandomAddressFormData();
|
||||
fillFormWithData(addressFormData);
|
||||
cy.dataCy('formDefaultSaveButton').should('not.be.disabled');
|
||||
cy.dataCy('formDefaultSaveButton').click();
|
||||
cy.checkNotify('positive', 'Datos guardados');
|
||||
verifyAddressCardData(addressFormData);
|
||||
});
|
||||
|
||||
it('should edit an existent address', () => {
|
||||
cy.dataCy('addressCardList')
|
||||
.children()
|
||||
.last()
|
||||
.find('[data-testid="editAddressBtn"]')
|
||||
.click();
|
||||
// Clear form data
|
||||
cy.get('form input').each(input => {
|
||||
cy.wrap(input).clear(); // Limpia el valor de cada campo de entrada
|
||||
});
|
||||
// Fill form with new data
|
||||
const addressFormData = getRandomAddressFormData();
|
||||
fillFormWithData(addressFormData);
|
||||
cy.dataCy('formDefaultSaveButton').should('not.be.disabled');
|
||||
cy.dataCy('formDefaultSaveButton').click();
|
||||
cy.checkNotify('positive', 'Datos guardados');
|
||||
verifyAddressCardData(addressFormData);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,70 @@
|
|||
// Login view commands
|
||||
Cypress.Commands.add('login', user => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/Accounts/login',
|
||||
body: {
|
||||
user,
|
||||
password: 'nightmare'
|
||||
}
|
||||
}).then(response => {
|
||||
window.sessionStorage.setItem('token', response.body.token);
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: '/api/VnUsers/ShareToken',
|
||||
headers: {
|
||||
Authorization: window.sessionStorage.getItem('token')
|
||||
}
|
||||
}).then(({ body }) => {
|
||||
window.sessionStorage.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.dataCy('loginUserInput').type(user);
|
||||
cy.getValue('[data-testid="loginUserInput"]').should('equal', user);
|
||||
cy.dataCy('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('changeLanguage', language => {
|
||||
const languagesOrder = ['en', 'es', 'ca', 'fr', 'pt'];
|
||||
const index = languagesOrder.indexOf(language);
|
||||
cy.waitForElement('[data-testid="switchLanguage"]');
|
||||
cy.dataCy('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);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('logoutFlow', language => {
|
||||
cy.dataCy('logoutButton').should('exist');
|
||||
cy.dataCy('logoutButton').click();
|
||||
});
|
|
@ -0,0 +1,100 @@
|
|||
describe('Login Tests', () => {
|
||||
const rememberCheckbox = '[data-testid="rememberCheckbox"]';
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/#/login');
|
||||
});
|
||||
|
||||
it('should toggle password visibility', () => {
|
||||
cy.dataCy('showPasswordIcon').should('exist');
|
||||
cy.dataCy('showPasswordIcon').click();
|
||||
cy.dataCy('showPasswordIcon').should('have.text', 'visibility_off');
|
||||
cy.dataCy('showPasswordIcon').click();
|
||||
cy.dataCy('showPasswordIcon').should('have.text', 'visibility');
|
||||
});
|
||||
|
||||
it('should select a language from the dropdown', () => {
|
||||
cy.dataCy('switchLanguage').should('exist');
|
||||
cy.changeLanguage('en');
|
||||
cy.get('button[type="submit"]').should('contain', 'Log in');
|
||||
cy.changeLanguage('es');
|
||||
cy.get('button[type="submit"]').should('contain', 'Iniciar sesión');
|
||||
});
|
||||
|
||||
it('should fail to log in using wrong user', () => {
|
||||
cy.dataCy('loginUserInput').type('incorrectUser');
|
||||
cy.dataCy('loginPasswordInput').type('nightmare');
|
||||
cy.get('button[type="submit"]').click();
|
||||
cy.checkNotify('negative', 'login failed');
|
||||
});
|
||||
|
||||
it('should fail to log in using wrong password', () => {
|
||||
cy.dataCy('loginUserInput').type('incorrectUser');
|
||||
cy.dataCy('loginPasswordInput').type('nightmare');
|
||||
cy.get('button[type="submit"]').click();
|
||||
cy.checkNotify('negative', 'login failed');
|
||||
});
|
||||
|
||||
it('should log in', () => {
|
||||
cy.loginFlow('employee');
|
||||
});
|
||||
|
||||
it('should log in as guest', () => {
|
||||
cy.dataCy('loginAsGuestButton').should('exist');
|
||||
cy.dataCy('loginAsGuestButton').click();
|
||||
cy.url().should('contain', '/#/cms/home');
|
||||
});
|
||||
|
||||
it('should save localStorage keepLogin true value if remember checkbox is checked', () => {
|
||||
cy.dataCy('rememberCheckbox').should('exist');
|
||||
cy.dataCy('rememberCheckbox').click();
|
||||
cy.getValue(rememberCheckbox).should('equal', 'true');
|
||||
cy.loginFlow('employee', false);
|
||||
cy.window().then(window => {
|
||||
expect(window.localStorage.getItem('keepLogin')).to.eq('true');
|
||||
});
|
||||
});
|
||||
|
||||
it('should save localStorage keepLogin false value if remember checkbox is not checked', () => {
|
||||
cy.dataCy('rememberCheckbox').should('exist');
|
||||
cy.getValue(rememberCheckbox).should('equal', 'false');
|
||||
cy.loginFlow('employee', false);
|
||||
cy.window().then(window => {
|
||||
expect(window.localStorage.getItem('keepLogin')).to.eq('false');
|
||||
});
|
||||
});
|
||||
|
||||
it('saves data in session storage if remember is not checked', () => {
|
||||
cy.dataCy('rememberCheckbox').should('exist');
|
||||
cy.getValue(rememberCheckbox).should('equal', 'false');
|
||||
cy.loginFlow('employee', false);
|
||||
cy.window().then(window => {
|
||||
expect(window.sessionStorage.getItem('hederaLastUser')).to.eq(
|
||||
'employee'
|
||||
);
|
||||
expect(window.localStorage.getItem('hederaLastUser')).to.eq(null);
|
||||
});
|
||||
});
|
||||
|
||||
it('saves data in local storage if remember is checked', () => {
|
||||
cy.dataCy('rememberCheckbox').should('exist');
|
||||
cy.dataCy('rememberCheckbox').click();
|
||||
cy.getValue(rememberCheckbox).should('equal', 'true');
|
||||
cy.loginFlow('employee', false);
|
||||
cy.window().then(window => {
|
||||
expect(window.localStorage.getItem('hederaLastUser')).to.eq(
|
||||
'employee'
|
||||
);
|
||||
expect(window.sessionStorage.getItem('hederaLastUser')).to.eq(null);
|
||||
});
|
||||
});
|
||||
|
||||
it('should redirect to login if storage token is removed', () => {
|
||||
cy.loginFlow('employee', false);
|
||||
cy.window().then(window => {
|
||||
window.sessionStorage.removeItem('token');
|
||||
cy.visit('/#/account/conf');
|
||||
cy.url().should('contain', '/#/login');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
describe('PendingOrders', () => {
|
||||
beforeEach(() => {
|
||||
cy.login('brucewayne');
|
||||
cy.visit('/#/ecomerce/orders');
|
||||
});
|
||||
|
||||
const makePayment = typeAmount => {
|
||||
cy.dataCy('makePaymentButton').should('exist');
|
||||
cy.dataCy('makePaymentButton').click();
|
||||
cy.dataCy('payAmountDialog').should('exist');
|
||||
cy.dataCy('payAmountInput').find('input').should('exist');
|
||||
cy.dataCy('payAmountInput').find('input').clear();
|
||||
if (typeAmount || typeAmount === 0)
|
||||
cy.dataCy('payAmountInput').find('input').type(typeAmount);
|
||||
cy.setConfirmDialog();
|
||||
jsegarra
commented
Estas 2 podrian ser candidatas a irse a un comando global Estas 2 podrian ser candidatas a irse a un comando global
wbuezas
commented
Coincido, aplicado. Commit: Coincido, aplicado.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/e4bc14ef3b7b8eb5f4951088c9b077a8b022363f
|
||||
};
|
||||
|
||||
// it('confirm payment redirects to payment site', () => {
|
||||
// makePayment('100');
|
||||
// TODO: Ver como hacer para verificar redirección a sitio externo
|
||||
// });
|
||||
|
||||
it('fails payment if pay amount is 0', () => {
|
||||
cy.visit('/#/ecomerce/orders');
|
||||
makePayment(0);
|
||||
cy.checkNotify(
|
||||
'negative',
|
||||
'La cantidad debe ser un número positivo e inferior o igual al importe pendiente'
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,55 @@
|
|||
describe('PendingOrders', () => {
|
||||
before(() => {
|
||||
// Esto se ejecuta una vez antes de todas las pruebas
|
||||
cy.resetDB();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login('developer');
|
||||
});
|
||||
|
||||
const checkEmptyList = () => {
|
||||
cy.dataCy('pendingOrdersList').should('exist');
|
||||
cy.dataCy('pendingOrdersList').should('contain', 'Lista vacía');
|
||||
cy.dataCy('pendingOrderCard').should('not.exist');
|
||||
};
|
||||
|
||||
const checkExistingOrder = () => {
|
||||
cy.dataCy('pendingOrdersList').should('exist');
|
||||
cy.dataCy('pendingOrdersList').should('not.contain', 'Lista vacía');
|
||||
cy.dataCy('pendingOrderCard').should('exist');
|
||||
};
|
||||
|
||||
it('shows empty state', () => {
|
||||
// Cuando la db se reinicia el usuario developer no tiene ordenes pendientes
|
||||
cy.visit('/#/ecomerce/pending');
|
||||
checkEmptyList();
|
||||
});
|
||||
|
||||
it('creates a new order', () => {
|
||||
cy.createOrderReceiveFlow();
|
||||
cy.visit('/#/ecomerce/pending');
|
||||
checkExistingOrder();
|
||||
cy.dataCy('pendingOrderCard').should('have.length', 1);
|
||||
cy.resetDB();
|
||||
});
|
||||
|
||||
it('deletes an order', () => {
|
||||
cy.createOrderReceiveFlow();
|
||||
cy.visit('/#/ecomerce/pending');
|
||||
checkExistingOrder();
|
||||
cy.dataCy('pendingOrderCard').should('have.length', 1);
|
||||
cy.dataCy('pendingOrderCardDelete').click();
|
||||
cy.setConfirmDialog();
|
||||
cy.checkNotify('positive', 'Datos guardados');
|
||||
checkEmptyList();
|
||||
});
|
||||
|
||||
it('adds order to basket', () => {
|
||||
cy.createOrderReceiveFlow();
|
||||
cy.visit('/#/ecomerce/pending');
|
||||
cy.dataCy('addOrderToBasket').should('exist');
|
||||
cy.dataCy('addOrderToBasket').click();
|
||||
cy.checkNotify('positive', '¡Pedido cargado en la cesta!');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,93 @@
|
|||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
|
||||
// Importar dinámicamente todos los archivos con el sufijo .commands.js dentro de la carpeta src/test/cypress/integration
|
||||
const requireCommands = require.context(
|
||||
'../integration',
|
||||
true,
|
||||
/\.commands\.js$/
|
||||
);
|
||||
// Iterar sobre cada archivo y requerirlo
|
||||
requireCommands.keys().forEach(requireCommands);
|
||||
|
||||
// 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');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('waitForElement', (element, timeout = 5000) => {
|
||||
cy.get(element, { timeout }).should('be.visible');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('dataCy', (dataTestId, attr = 'data-testid') => {
|
||||
return cy.get(`[${attr}="${dataTestId}"]`);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('getSessionStorage', key => {
|
||||
cy.window().then(window => window.sessionStorage.getItem(key));
|
||||
});
|
||||
|
||||
Cypress.Commands.add('getLocalStorage', key => {
|
||||
cy.window().then(window => window.localStorage.getItem(key));
|
||||
});
|
||||
|
||||
Cypress.Commands.add('setLocalStorage', (key, value) => {
|
||||
cy.window().then(window => {
|
||||
window.localStorage.setItem(key, value);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('setSessionStorage', (key, value) => {
|
||||
cy.window().then(window => {
|
||||
window.sessionStorage.setItem(key, value);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('resetDB', () => {
|
||||
cy.exec('npm run resetDatabase');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('setConfirmDialog', () => {
|
||||
cy.dataCy('confirmDialogButton').should('exist');
|
||||
cy.dataCy('confirmDialogButton').click();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('checkNotify', (status, content) => {
|
||||
cy.dataCy(`${status}Notify`).should('contain', content);
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
// ***********************************************************
|
||||
// This example support/e2e.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
|
@ -0,0 +1,24 @@
|
|||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your e2e test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
import './commands';
|
||||
|
||||
/* eslint-disable */
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// returning false here prevents Cypress from
|
||||
// failing the test
|
||||
return false;
|
||||
});
|
||||
/* eslint-enable */
|
no entiendo la diferencia entre hedera-web y hedera-web-mindshore
Que uno luego del
gulp docker
va al proyecto dehedera-web
y el otro al proyectohedera-web-mindshore
(fork), eso luego pueden eliminarlo, lo uso para poder desarrollar en el fork