first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
import * as wpj from '../support/wpj';
import * as gtm from '../support/gtm';
describe('Průchod košíkem s vybráním dopravy Balíkovny', () => {
afterEach(() => {
gtm.checkUserInfoPosition();
});
it('Přidej produkt do košíku', () => {
wpj.addProductToCart();
});
it('Přejdi do košíku', () => {
wpj.stepIntoCart();
gtm.dataLayerContainsEvent('begin_checkout');
cy.matchImageSnapshot('Košík');
});
it('Výběr Balikovny', () => {
cy.get('.delivery-item-balikovna .custom-control-input').then(($radio) => {
if (!$radio.is(':checked')) {
cy.get('.delivery-item-balikovna > .custom-radio').click();
} else {
cy.get('[data-btn="open-balikovna-widget"]').click();
}
});
cy.getIframeBody('iframe[data-src*="BALIKOVNY"]')
.find('.Suggest-input')
.should('exist')
.type('54301{enter}');
cy.wait(5000);
cy.getIframeBody('iframe[data-src*="BALIKOVNY"]')
.find('.Suggest-resultButton')
.first()
.click();
cy.wait(5000);
cy.getIframeBody('iframe[data-src*="BALIKOVNY"]')
.find('.PointRow', { timeout: 10000 })
.contains('Krkonošská 164', { timeout: 10000 })
.click();
cy.getIframeBody('iframe[data-src*="BALIKOVNY"]').find('.PointDetail-btnPrimary').click();
});
it('Doprava se vybrala správně', () => {
cy.get('.delivery-item-balikovna').should('have.class', 'selected');
cy.get('.delivery-class-info').contains('Vrchlabí SAZKA Tabák Krkonošská 164');
cy.get('.delivery-class-info').contains('Krkonošská 164, 54301, Vrchlabí');
cy.wait(1000);
gtm.dataLayerContainsEvent('add_shipping_info');
cy.matchImageSnapshot('Košík s vybranou dopravou Balikovna');
});
it('Výběr dobírky', () => {
cy.get('.payment-item-dobirka').first().click().should('have.class', 'selected');
gtm.dataLayerContainsEvent('add_payment_info');
cy.matchImageSnapshot('Košík s dobírkou');
});
it('Kontrola ceny', () => {
cy.get('.price-box .price-box-row:first-child > :nth-child(2)').contains('149 Kč');
cy.get('.price-box .price-box-row:nth-child(2) > :nth-child(2)').contains('134 Kč');
cy.get('.price-box .price-box-row:nth-child(3) > :nth-child(2)').contains('233,88 Kč');
cy.get('.price-box .total-price > :nth-child(2)').contains('283 Kč');
});
it('Proklik na vyplnění údajů', () => {
cy.get('.cart-nextstep-wrapper > .btn').click({ force: true });
cy.wait(1500);
wpj.fillCustomerDeliveryInfo();
gtm.dataLayerContainsEvent('add_contact_details');
cy.matchImageSnapshot('Košík s vyplněnými údaji pro doručení');
});
it('Dokončení nákupního procesu', () => {
cy.get('.cart-nextstep-wrapper > .btn').click();
cy.get('.page-ordersuccess').contains('úspěšně přijali');
gtm.dataLayerContainsEvent('purchase');
gtm.dataLayerEventEcommerceContainsKey('purchase', 'transaction_id');
gtm.dataLayerEventContainsEcommerceItem('purchase', {
...gtm.getCelenkaEcommerceItem(),
category_current: [],
quantity: 1,
});
cy.matchImageSnapshot('Odeslaná objednávka');
});
});

View File

