UNPKG

qe-fe-automation

Version:
488 lines (451 loc) 18.9 kB
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'); } }); } }