qe-fe-automation
Version:
FE test automation framework using cypress
488 lines (451 loc) • 18.9 kB
text/typescript
import {
Logs,
guidRegex,
Utility,
utilitySelector,
Timeouts,
InputDelays
} from '@utility-lib/index';
import { AmplitudeEvents } from '@growth-lib/amplitude-events';
import { Interception } from 'cypress/types/net-stubbing';
import { FlightBookingParams } from '@flight-modal/flight_booking_utility';
import { FlightTripType } from './search';
const flightCheckoutSelector = {
saveButton: '.ta-button__content',
changeCancellationPolicy: '.ta-checkout-booking-policy__continue span',
contactDetailsContinueButton: '.flight-checkout__contact .ta-button__content',
travelerCheckIn: '.ta-checkout-traveler button',
bookFLight: ' [qaid="flightContractBook"]',
cancellationTitle: '[title="Change, cancelation, and refund policy"]',
continueCancellation: '.ta-checkout-booking-policy .ta-button__content',
skipCheckIn: '[class^="ta-checkout-traveler__ancillaries_action__skip ta-button"]',
flightBookedStatusTitle: '.booking-success__left__title',
passportInfo: '[title="Passport & visa information"]',
passportAcknowLedgement:
'[qaid="passportAndVisaCheckoutCard"] .mat-checkbox-inner-container',
setPassPortInfo: '[qaid="passportAndVisaCheckoutCard"] .ta-button__content',
bookingSuccessMsg: '[qaid="flightConfirmed"]',
roundTripInfo: '[qaid="tripCheckoutShowAllTripsBlock"] [qaid="tripNameInputDiv"]',
addTripInfo: '.ta-trip-checkout__select .ta-button__content',
bundledFlightSuccessMsg: '.booking-success .booking-success__left__title',
bookingSummary: '.booking-item',
outOfPolicyHeader: 'ta-out-of-policy',
outOfPolicyHeaderGuest: '[headerprimarybuttonlabel="Your policy"]',
outOfPolicyBookingReason: 'textarea[formcontrolname="reason"]',
acceptOOPAcknowledgement: 'ta-out-of-policy .mat-checkbox-inner-container',
acceptOOPAcknowledgementGuest:
'[headerprimarybuttonlabel="Your policy"] .mat-checkbox-inner-container',
continueOOPFlight: 'ta-out-of-policy [qaid="infoBannerPrimaryButton"]',
continueOOPFlightGuest:
'[headerprimarybuttonlabel="Your policy"] [qaid="infoBannerPrimaryButton"]',
requireDataSection: '.checkout-card .traveler-require-data__form',
requireDataEmail: 'input[formcontrolname="alternateEmail"]',
requireDataSave: '[data-testid="traveler-required-save"]',
numberOfTravelers:
'.flight-checkout-booking-summary__in-booking > :nth-child(1) > :nth-child(2) > span',
bookFlightPopup: 'div.booking-success__close ta-svg-image div',
viewTrips: '.booking-complete-others__left__buttons > :nth-child(2) > div',
flightBookingTotalCharges:
'.flight-checkout-booking-summary__est-total div span:nth-child(1)',
flightBookingTotalCurrency:
'.flight-checkout-booking-summary__est-total div span:nth-child(2)',
promoCardPercentage: '.ta-promotion-rebate-dropdown span',
oopFlightHeader: '[titletype="WARNING"] .policy-slash',
oopReasonHeader:
'[qaid="outOfPolicyCheckoutCard"] [class="booking-policy booking-policy__oop"]',
acceptOOPReasonAcknowledgement:
'[qaid="outOfPolicyCheckoutCard"] .mat-checkbox-inner-container',
continueOOPReasonFlight:
'[qaid="outOfPolicyCheckoutCard"][qaid="infoBannerPrimaryButton"]',
creditCardNumber: '[class^="ta-payment-card--digits"]',
confirmationModalNotEmployeeBook: 'ta-information-modal .ta-button__content',
confirmButtonNotEmployeeBook: 'ta-information-modal .ta-button__content',
loyaltyCardInfo: '.ta-guest-info-loyalty-card__details',
securePriceModal: '.ta-exit-secure-price-modal',
securePriceModalCTAApprove: '.ta-modal-footer__main-block .ta-button--primary-theme',
checkoutInsuranceLocation: '[data-testid="ta-insurance-addressLine1"]',
checkoutInsuranceFirstName: '[data-testid="ta-insurance-firstName"]',
checkoutInsuranceLastName: '[data-testid="ta-insurance-lastName"]',
checkoutInsuranceEmail: '[data-testid="ta-insurance-email"]',
checkoutInsuranceRelation: '[data-testid="ta-insurance-relation"]',
autoCompleteLocationsItems: '.ta-location-search-v2__item',
checkoutInsuranceRelationItems: '.ta-select-option',
checkoutInsuranceContinue: '[data-testid="ta-insurance-continue"]',
tripFeeCheckOut: 'div.checkout-card__content ta-charge-item',
tripFeeValue: 'div.charge-item__right-top',
checkoutGuestInfo: '.checkout-card__content ta-guest-info-v2',
tripInfoSection: 'ta-trip-checkout-v2 .ta-trip-checkout',
flightContractLegBlock: '[qaid="flightContractLegBlock"]',
flightCardMiniDepartureAirport: '[qaid="flightCardMiniDepartureAirport"]',
flightCardMiniArrivalAirport: '[qaid="flightCardMiniArrivalAirport"]',
skipSeatSelection: '[qaid="checkoutTravelerSkipAncillaries"]',
infoBannerCheckbox: '.info-banner__checkbox'
};
export class FlightCheckout {
static waitToPageBeLoaded(): void {
cy.allure().logStep('wait for flight checkout page loaded');
FlightCheckout.verifyUrlAndTripInfoSection();
cy.wait(['@waitForMatchingTrips', '@waitForPaymentMethods']);
}
static verifyUrlAndTripInfoSection() {
cy.url().should(
'match',
new RegExp(
`/search/(flights|flightBundles|flightBundlesFlex|)/${guidRegex}/contracts/${guidRegex}`
)
);
cy.get(flightCheckoutSelector.tripInfoSection).should('be.visible');
}
static setTripInfo() {
Utility.saveTripInformation();
}
static isCurrentUrlCheckoutPage(): Cypress.Chainable<boolean> {
const regExValue = `\\/search\\/flights\\/${guidRegex}\\/contracts\\/${guidRegex}`;
return cy
.location('pathname', Timeouts.MEDIUM_TIMEOUT_60_SEC)
.then((pathName) => !!pathName.match(regExValue));
}
static saveTripInformation() {
Utility.saveTripInformation();
}
static createTripInformation() {
Utility.createNewTrip();
cy.wait(Timeouts.SHORT_TIMEOUT_5_SEC.timeout);
Utility.saveTripInformation();
}
static updateContactDetails() {
cy.allure().logStep('continue contact details');
cy.get(flightCheckoutSelector.infoBannerCheckbox).eq(0).click();
cy.get(flightCheckoutSelector.contactDetailsContinueButton).click();
}
static changeCancellationPolicy() {
cy.allure().logStep('continue contact details');
cy.get(flightCheckoutSelector.changeCancellationPolicy).click();
}
static updateEmailDetails(email: string) {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.log('log personal email details');
cy.get(utilitySelector.bodySelector).then(($body) => {
if ($body.find(flightCheckoutSelector.requireDataSection).length > 0) {
cy.allure().logStep('enter required email details');
cy.log('enter required email details');
cy.get(flightCheckoutSelector.requireDataEmail).type(
email,
InputDelays.INPUT_DELAY_100_MILLIS
);
cy.get(flightCheckoutSelector.requireDataSave).click();
} else {
cy.log('enter required email details not required');
}
});
}
static checkIn(checkInType?: string) {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.bodySelector).then(($body) => {
if (checkInType && $body.text().includes(`${checkInType}`)) {
cy.get(flightCheckoutSelector.travelerCheckIn).contains(`${checkInType}`).click();
cy.allure().logStep('add check in');
} else {
cy.allure().logStep('skip check in');
cy.get(flightCheckoutSelector.skipCheckIn, Timeouts.SHORT_TIMEOUT_3_SEC).each(
(ele) => {
cy.wrap(ele).click();
}
);
}
});
}
static checkInSeveralForPassengers(numberOfPassengers: number, checkInType?: string) {
Cypress._.times(numberOfPassengers, () => {
FlightCheckout.checkIn(checkInType);
});
}
static storeBookingData() {
cy.get(flightCheckoutSelector.flightBookingTotalCharges).then((element) => {
cy.task('putDataInCache', {
key: 'flightBookingTotalCharges',
data: element.text().trim()
});
});
cy.get(flightCheckoutSelector.flightBookingTotalCurrency).then((element) => {
cy.task('putDataInCache', {
key: 'flightBookingTotalChargesCurrency',
data: element.text().trim()
});
});
if (
Cypress.$(`${flightCheckoutSelector.tripFeeCheckOut}:contains('Trip fee')`).length >
0
) {
cy.contains(flightCheckoutSelector.tripFeeCheckOut, 'Trip fee')
.find(flightCheckoutSelector.tripFeeValue)
.should('exist')
.then((value) => {
cy.task('putDataInCache', {
key: 'tripFeeCheckOut',
data: value.text().trim()
});
});
}
}
static bookAndPay(flightParams: FlightBookingParams): void {
if (flightParams.isExchangeFlow) {
cy.intercept('POST', '**/api/v1/trip/flight/exchange/book/**/contract/**').as(
'waitForFlightBooking'
);
} else if (
flightParams.flightTripType === FlightTripType.ONEWAY ||
flightParams.flightTripType === FlightTripType.ROUNDTRIP
) {
cy.intercept(
'POST',
'**/api/v1/trip/flight/searches/**/contracts/**/book/streaming**'
).as('waitForFlightBooking');
} else if (flightParams.flightTripType === FlightTripType.MULTICITY_BUNDLE) {
cy.intercept(
'POST',
'**/api/v1/trip/flight/bundle/searches/**/contracts/**/book**'
).as('waitForFlightBooking');
} else if (flightParams.flightTripType === FlightTripType.MULTICITY_CUSTOM) {
cy.intercept(
'POST',
'**/api/v1/trip/flight/bundle/flexible/searches/**/contracts/**/book**'
).as('waitForFlightBooking');
}
cy.get(flightCheckoutSelector.bookFLight).click();
this.confirmBookForNotCompanyEmployee();
cy.wait('@waitForFlightBooking').then((xhr) => {
this.setToCacheSuggestedHotelSearch(xhr);
Logs.cypressRequestLog('FLIGHT CHECKOUT RESPONSE', xhr);
});
cy.allure().logStep('Book a flight');
cy.get(utilitySelector.bodySelector).then((body) => {
if (body.find(flightCheckoutSelector.bookFlightPopup).length > 0) {
cy.get(flightCheckoutSelector.bookFlightPopup).click();
}
});
}
static confirmBookForNotCompanyEmployee() {
cy.get(utilitySelector.bodySelector).then((body) => {
if (body.find(flightCheckoutSelector.confirmationModalNotEmployeeBook).length > 0) {
cy.get(flightCheckoutSelector.confirmButtonNotEmployeeBook)
.contains('Confirm')
.click();
}
});
}
static confirmDropSecureModal(): void {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.bodySelector).then((body) => {
if (body.find(flightCheckoutSelector.securePriceModal).length > 0) {
cy.get(flightCheckoutSelector.securePriceModalCTAApprove)
.contains('Back to checkout')
.click();
AmplitudeEvents.addExpectedAmplitudeEvents(
'Checkout drop pop up showed',
'Checkout drop pop up clicked'
);
}
});
}
static isSecuredModalRemoved(): void {
cy.get(utilitySelector.bodySelector).then((body) => {
expect(body.find(flightCheckoutSelector.securePriceModal).length).to.equal(0);
});
}
private static setToCacheSuggestedHotelSearch(xhr: Interception): void {
cy.task('putDataInCache', {
key: 'suggestedHotelSearch',
data: !!xhr.response?.body?.suggestedHotelSearch
});
}
static checkCancellationPolicy() {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.log(' check Cancellation Policy');
cy.get(utilitySelector.bodySelector).then((cancellation) => {
if (cancellation.find(flightCheckoutSelector.changeCancellationPolicy).length) {
cy.get(flightCheckoutSelector.changeCancellationPolicy).click();
cy.allure().logStep('continue cancellation policy ');
} else {
cy.allure().logStep('Cancellation refund not found');
cy.log('Cancellation refund not found');
}
});
}
static acceptOutOfPolicyFlight() {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.log('add oop reason ');
cy.get(utilitySelector.bodySelector).then((outOfPolicy) => {
if (outOfPolicy.find(flightCheckoutSelector.oopFlightHeader).length > 0) {
cy.get(flightCheckoutSelector.outOfPolicyBookingReason).type(
'Urgent booking required'
);
cy.get(flightCheckoutSelector.acceptOOPAcknowledgement).click();
cy.get(flightCheckoutSelector.continueOOPFlight).click();
cy.allure().logStep('accept out of policy');
} else {
cy.allure().logStep('out of policy not found');
cy.log('out of policy not found');
}
});
}
static acceptOopAndMentionReason() {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.log('add oop reason ');
cy.get(utilitySelector.bodySelector).then((outOfPolicy) => {
if (outOfPolicy.find(flightCheckoutSelector.oopReasonHeader).length > 0) {
cy.get(flightCheckoutSelector.outOfPolicyBookingReason).type(
'Urgent booking required'
);
cy.get(flightCheckoutSelector.acceptOOPReasonAcknowledgement).click();
cy.get(flightCheckoutSelector.continueOOPReasonFlight).last().click();
cy.allure().logStep('accept out of policy');
} else {
cy.allure().logStep('out of policy not found');
cy.log('out of policy not found');
}
});
}
// delete when Guest flow UI updated to the latest version
static acceptOutOfPolicyFlightGuestFlow() {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(utilitySelector.bodySelector).then((outOfPolicy) => {
if (outOfPolicy.find(flightCheckoutSelector.outOfPolicyHeaderGuest).length > 0) {
cy.get(flightCheckoutSelector.outOfPolicyBookingReason).type(
'Urgent booking required'
);
cy.get(flightCheckoutSelector.acceptOOPAcknowledgementGuest).click();
cy.get(flightCheckoutSelector.continueOOPFlightGuest)
.contains(' Continue ')
.click();
cy.allure().logStep('accept out of policy');
} else {
cy.allure().logStep('out of policy not found');
cy.log('out of policy not found');
}
});
}
static validateIfPassportAndVisaInfoRequired() {
cy.get(utilitySelector.bodySelector).then((passport) => {
if (passport.find(flightCheckoutSelector.passportAcknowLedgement).length > 0) {
cy.get(flightCheckoutSelector.passportAcknowLedgement).click();
cy.get(flightCheckoutSelector.setPassPortInfo).click();
cy.allure().logStep('add passport detail');
} else {
cy.allure().logStep('passport detail not required');
cy.log('Passport not required');
}
});
}
static expectBookingSummary(tripName: string) {
cy.get(flightCheckoutSelector.bookingSummary).contains(`${tripName}`);
cy.allure().logStep(`${tripName} is present`);
}
static expectFlightSuccessfullyConfirmed(successMsg: string) {
cy.get(flightCheckoutSelector.bookingSuccessMsg, Timeouts.MAX_TIMEOUT_120_SEC).should(
'be.contain',
`${successMsg}`
);
cy.allure().logStep('Flight is successfully booked');
}
static expectBundledFlightSuccessfullyBooked(successMsg: string) {
cy.get(
flightCheckoutSelector.bundledFlightSuccessMsg,
Timeouts.MAX_TIMEOUT_120_SEC
).should('be.contain', `${successMsg}`);
cy.allure().logStep('Flight is successfully booked');
}
static expectNumberOfTravelers(numberOfTravelers: number): void {
cy.get(flightCheckoutSelector.numberOfTravelers).should(
'contain.text',
numberOfTravelers
);
}
static viewTrips() {
cy.get(flightCheckoutSelector.viewTrips).click();
}
static verifyPromoCard(value: string) {
cy.get(flightCheckoutSelector.promoCardPercentage).should(
'contain.text',
`${value} gift card earned`
);
}
static storeCreditCardLastDigits() {
cy.get(flightCheckoutSelector.creditCardNumber)
.eq(0)
.invoke('text')
.then((text) => {
const cardNumber = text.replace(/[^0-9 ]/g, '');
cy.task('putDataInCache', {
key: 'cardNumber',
data: cardNumber
});
});
}
static verifyLoyaltyCardInfo(loyaltyCardInfo: string) {
cy.allure().logStep('verify loyalty card info');
cy.get(flightCheckoutSelector.loyaltyCardInfo).contains(loyaltyCardInfo);
}
static addInsurance() {
cy.allure().logStep('add insurance');
cy.get(flightCheckoutSelector.checkoutInsuranceLocation).type(
'NEVERLAND TOKYO, 2 Chome-21-7 Dogenzaka, Shibuya City, Tokyo, Japan'
);
cy.get(flightCheckoutSelector.autoCompleteLocationsItems).first().trigger('click', {
force: true
});
cy.get(flightCheckoutSelector.checkoutInsuranceRelation).click();
cy.get(flightCheckoutSelector.checkoutInsuranceRelationItems)
.first()
.trigger('click', {
force: true
});
cy.get(flightCheckoutSelector.checkoutInsuranceFirstName).type('Eevee');
cy.get(flightCheckoutSelector.checkoutInsuranceLastName).type('Pikachu');
cy.get(flightCheckoutSelector.checkoutInsuranceEmail).type('pokemon@world.com');
cy.get(flightCheckoutSelector.checkoutInsuranceContinue).click();
}
static verifyNumberOfTravelers(travelersNumber: number) {
cy.allure().logStep(`verify number of travelers is equeal to ${travelersNumber}`);
cy.get(flightCheckoutSelector.checkoutGuestInfo).should(
'have.length',
travelersNumber
);
}
static verifyFlightLocation(flightBookingParams: FlightBookingParams) {
const checkAirports = (index: number, departure: string, arrival: string) => {
cy.get(flightCheckoutSelector.flightContractLegBlock)
.eq(index)
.as('flightBlock')
.then(() => {
cy.get('@flightBlock')
.find(flightCheckoutSelector.flightCardMiniDepartureAirport)
.should('contain.text', departure);
cy.get('@flightBlock')
.find(flightCheckoutSelector.flightCardMiniArrivalAirport)
.should('contain.text', arrival);
});
};
if (flightBookingParams.flightTripType === 'ROUNDTRIP') {
const departure = flightBookingParams.locations[0].slice(0, 3);
const arrival = flightBookingParams.locations[1].slice(0, 3);
checkAirports(0, departure, arrival);
checkAirports(1, arrival, departure);
}
}
static skipSeatSelection() {
cy.get(utilitySelector.bodySelector).then((body) => {
if (body.find(flightCheckoutSelector.skipSeatSelection).length > 0) {
cy.get(
flightCheckoutSelector.skipSeatSelection,
Timeouts.SHORT_TIMEOUT_3_SEC
).each((ele) => {
cy.wrap(ele).click();
});
cy.allure().logStep('Seat maps were skipped');
} else {
cy.allure().logStep('Seat maps not required');
}
});
}
}