@@ -0,0 +1,39 @@
import * as wpj from '../support/wpj';
describe('Průchod košíkem Osobní odběr', () => {
it('Vejdi do detailu produktu', () => {
wpj.visitProductDetail();
});
it('Zobrazení dostupnosti - kdy zboží dostanu', () => {
cy.get('.c-product-deliverytime button').first().click({ force: true }).wait(1000);
cy.get('.c-modal .close').first().click({ force: true });
});
it('Zvýšit počet na 2 kusy', () => {
cy.get('.c-product-buycount .plus_unit').first().click();
cy.get('.c-product-buycount .form-control').should('have.value', '2');
});
it('Přidat do košíku a kontrola že se zvětšila cena na 298', () => {
cy.get('.btn.c-product-addtocartbutton').first().click();
cy.get('.price-total strong').contains('298');
});
it('Přejít do košíku', () => {
wpj.stepIntoCart();
});
it('Výběr Osobní odběr a platba hotovosti', () => {
cy.get('.delivery-item-osobniodber > .custom-radio').click();
cy.get('.payment-item-hotovost').first().click();
});
it('Pokračovat na vyplnění údajů', () => {
cy.get('.cart-nextstep-wrapper > .btn').click({ force: true });
wpj.fillCustomerInfo();
});
it('Dokončit objednávku', () => {
cy.get('.cart-nextstep-wrapper > .btn').click();
cy.get('.page-ordersuccess').contains('úspěšně přijali');
});
it('Kontrola funkčnosti odkazu na detail objednávky', () => {
cy.get('.page-ordersuccess').contains('Detail objednávky').click({ force: true });
cy.url().should('include', '/objednavka/');
});
});

View File

@@ -0,0 +1,33 @@
import * as wpj from '../support/wpj';
describe('Průchod košíkem s vybráním dopravy Zasilkovna', () => {
// it('Přidej produkt do košíku a vyber Zasilkovna dopravu', () => {
// wpj.addProductToCart();
// wpj.stepIntoCart();
// cy.get('.delivery-item-zasilkovna > .custom-radio').click();
// cy.get('.deliveries-box', {
// timeout: 2000,
// }).should('be.visible');
// cy.url().should('include', 'doprava-platba');
// });
// it('Vyber Zasilkovny', () => {
// cy.get('.delivery-item-zasilkovna> .custom-radio').click({ force: true });
// cy.getIframeBody('#packeta-widget')
// .find('.custom-autocomplete input')
// .type('Vrchlabí{enter}');
// cy.getIframeBody('#packeta-widget')
// .find('custom-autocomplete__list li.point', { timeout: 3000 })
// .first()
// .click();
// cy.getIframeBody('#packeta-widget').find('#btn_select_branch').click();
// });
// it('Proklik na vyplnění údajů', () => {
// cy.get('.cart-nextstep-wrapper > .btn', { timeout: 10000 }).click({ force: true });
// cy.url().should('include', '/kosik/udaje/');
// wpj.fillCustomerDeliveryInfo();
// });
// it('Dokončení nákupního procesu', () => {
// cy.get('.cart-nextstep-wrapper > .btn').click();
// cy.get('.cart-success-message').contains('úspěšně přijata');
// });
});

View File

@@ -0,0 +1,68 @@
import * as wpj from '../support/wpj';
describe('Výběr filtrů', () => {
it('Přechod do filtrovatelné sekce', () => {
cy.visit('/');
cy.get('.c-header-sections ul li a').contains('Káva').click();
cy.url().should('contain', '/kava_k451/');
cy.matchImageSnapshot('Sekce Káva{id=451}');
});
it('Kontrola výchozího počtu produktů', () => {
cy.get('.filter-total').should('contain', 6);
});
it('Kliknuti na filtr vyrobci', () => {
cy.get('.filter-top-horizontal > .filter-item:not(.filter-item-more)').last().click();
});
it('Vybrani vyrobce Beansmith\'s', () => {
cy.get('[for="mc-beansmith\'s-124"]').click();
cy.get('.reset-item').contains('Beansmith\'s');
cy.url().should('include', 'dynamic_filter%5BproducerIds%5D%5B0%5D=124');
cy.get('.filter-total').should('contain', 2);
cy.matchImageSnapshot('Sekce Káva filtrováno podle výrobce Beansmith\'s');
});
it('Vyber dalsiho filtru vyrobce Nordbeans', () => {
cy.get('[for="mc-nordbeans-125"]').click();
cy.get('.reset-item').contains('Nordbeans');
cy.url().should('include', 'dynamic_filter%5BproducerIds%5D%5B1%5D=125');
cy.get('.filter-total').should('contain', 6);
cy.matchImageSnapshot('Sekce Káva filtrováno podle výrobců Rafiki a wpj');
});
it('Reset filtru', () => {
cy.get('.reset-all').click();
cy.url().should('not.include', 'producerIds');
});
it('Výběr řazení "Nejlevnější"', () => {
cy.get('[name="order"]').select('Nejlevnější');
cy.url().should('include', 'order=price');
cy.matchImageSnapshot('Sekce Káva řazeno podle nejlevnějších produktů');
});
it('Výběr prvního produktu v aktivním filtru', () => {
wpj.getNthProduct(0).find('.product-link').first().click();
cy.get('.c-breadcrumbs .active').contains('Hacienda Sonora, 250g');
});
it('Výběr filtru "Nejdražší"', () => {
cy.get('.c-breadcrumbs li:nth-child(2) > a').click();
cy.get('.c-breadcrumbs .active').contains('Káva');
cy.get('[name="order"]').select('Nejdražší');
cy.url().should('include', 'order');
cy.matchImageSnapshot('Sekce Káva řazeno podle nejdražších produktů');
});
it('Výběr prvního produktu v aktivním filtru', () => {
wpj.getNthProduct(0).find('.product-link').first().click();
cy.get('.c-breadcrumbs .active').contains('Předplatné Espresso 1000g');
});
});

