qe-fe-automation
Version:
FE test automation framework using cypress
430 lines (380 loc) • 16.6 kB
text/typescript
import { UtilityIntercept } from './api-intercept';
import { TripTileType, verticalType, Timeouts } from '@utility-lib/constants';
import { Interception } from 'cypress/types/net-stubbing';
import { Logs } from './log';
type navigation = 'HOME' | 'TRIPS' | 'EVENTS' | 'OFFICE_GUIDES' | 'HELP';
export type DaysToMove = {
daysToMove: number;
daysAfterMovedDays: number;
};
export const utilitySelector = {
businessTypeSelect: '[class^="trip-type-select__container"]',
tripCheckoutAddToTrip: '[qaid="tripCheckoutAddToTrip"]',
createNewTrip: '[qaid="tripCheckoutCreateNewTrip"]',
saveTripInfo: '[qaid="tripCheckoutCreateButton"]',
dropDownButton: '.ta-select',
tripCheckoutSelect: '.ta-trip-checkout__select',
nextMonthCalendarButton: '[class="popover popover-calendar enter"] [class$="ta-calendar__handle--right"]',
calendarButton: '[class^="ta-date-trigger"] [class^="ta-date-trigger"][class$="text"]',
calendarInputText: '[class^="ta-date-trigger"] [class^="ta-date-trigger"][class$="text"] [class*="__date-wrap"]',
calendarText: '[class^="ta-date-trigger"] .ta-date-trigger__text',
selectDate: '[data-testid="calendarDay"]',
closeCalendar: '.popover-content [type="submit"]',
startDayRangeCalendar: 'div.ta-calendar-day--range-start',
searchLoader: '.ta-search__content',
searchLoaderPersonal: '.ta-lottie-search__content',
warningMsg: '[class^="ta-toastr-event__message"]',
chatBoxCLoseButton: '#ta-chat [href="#"]',
upgradeLiquidCardPopup: '[title^="Upgrade to TripActions Liquid and get"] .ta-trip-group__group',
dismissLiquidCardPopup: '.trip-type-selection__group-container__actions',
bookingTypeTitle: '.ta-trip-tile__title',
bookingType: '[class^="ta-tabs__item"]',
searchLocationInput: '.search-form-container-minimized__fake-form__text',
checkoutSummary: '[class="booking-item"]',
tripTile: (tripType: TripTileType) =>
`[class^="search-form-container__header__theme-selector"] [aria-label=${tripType}]`,
tripsOnTripPage: '.booking-complete-others__left__buttons > :nth-child(2) > :nth-child(2)',
firstTripOnTripPage: 'ta-trip-card-v2',
eventsPageTab: '[data-qaid="EVENTS"]',
ariaLabel: (name: string) => `[aria-label*="${name}"]`,
dropdownLocation: (location: string) => `.popover-content [aria-label^="${location}"]`,
cancellationReasonDropdown: '[formcontrolname="selectedReason"] [type="button"]',
cancelConfirm: '[qaid="cancelBookingButton"]',
canceledLabel: '[class^="booking-status-tag"]',
canceledWarning: '[class^="booking-status-tag"] span',
iframe: '#invoiceIframe',
selectTripOnTripPage: '[qaid="goToItinerary"]',
popUpCancel: '[qa-id="event-action-cancel-train"]',
dataTestID: (name: string) => `[data-testid="${name}"]`,
closePersonalTravelerInputModal: '.ta-button__content',
buttonClass: '.ta-button-v2',
closeTravelerInputModal: '.ta-chevron-toggle__icon.ta-chevron-toggle__icon--expanded',
navTypeItem: (navType: string) => `[data-qaid="${navType}"]`,
eventActionCancel: (vertical: string) => `[qaid="eventActionCancel${vertical}"]`,
eventActionChange: (vertical: string) => `[qaid="eventActionChange${vertical}"]`,
cancellationReason: (reason: string) => `[aria-label="${reason}"]`,
adminNav: (adminNav: string) => `[data-qaid="${adminNav}"] button`,
adminDropDownButton: (dropDownButton: string) => `[data-qaid="${dropDownButton}"]`,
bodySelector: 'body',
tableRowSelector: 'tr',
listItemSelector: 'li',
buttonSelector: 'button',
spanSelector: 'span',
inputSelector: 'input',
imageSelector: 'img',
paragraphSelector: 'p'
};
export class Utility {
static selectTripTileType(tripType: TripTileType): void {
cy.get(utilitySelector.tripTile(tripType), Timeouts.MEDIUM_TIMEOUT_60_SEC).click({
force: true
});
cy.allure().logStep(`${tripType} selected`);
}
static selectBusinessType(bookingType: TripTileType) {
cy.get(utilitySelector.searchLocationInput).click();
cy.get(utilitySelector.bookingType).contains(bookingType).click({ force: true });
}
static setTripInfo() {
cy.allure().logStep('set trip information');
cy.get(utilitySelector.tripCheckoutAddToTrip || utilitySelector.saveTripInfo, Timeouts.MAX_TIMEOUT_120_SEC);
this.closeIfChatBoxIsOpen();
cy.get(utilitySelector.bodySelector).then(($body) => {
if ($body.text().includes(' Add to this trip ')) {
cy.get(utilitySelector.tripCheckoutAddToTrip).contains(' Add to this trip ').click();
cy.allure().logStep('add to this trip');
} else {
cy.allure().logStep('save trip information');
cy.get(utilitySelector.dropDownButton).click();
cy.intercept('POST', /api\/v1\/trip\/tripFee\/searches/).as('waitForSaveInfo');
cy.get(utilitySelector.saveTripInfo).contains(' Save trip info ').click();
cy.wait('@waitForSaveInfo');
}
});
}
static saveTripInformation() {
cy.clickIfExist(utilitySelector.saveTripInfo, Timeouts.MEDIUM_TIMEOUT_60_SEC);
}
static createNewTrip() {
cy.clickIfExist(utilitySelector.createNewTrip, Timeouts.MEDIUM_TIMEOUT_60_SEC);
}
static selectVertical(tab: verticalType) {
cy.allure().logStep(`select search type: ${tab}`);
cy.get(utilitySelector.searchLocationInput, Timeouts.MEDIUM_TIMEOUT_60_SEC).should('be.visible').click();
cy.get(utilitySelector.dataTestID(tab)).should('be.visible').click();
}
static clickLocationInput() {
cy.allure().logStep('click on the location input');
cy.get(utilitySelector.searchLocationInput).click();
}
static selectLocationFromDropdown(location: string) {
cy.get(utilitySelector.dropdownLocation(location)).eq(0).trigger('click', {
force: true
});
}
static selectFutureDate(numberOfMonthsAfterStartDate = 5, newDayOfMonth = 0, numberOfDaysAfterDeparture = 0) {
cy.allure().logStep(`select ${numberOfMonthsAfterStartDate} months later flight`);
cy.get(utilitySelector.calendarButton).then((elements) => {
let dayInMonth = newDayOfMonth > 0 ? newDayOfMonth : 1 + Math.floor(Math.random() * 27);
for (let i = 0; i < elements.length; i++) {
cy.get(utilitySelector.calendarButton).eq(i).click();
if (i === 0) {
Cypress._.times(numberOfMonthsAfterStartDate, () => {
cy.get(utilitySelector.nextMonthCalendarButton).click();
});
}
if (dayInMonth > 28) {
dayInMonth -= 28;
cy.get(utilitySelector.nextMonthCalendarButton).click();
}
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.selectDate).contains(dayInMonth).should('be.visible').eq(0).click({ force: true });
cy.get(utilitySelector.closeCalendar).click();
if (i === 0 && numberOfDaysAfterDeparture > 0) {
dayInMonth +=
numberOfDaysAfterDeparture <= 7 ? numberOfDaysAfterDeparture : 1 + Math.floor(Math.random() * 3);
} else {
dayInMonth += Math.ceil(Math.random() * 7);
}
}
});
}
static shiftingDates(inputDaysToMove: DaysToMove) {
const { daysToMove, daysAfterMovedDays } = inputDaysToMove;
const currDate = new Date();
const currMonthIndex = currDate.getMonth();
currDate.setDate(currDate.getDate() + daysToMove);
// The temporary variable is needed for correct putDataInCache work
const tempDate = new Date(currDate);
cy.task('putDataInCache', {
key: 'selectedCheckInDate',
data: tempDate
});
cy.log('checkInDate: ' + currDate);
const chosenCheckinDay = currDate.getDate();
const chosenCheckinMonthIndex = currDate.getMonth();
const monthsToShift = chosenCheckinMonthIndex - currMonthIndex;
currDate.setDate(currDate.getDate() + daysAfterMovedDays);
cy.task('putDataInCache', {
key: 'selectedCheckoutDate',
data: currDate
});
cy.log('checkoutDate: ' + currDate);
const chosenCheckoutDay = currDate.getDate();
const chosenCheckoutMonthIndex = currDate.getMonth();
const monthsToShiftToCheckoutDay = chosenCheckoutMonthIndex - chosenCheckinMonthIndex;
return {
monthsToShift: monthsToShift,
monthsToShiftToCheckoutDay: monthsToShiftToCheckoutDay,
chosenCheckinDay: chosenCheckinDay,
chosenCheckoutDay: chosenCheckoutDay
};
}
static selectShiftedDate(inputDaysToMove: DaysToMove) {
cy.allure().logStep(`Select dates shifted ${inputDaysToMove.daysToMove} according to today`);
const shiftedDates = Utility.shiftingDates(inputDaysToMove);
cy.get(utilitySelector.calendarButton).then((elements) => {
for (let i = 0; i < elements.length; i++) {
cy.get(utilitySelector.calendarButton).eq(i).click();
if (i === 0) {
if (shiftedDates.monthsToShift > 0) {
Cypress._.times(shiftedDates.monthsToShift, () => {
cy.get(utilitySelector.nextMonthCalendarButton).click();
});
}
cy.get(utilitySelector.selectDate).contains(shiftedDates.chosenCheckinDay).eq(0).click();
} else {
if (shiftedDates.monthsToShiftToCheckoutDay > 0) {
Cypress._.times(shiftedDates.monthsToShiftToCheckoutDay, () => {
cy.get(utilitySelector.nextMonthCalendarButton).click();
});
}
cy.get(utilitySelector.selectDate).contains(shiftedDates.chosenCheckoutDay).eq(0).click();
}
cy.get(utilitySelector.closeCalendar).click();
}
});
}
// workaround for guest invite due to bug GME-2118
static reselectSelectedDate() {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.calendarText).eq(0).click();
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.startDayRangeCalendar).click();
}
static openEventsPage() {
cy.allure().logStep('open events page');
cy.get(utilitySelector.eventsPageTab).contains('Events').click();
}
static openTeamOffsitePage() {
cy.allure().logStep('open events page');
cy.get(utilitySelector.eventsPageTab).click();
}
static expectSearchLoaderDisabled() {
cy.allure().logStep('wait until search loader until it disappear');
cy.get(utilitySelector.searchLoader, Timeouts.MAX_TIMEOUT_120_SEC).should('be.not.exist');
cy.get(utilitySelector.searchLoaderPersonal, Timeouts.MAX_TIMEOUT_120_SEC).should('be.not.exist');
}
static waitUntilWarningMsgDisabled() {
cy.allure().logStep('wait for warning msg to disappear');
cy.get(utilitySelector.warningMsg, Timeouts.MAX_TIMEOUT_120_SEC).should('be.not.exist');
}
static closeIfChatBoxIsOpen() {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.bodySelector).then((chatBox) => {
if (chatBox.find(utilitySelector.chatBoxCLoseButton).length > 0) {
cy.get(utilitySelector.chatBoxCLoseButton).click();
} else {
cy.log('chat box not opened');
}
});
}
static visitSearchPage(retryCount = 3) {
cy.allure().logStep('visit search page');
cy.visit('app/user2/home');
this.waitForLoadHomePage();
cy.url()
.should('include', '/home', Timeouts.MEDIUM_TIMEOUT_60_SEC)
.then((urlCheck) => {
if (!urlCheck && retryCount > 0) {
cy.log(`<<<<<<<< Retry attempt >>>>>>>>>: ${retryCount}`);
this.visitSearchPage(retryCount - 1);
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
this.waitForLoadHomePage();
}
});
}
static verifyPageTitle(title: string) {
cy.title().should('eq', title);
}
static selectNavItem(navType: navigation) {
cy.get(utilitySelector.navTypeItem(navType)).trigger('click');
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
}
static changeBrowserLanguageTo(language: string) {
cy.log('Changing browser language to DE');
cy.on('window:before:load', (win) => {
Object.defineProperty(win.navigator, 'languages', {
value: [language, 'en', 'en-US']
});
Object.defineProperty(win.navigator, 'language', {
value: language
});
});
}
static waitForLoadHomePage() {
UtilityIntercept.interceptBaseApis();
}
static openTrip() {
cy.log('Opening trip from trip page');
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.tripsOnTripPage).click();
cy.get(utilitySelector.selectTripOnTripPage, Timeouts.MEDIUM_TIMEOUT_60_SEC).should('be.visible').eq(0).click();
}
static cancelTrip(vertical: string) {
cy.allure().logStep('cancel hotel');
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.eventActionCancel(vertical)).should('be.visible').click();
}
static selectCancellationReason(reason: string) {
cy.allure().logStep(`select cancellation reason ${reason}`);
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.cancellationReasonDropdown).click();
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.cancellationReason(reason)).click({
force: true
});
}
static confirmCancellation() {
cy.allure().logStep('Confirm Cancellation');
cy.get(utilitySelector.cancelConfirm).click();
cy.wait('@waitForCancelBooking').then((interception) => {
const status = interception.response?.statusCode;
cy.log(` ---->>> Cancellation status code: ${status} <<<----`);
});
}
static confirmFlightCancellation() {
cy.allure().logStep('confirm cancellation');
cy.get(utilitySelector.cancelConfirm).click();
}
static expectCancelledLabelIsPresent() {
cy.allure().logStep('expect cancelled label is present');
cy.get(utilitySelector.canceledLabel).should('contain', 'Canceled');
cy.get(utilitySelector.canceledWarning).should('contain', 'Canceled');
}
static getIframeDocument() {
return cy.get(utilitySelector.iframe).its('0.contentDocument').should('exist');
}
static getIframeBody() {
return this.getIframeDocument().its(utilitySelector.bodySelector).should('not.be.undefined').then(cy.wrap);
}
static changeTrip(vertical: string) {
cy.get(utilitySelector.eventActionChange(vertical)).click();
}
static selectAdminNav(adminNav: string, dropDownButton: string) {
cy.allure().logStep(`select ${adminNav}`);
cy.get(utilitySelector.adminNav(adminNav)).click();
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.adminDropDownButton(dropDownButton)).click();
}
static loginAsAdmin(password: any) {
cy.clearLocalStorage();
cy.clearCookies();
cy.clearLocalStorage();
cy.task('getDataFromCache', 'companyCreationEmail').then((email: any) => {
cy.loginWithAuthToken({ email, password });
cy.allure().logStep(`logged in as admin: ${email}`);
});
}
static addAmexBTAEUPaymentUuId(amexBTAPlatformType: any) {
cy.task('getDataFromCache', 'paymentMethodUuId').then((paymentMethodUuId: any) => {
cy.addAmexBTAEUPaymentUuId(paymentMethodUuId, amexBTAPlatformType);
});
}
static confirmHotelCancellation() {
cy.allure().logStep('confirm cancellation');
cy.get(utilitySelector.cancelConfirm).click();
}
static createEntity(creds: any, legalEntitiesData: any) {
cy.clearLocalStorage();
cy.clearCookies();
cy.clearLocalStorage();
cy.task('getDataFromCache', 'companyCreationEmail').then((email: any) => {
cy.createCompanyLegalEntity(email, creds, legalEntitiesData);
cy.allure().logStep(`logged in as admin: ${email}`);
});
}
static getXmlContentFromCache(cacheKey: string) {
cy.allure().logStep('Get XML content from cache');
return cy.task('getDataFromCache', cacheKey).then((response: any) => {
const xmlContent = response.xmlReports[0];
return xmlContent;
});
}
static parseXmlContent(xmlContent: string): Document {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlContent, 'text/xml');
return xmlDoc;
}
static normalizeText(text: string) {
cy.allure().logStep(`Normalize text: ${text}`);
const normalizedText = text
.trim()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '');
return normalizedText;
}
static closeSurveyIfExists() {
cy.document().then((doc) => {
const surveyClose = utilitySelector.dataTestID('surveyClose');
if (doc.querySelector(surveyClose)) {
cy.get(surveyClose).then((elements) => {
console.log({ elements });
for (let i = 0; i < elements.length; i++) {
cy.get(surveyClose).eq(i).click();
}
});
}
});
}
}