View File

@@ -0,0 +1,16 @@
import * as wpj from '../support/wpj';
describe('Výběr prvního produktu', () => {
it('Proklik na první sekci - Capsle', () => {
cy.visit('/');
cy.get('.c-header-sections ul li a').first().click();
cy.get('.c-breadcrumbs .active').contains('Capsle');
cy.url().should('contain', '/capsle_k436/');
});
it('Výběr prvního produktu', () => {
cy.get('.c-section-products > div .product-link').first().click();
cy.url().should('contain', '/darkovy-poukaz-capsle-1000-kc_z6263/');
cy.get('.c-breadcrumbs .active').first().contains('Dárkový poukaz Capsle 1000 Kč');
});
});

View File

@@ -0,0 +1,27 @@
import * as wpj from '../support/wpj';
describe('Zobrazení obrázku v produktu', () => {
it('Proklik na detail produktu + Kliknuti na obrazek', () => {
cy.visit('/');
cy.get('.c-header-sections [href*="typy-produktu"]').click();
wpj.getNthProduct(0).find('.product-link').first().click();
cy.get('.main-photo a').click();
cy.wait(3000);
});
it('Zavreni obrazku', () => {
cy.get('.pswp__button--close').click();
});
it('Proklik mezi obrazku u produktu', () => {
cy.visit('/');
cy.get('.c-header-sections [href*="typy-produktu"]').click();
wpj.getNthProduct(1).find('.product-link').first().click();
cy.get('.c-breadcrumbs .active').contains('Kolekce');
cy.get('.main-photo a').click();
cy.wait(3000);
cy.get('.pswp__button--arrow--next').click();
cy.get('.pswp').type('{esc}');
cy.wait(1000);
});
});

View File

@@ -0,0 +1,44 @@
import * as wpj from '../support/wpj';
describe('Konfigurace multisetu a přidání do košíku', () => {
it('Vejdi na detail multiset produktu', () => {
cy.visit('multiset-konfigurator_z6163/');
});
it('Otevři výběr první části multisetu', () => {
wpj.clickMultisetSelectionButton(1);
});
it('Vyber druhý produkt a variantu M', () => {
wpj.selectMultisetItem(2);
wpj.selectMultisetVariation('M');
});
it('Otevři popisek a galerii', () => {
cy.get('.jsmultisets-opener-title-wrapper').click({ multiple: true });
cy.wait(1000);
// TODO(havlicek): Vymyslet, jak udělat dobrý screenshot bez duplikace multisetu nebo použití viewportu, který je hodně malý
cy.matchImageSnapshot('Multiset s otevřeným popiskem a galerií', { capture: 'viewport' });
});
it('Vlož výběr do setu', () => {
wpj.clickAddToSetButton();
});
it('Otevři výběr druhé části multisetu, vyber variantu XL a vlož do setu', () => {
wpj.clickMultisetSelectionButton(2);
wpj.selectMultisetVariation('M');
wpj.clickAddToSetButton();
});
it('Otevři výběr třetí části multisetu a vlož do setu', () => {
wpj.clickMultisetSelectionButton(3);
wpj.clickAddToSetButton();
});
it('Přidej multiset do košíku', () => {
cy.get('.product-right-side .c-product-addtocartbutton').click();
cy.wait(1000);
cy.get('.cartbox-product').contains('Multiset');
});
});

View File

@@ -0,0 +1,48 @@
import * as gtm from '../support/gtm';
describe('Pruchod sekcemi pres navigaci', () => {
it('Kontrola, ze existuje sekce Typy produktů', () => {
cy.visit('/');
cy.get('.c-header-sections > .container').contains('Typy produktů');
});
it('Proklik do sekce Typy produktů', () => {
cy.get('.c-header-sections [href*="typy-produktu"]').click();
cy.get('.c-breadcrumbs .active').should('contain', 'Typy produktů');
});
it('Proklik do prvniho produktu', () => {
cy.get('.c-section-products .c-productlist-squareitem').contains('Dárkový poukaz 1000 Kč').click();
cy.get('.c-breadcrumbs .active').contains('Dárkový poukaz 1000 Kč');
});
it('Navrat pres navigaci do predchozi sekce', () => {
cy.get('.c-breadcrumbs li:nth-child(2) > a').click();
cy.get(' .c-breadcrumbs .active').should('contain', 'Typy produktů');
});
it('Zopakovat proklik do produktu s produktem Kolekce', () => {
cy.get('.c-section-products .c-productlist-squareitem').contains('Kolekce').click();
cy.get('.c-breadcrumbs .active').should('contain', 'Kolekce');
// cy.matchImageSnapshot();
});
it('Kliknuti na produkt tag, ktery neni stejny jako sekce, ze ktere prijdu', () => {
cy.get('.c-product-sections [href*="wpj_v90"]').click();
cy.get('.c-breadcrumbs .active').should('contain', 'Výrobce wpj');
});
it('Navigace skrz recommender na homepage', () => {
cy.visit('/');
cy.get('.c-editablecontent-recommender').eq(0).scrollIntoView();
cy.wait(1500);
gtm.dataLayerContainsEvent('view_item_list');
gtm.dataLayerEventEcommerceContainsKeyAndValue('view_item_list', 'item_list_name', 'recommender');
gtm.checkDataLayerEventHasCorrectPositionsForEcommerceItems('view_item_list');
cy.get('.c-editablecontent-recommender .c-productlist-squareitem').eq(1).find('.product-link').eq(0).then($link => {
$link.removeAttr('href');
});
cy.get('.c-editablecontent-recommender .c-productlist-squareitem').eq(1).find('.product-link').eq(0).click();
gtm.checkDataLayerEcommerceItemHasCorrectPosition('select_item', 0, 2);
});
});

View File

@@ -0,0 +1,17 @@
import * as wpj from '../support/wpj';
describe('Registrace a prihlaseni uzivatele', () => {
it('Registrace uzivatele', () => {
wpj.register();
cy.visit('/');
});
it('Odhlaseni uzivatele', () => {
wpj.logout();
});
it('Prihlaseni uzivatele', () => {
wpj.login();
// cy.matchImageSnapshot();
});
});

View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -0,0 +1,22 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* @type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}

View File

@@ -0,0 +1,49 @@
// ***********************************************
// 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) => { ... })
declare global {
namespace Cypress {
interface Chainable {
getIframeBody(selector: string): Chainable<JQuery>;
inIframe(selector: string, callback: (chainable: Chainable<JQuery>) => unknown): void;
}
}
}
Cypress.Commands.add('getIframeBody', (selector) => {
return cy
.get(selector, { timeout: 30000 })
.should('be.visible')
.its('0.contentDocument.body', { timeout: 30000 })
.should('not.be.empty');
});
Cypress.Commands.add('inIframe', (selector, callback) => {
return cy.getIframeBody(selector).then(($body) => {
callback(cy.wrap($body));
});
});
export {};

View File

@@ -0,0 +1,29 @@
import { addMatchImageSnapshotCommand } from '@simonsmith/cypress-image-snapshot/command';
import installLogsCollector from 'cypress-terminal-report/src/installLogsCollector';
import 'cypress-fail-fast';
import './commands';
import { acceptAllCookies } from './wpj';
addMatchImageSnapshotCommand({
failureThresholdType: 'percent',
failureThreshold: 0.01,
customDiffDir: 'cypress/snapshot_diffs',
});
Cypress.env('useDetailedLogging') && installLogsCollector();
before(() => {
// preventivně nastavit zemi na CZ, kvůli dopravě
cy.visit('/zeme/CZ');
cy.wait(5000);
acceptAllCookies();
});
// Cypress.on('uncaught:exception', e => {
// // TODO(hauschwitz): asi není nejlepší řešení, ale prozatim dobrý
// if (e.message.toLowerCase().match(/(sentry)|(\$)|(wpj\.onready)/).length > 1) {
// return false;
// }
//
// throw e;
// });

View File

@@ -0,0 +1,148 @@
declare global {
interface Window {
dataLayer: Record<string, any>[];
}
}
function getArrayOfEventsFromDataLayer(dataLayer: Record<string, any>[]) {
return Cypress._.map(dataLayer, (o) => Cypress._.pick(o, 'event'));
}
function getEventFromDataLayer(dataLayer: Record<string, any>[], event: string) {
return Cypress._.find(dataLayer, (o) => o.event === event);
}
export function getCelenkaEcommerceItem() {
return {
item_id: 104,
product_id: 104,
ean: '',
item_code: 'XY264',
product_code: 'XY264',
has_variations: false,
variation_ids: [],
variation_id: null,
variation_code: null,
item_variant: null,
sold_out: null,
variation_codes: [],
category_main: [
{ id: 386, name: 'Oblečení' },
{ id: 388, name: 'Doplňky' },
{ id: 393, name: 'Čepice' },
],
item_brand: 'wpj',
campaigns: [],
item_name: 'Čelenka Mountains black&white',
tax: 21,
price: 149,
price_with_tax: 149,
price_without_tax: 123.14,
price_tax: 25.86,
price_without_discount: 149,
discount: 0,
has_discount: false,
availability: 'skladem',
url: '',
image_url: '',
category_current: [
{ id: 386, name: 'Oblečení' },
{ id: 388, name: 'Doplňky' },
{ id: 393, name: 'Čepice' },
],
quantity: null,
};
}
export function dataLayerContains(target: Record<string, any>) {
expect(window.dataLayer).to.contain(target);
}
export function dataLayerContainsEvent(event: string) {
cy.window()
.then((win) => {
return getArrayOfEventsFromDataLayer(win.dataLayer);
})
.should('deep.include', { event });
}
export function dataLayerContainsEcommerceItem(ecommerceItem: Record<string, any>) {
cy.window().then((win) => {
const itemFound = win.dataLayer.some((layerItem) =>
layerItem.ecommerce?.items.some((item: Record<string, any>) =>
Cypress._.isEqual({
...item,
url: '',
image_url: '',
}, ecommerceItem),
),
);
expect(itemFound, `Item ${JSON.stringify(ecommerceItem)} not found in any ecommerce items array \ndataLayer: ${JSON.stringify(win.dataLayer)}`).to.be.true;
});
}
export function dataLayerEventContainsEcommerceItem(
event: string,
ecommerceItem: Record<string, any>,
) {
cy.window().then((win) => {
const eventObject = getEventFromDataLayer(win.dataLayer, event);
const itemFound = eventObject.ecommerce?.items.some((item: Record<string, any>) => {
return Cypress._.isEqual({
...item,
url: '',
image_url: '',
}, ecommerceItem);
});
expect(itemFound, `Item ${JSON.stringify(ecommerceItem)} not found in ecommerce of ${event} event. \neventObject: ${JSON.stringify(eventObject)}`).to.be.true;
});
}
export function dataLayerEventEcommerceContainsKey(event: string, key: string) {
cy.window().then((win) => {
const eventObject = getEventFromDataLayer(win.dataLayer, event);
expect(Object.prototype.hasOwnProperty.call(eventObject.ecommerce, key), `Event ${event} doesn't have ${key} key. \neventObject: ${JSON.stringify(eventObject)}`).to.be.true;
});
}
export function checkUserInfoPosition() {
cy.window().then((win) => {
const events = Cypress._.filter(
getArrayOfEventsFromDataLayer(win.dataLayer),
(event) => {
return Object.prototype.hasOwnProperty.call(event, 'event') && !event.event.includes('gtm');
},
);
const consentIndex = Cypress._.findIndex(events, { event: 'consent_default' });
const userInfoIndex = Cypress._.findIndex(events, { event: 'user_info' });
// user info je hned po consentu
expect(userInfoIndex).to.be.eq(consentIndex + 1, `User info is in wrong position, \nall events: ${JSON.stringify(events)}`);
});
}
export function dataLayerEventEcommerceContainsKeyAndValue(event: string, key: string, value: string) {
cy.window().then((win) => {
const eventObject = getEventFromDataLayer(win.dataLayer, event);
expect(Object.prototype.hasOwnProperty.call(eventObject.ecommerce, key), `${event} is missing the ${key} property, \neventObject: ${JSON.stringify(eventObject)}`).to.be.true;
expect(eventObject.ecommerce[key]).to.be.eq(value, `${key} in event ${event} does not have expected value ${value}`);
});
}
export function checkDataLayerEventHasCorrectPositionsForEcommerceItems(event: string) {
cy.window().then((win) => {
const eventObject = getEventFromDataLayer(win.dataLayer, event);
expect(eventObject.ecommerce.items[0].position).to.be.eq(1, `Item at position 0 has wrong position value, \neventObject: ${JSON.stringify(eventObject)}`);
expect(eventObject.ecommerce.items[1].position).to.be.eq(2, `Item at position 1 has wrong position value, \neventObject: ${JSON.stringify(eventObject)}`);
});
}
export function checkDataLayerEcommerceItemHasCorrectPosition(event: string, index: number, position: number) {
cy.window().then((win) => {
const eventObject = getEventFromDataLayer(win.dataLayer, event);
expect(eventObject.ecommerce.items[index].position).to.be.eq(position, `Item at index ${index} in event ${event} has wrong position, \neventObject: ${JSON.stringify(eventObject)}`);
});
}

View File

@@ -0,0 +1,204 @@
import { syncFetch } from '../util';
import * as gtm from './gtm';
import Selector = JQuery.Selector;
import Chainable = Cypress.Chainable;
function withPreviousUrl(callback: (url: string) => unknown): void {
cy.url().then((url) => {
callback(url);
if (url.startsWith('about:')) {
url = '/';
}
cy.visit(url);
});
}
export const testUser = {
email: 'cuchac@email.cz',
password: 'wpjwpj123',
name: 'Wpj',
surname: 'Wpj',
phone: '+420728123219',
street: 'Fügnerova 1288',
city: 'Vrchlabí',
zip: '54301',
country: 'CZ',
} as const;
export type LoginOptions = {
[key in keyof typeof testUser]?: (typeof testUser)[key];
};
export function register(): LoginOptions;
export function register(login: LoginOptions): LoginOptions;
export function register(login?: LoginOptions): LoginOptions {
withPreviousUrl(() => {
login = {
...testUser,
...(login ?? {}),
};
cy.visit('/');
acceptAllCookies();
cy.get('.cart-signin').click();
cy.get('.c-userlogin-form [href*=registrace]').first().click();
cy.wait(100); // hack - $ is not defined
for (const [id, value] of Object.entries(login)) {
if (id === 'country') {
continue;
}
cy.get(`#${id}`).type(value, { force: true });
}
cy.get('#country').select(login.country);
cy.get('.registration-submit > .btn').click();
});
return login;
}
export function login(): void;
export function login(email: string, password: string): void;
export function login(email?: string, password?: string): void {
withPreviousUrl(() => {
email ??= testUser.email;
password ??= testUser.password;
cy.visit('/');
cy.get('.cart-signin').click();
cy.get('#type_login').type(email);
cy.get('#type_password').type(password);
cy.get('#type_Submit').click();
});
}
export function logout(): void {
withPreviousUrl(() => {
//Zakomentovat login() z duvodu registration.cy.ts, jelikoz nejprve probehne registrace a uzivatel je jiz prihlasen
// tudiz problem s visit('/prihlaseni')
// login();
cy.visit('/ucet');
cy.get('.item-logout > a').click();
});
}
export function resetSoft() {
cy.clearAllCookies();
cy.clearAllLocalStorage();
cy.clearAllSessionStorage();
}
export function resetHard(opts?: { baseUrl: string }) {
let baseUrl: string;
if (opts) {
baseUrl = opts.baseUrl;
} else {
baseUrl = Cypress.config('baseUrl');
}
const url = new URL('/_cypress/resetHard', baseUrl);
const response = syncFetch(url.href);
// prime web server
syncFetch(baseUrl);
return response;
}
export function getNthProduct(idx: number = 0) {
return cy.get('.c-section-products .c-productlist-squareitem').eq(idx);
}
export function fillCustomerInfo() {
cy.get('.cart-nextstep-wrapper > .btn').click();
cy.get('#iemail ').type(testUser.email);
cy.get('#iname').type(testUser.name);
cy.get('#isurname').type(testUser.surname);
cy.get('#iphone').type(testUser.phone);
}
export function fillCustomerDeliveryInfo() {
cy.get('.cart-nextstep-wrapper > .btn').click();
cy.get('#iemail ').type(testUser.email);
cy.get('#iname').type(testUser.name);
cy.get('#isurname').type(testUser.surname);
cy.get('#iphone').type(testUser.phone);
cy.get('#istreet').type(testUser.street);
cy.get('#icity').type(testUser.city);
cy.get('#izip').type(testUser.zip);
}
export function priceEquals<Subject extends JQuery>(price: number): (fn: Subject) => void {
return function (subject) {
const actualPrice = +subject.text().replace(/\D/, '');
cy.wrap(actualPrice).should('eq', price);
};
}
export function getIframeDocument(selector: Selector): Chainable<JQuery> {
return cy.get(selector).its('0.contentDocument').should('exist');
}
export function getIframeBody(selector: Selector): Chainable<JQuery> {
return getIframeDocument(selector)
.its('body')
.should('not.be.undefined')
.then((body: JQuery) => cy.wrap(body));
}
export function acceptAllCookies() {
cy.get('.cookiebar-btns-simple .btn', { timeout: 10000 }).last().then(
($btn) => {
if ($btn.is(':visible')) {
cy.wrap($btn).click();
}
}
);
}
export function visitProductDetail() {
cy.wait(100);
cy.visit('/celenka-mountains-black-white_z104/');
gtm.dataLayerContainsEvent('page_view');
gtm.dataLayerContainsEvent('view_item');
gtm.dataLayerContainsEcommerceItem(gtm.getCelenkaEcommerceItem());
}
export function addProductToCart() {
visitProductDetail();
cy.get('.c-product-submitblock > .btn.c-product-addtocartbutton').first().click();
gtm.dataLayerContainsEvent('add_to_cart');
gtm.dataLayerEventContainsEcommerceItem('add_to_cart', {
...gtm.getCelenkaEcommerceItem(),
quantity: 1,
});
}
export function stepIntoCart() {
cy.get('.cartbox-footer > .btn', { timeout: 30_000 }).first().click();
cy.url().should('include', 'kosik');
gtm.dataLayerContainsEvent('view_cart');
cy.get('.cart-nextstep-wrapper > .btn', { timeout: 30_000 }).click();
}
export function clickMultisetSelectionButton(index: number) {
cy.get('.jsmultisets-selected .item').eq(index - 1).find('a').click();
cy.wait(500);
}
export function selectMultisetItem(index: number) {
cy.get('.jsmultisets-selection-item-navigation .item').eq(index - 1).find('a').click();
}
export function selectMultisetVariation(text: string) {
cy.get('.jsmultisets-product-variation').contains(text).click();
}
export function clickAddToSetButton() {
cy.get('.jsmultisets-sidebar-submit button').click();
}

24
tests/cypress/util.ts Normal file
View File

@@ -0,0 +1,24 @@
export function syncFetch(
url: string,
init?: RequestInit & { body?: XMLHttpRequestBodyInit | Document },
) {
// Running under node.js
if (typeof window === 'undefined') {
return require('sync-fetch')(url, init);
}
const request = new XMLHttpRequest();
if (init?.headers) {
for (const [key, value] of Object.entries(init.headers)) {
request.setRequestHeader(key, value);
}
}
request.open(init?.method ?? 'GET', url, false);
request.send(init?.body ?? null);
return {
...request,
json: () => JSON.parse(request.responseText),
};
}