UNPKG

qe-fe-automation

Version:
431 lines (388 loc) 16.2 kB
import { Logs, Timeouts, utilitySelector, Utility, DaysToMove } from '@utility-lib/index'; import { FlightBookingParams } from '@flight-modal/index'; import { HotelSearchResults, hotelSearchResultSelector, HotelCheckout } from '@hotel-lib/index'; import { ChatBox, chatBookingSelectors } from './chat'; import { FlightCheckout } from '@flight-lib/index'; const chatbotBookingSelectors = { locationInput: 'input[data-testid="Form__groupItem"]', getText: '[data-testid="DynamicList__AirportItem"]', wrapperButton: '[class*="messageAnim-enter-done"] button' }; export enum Directions { TO = 'To', FROM = 'From', HOTEL_LOCATION = 'Hotel location', DEPARTING_FROM = 'Departing from', ARRIVING_AT = 'Arriving at', PICKUP = 'Pick-up', DROPOFF = 'Drop-off' } const options: Intl.DateTimeFormatOptions = { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' }; export type FlightBookingData = { flightBookingParams: FlightBookingParams; departingFrom: Directions; arrivingAt: Directions; isChangeFlight?: boolean; }; export class ChatBooking { static bookTripFlight( flightBookingData: FlightBookingData, daysToMove: DaysToMove, numberOfFlights = 2 ) { const { flightBookingParams, departingFrom, arrivingAt, isChangeFlight = false } = flightBookingData; switch (numberOfFlights) { case 1: ChatBox.replyToAva('One-way'); break; case 2: ChatBox.replyToAva('Roundtrip'); break; } cy.allure().logStep('Book round trip flight'); ChatBooking.selectAirport(departingFrom, flightBookingParams.locations[0]); ChatBooking.selectAirport(arrivingAt, flightBookingParams.locations[1]); if (!isChangeFlight) { this.selectDates(daysToMove); } this.clickLetsGoButton(false); cy.wait(['@waitForGetFlightResults', '@waitForSentMessage']); cy.wait(Timeouts.MAX_TIMEOUT_120_SEC.timeout); ChatBox.waitUntilAvaStopTyping(); this.clickLetsGoButton(true); ChatBooking.selectTripFlight(numberOfFlights); this.clickLetsGoButton(true); cy.get(chatBookingSelectors.getChatMsgBody).then(($element) => { if ( $element.text().includes(`I couldn't find any results that match your search.`) ) { cy.allure().logStep(`I couldn't find any results that match your search.`); cy.wait(Timeouts.MEDIUM_TIMEOUT_30_SEC.timeout); cy.get(chatBookingSelectors.letsGoButton).as('letsGoButton'); cy.get('@letsGoButton').should('be.enabled'); cy.get('@letsGoButton').scrollIntoView(); cy.get('@letsGoButton').click({ force: true }); ChatBooking.selectTripFlight(numberOfFlights); } }); this.flightCheckout(flightBookingParams); } static continueBookTripFlight( flightBookingData: FlightBookingData, numberOfFlights = 2 ) { this.clickLetsGoButton(false); cy.wait(Timeouts.MAX_TIMEOUT_120_SEC.timeout); ChatBox.waitUntilAvaStopTyping(); this.clickLetsGoButton(true); ChatBooking.selectTripFlight(numberOfFlights); cy.get(chatBookingSelectors.getChatMsgBody).then(($element) => { if ( $element.text().includes(`I couldn't find any results that match your search.`) ) { cy.allure().logStep(`I couldn't find any results that match your search.`); cy.wait(Timeouts.MEDIUM_TIMEOUT_30_SEC.timeout); cy.get(chatBookingSelectors.letsGoButton).as('letsGoButton'); cy.get('@letsGoButton').should('be.enabled'); cy.get('@letsGoButton').scrollIntoView(); cy.get('@letsGoButton').click({ force: true }); ChatBooking.selectTripFlight(numberOfFlights); } }); this.flightCheckout(flightBookingData.flightBookingParams); } static changeFlight(flightBookingParams: FlightBookingParams) { const selectAirport = (index: number, location: string) => { cy.get(chatbotBookingSelectors.locationInput) .eq(index) .then((element) => { cy.wrap(element).click({ force: true }); cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout); cy.wrap(element).clear(); cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout); cy.wrap(element).type(location); cy.wrap(element) .invoke('val') .then((text) => { const selectLocationFromDropDown = text as string; const replacedText = selectLocationFromDropDown.replace(' - ', ' '); cy.log('Typed Text: ' + replacedText); cy.get(chatbotBookingSelectors.getText).contains(replacedText).click(); }); }); }; cy.get(chatbotBookingSelectors.wrapperButton) .contains('Edit details & search') .click(); cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout); selectAirport(0, flightBookingParams.locations[0]); selectAirport(1, flightBookingParams.locations[1]); } static changeFlightOptions(buttonName: string) { cy.get(chatbotBookingSelectors.wrapperButton).contains(buttonName).click(); ChatBooking.selectFlight(chatBookingSelectors.flightChangeCards); cy.wait(['@amplitudeBrowserSDK']); cy.get(chatBookingSelectors.chatButton).contains('Book it').click(); cy.wait('@waitForSentMessage'); } static selectAirport(direction: Directions, airport: string) { cy.allure().logStep(`Select ${direction} airport: ${airport}`); ChatBooking.clickAddFiledButton(direction); cy.get(chatBookingSelectors.airportInput(direction)).type(airport); cy.wait('@waitForLocation'); cy.get(chatBookingSelectors.airportsFromAutocomplete(airport)).click(); } static clickAddFiledButton(fieldName: string, buttonName = 'Add') { cy.allure().logStep(`Click ${buttonName} button for ${fieldName} field`); cy.get(chatBookingSelectors.formFields).contains(fieldName).click(); } static selectDates(inputDaysToMove: DaysToMove) { cy.allure().logStep('Select dates for next month'); const shiftedDates = Utility.shiftingDates(inputDaysToMove); ChatBooking.clickAddFiledButton('Date'); cy.get(chatBookingSelectors.calendar).should('be.visible'); if (shiftedDates.monthsToShift > 0) { Cypress._.times(shiftedDates.monthsToShift, () => { cy.get(chatBookingSelectors.calendarNextMonthButton).click(); }); } ChatBooking.selectDayInCalendar(shiftedDates.chosenCheckinDay); if (shiftedDates.chosenCheckinDay != shiftedDates.chosenCheckoutDay) { if (shiftedDates.monthsToShiftToCheckoutDay > 0) { Cypress._.times(shiftedDates.monthsToShiftToCheckoutDay, () => { cy.get(chatBookingSelectors.calendarNextMonthButton).click(); }); } ChatBooking.selectDayInCalendar(shiftedDates.chosenCheckoutDay); } } static enterShiftedDates(inputDaysToMove: DaysToMove) { Utility.shiftingDates(inputDaysToMove); cy.task('getDataFromCache', 'selectedCheckInDate').then( (selectedCheckInDate: any) => { cy.task('getDataFromCache', 'selectedCheckoutDate').then( (selectedCheckoutDate: any) => { const checkInDate = new Date(selectedCheckInDate); const checkoutDate = new Date(selectedCheckoutDate); const checkoutYear = checkInDate.getFullYear(); const formatter = new Intl.DateTimeFormat('en-US', options); const checkInFormatted = formatter.format(checkInDate); const checkoutFormatted = formatter.format(checkoutDate); const checkInFormattedWithoutYear = checkInFormatted.replace(/,\s\d{4}$/, ''); const checkoutFormattedWithoutYear = checkoutFormatted.replace( /,\s\d{4}$/, '' ); const formattedActual = `${checkInFormattedWithoutYear} - ${checkoutFormattedWithoutYear}, ${checkoutYear}`; ChatBox.typeMsgToAva(formattedActual); } ); } ); } static selectDayInCalendar(day: number) { cy.allure().logStep(`Select ${day} day in calendar`); cy.get(chatBookingSelectors.calendarDayButtons) .children(chatBookingSelectors.disabledCalendarDayButton) .contains(day) .click(); } static selectTripFlight(numberOfFlights = 2) { cy.allure().logStep('Select round trip flight'); Cypress._.times(numberOfFlights, () => { ChatBooking.selectFlight(chatBookingSelectors.flightCards); }); cy.wait(['@waitForSentMessage', '@amplitudeBrowserSDK']); } static selectFlight(selector: string, index = 0, retry = 0) { cy.allure().logStep('Select flight'); cy.wait(Timeouts.MEDIUM_TIMEOUT_30_SEC.timeout); cy.get(chatBookingSelectors.flightCardsList).then((element) => { if (!element.text().includes('Select')) { cy.wait(Timeouts.MEDIUM_TIMEOUT_10_SEC.timeout); } }); cy.get(selector).should('be.visible').eq(index).as('flightCard'); cy.get('@flightCard').contains('Select').click(); cy.wait('@waitForFlightStatus').then((interception) => { if (interception.response?.statusCode !== 200) { if (retry > 5) { throw new Error(`Failed to select flight. Tried ${retry} times.`); } retry++; Logs.logToCypressAndAllure('Retry to select another flight. Attempt: ' + retry); cy.get(chatBookingSelectors.paginatorNextButton).click(); ChatBooking.selectFlight(selector, ++index, retry); } }); } static checkIsChatMinimized() { cy.allure().logStep('Check if chat is minimized'); cy.get(chatBookingSelectors.chatView).should((chat) => { expect(chat, 'Chat should be minimized').not.exist; }); } static bookHotel(location: string, daysToMove: DaysToMove) { cy.allure().logStep('Book hotel'); this.selectAirport(Directions.HOTEL_LOCATION, location); this.selectDates(daysToMove); ChatBox.getHotelLocationText(); this.hotelCheckout(); } static hotelCheckout() { cy.get(chatBookingSelectors.letsGoButton).click(); cy.wait('@waitForHotelSearch'); this.expectHotelDatesAreCorrect(); HotelSearchResults.selectHotel(0); HotelSearchResults.selectRoomOption(); HotelCheckout.waitToBeLoaded(); HotelCheckout.checkoutFLow('Business'); HotelCheckout.expectHotelBookedSuccessfully('Hotel confirmed!'); } static bookCar( pickupLocation: string, dropoffLocation: string, daysToMove: DaysToMove ) { ChatBooking.selectDates(daysToMove); ChatBooking.selectAirport(Directions.PICKUP, pickupLocation); ChatBooking.selectAirport(Directions.DROPOFF, dropoffLocation); ChatBooking.clickLetsGoButton(false); } static clickLetsGoButton(withWaiting = true) { cy.allure().logStep('Click lets go button'); if (withWaiting) { cy.get(chatBookingSelectors.getChatMsgBody).then(($element) => { if ( $element.text().includes(`I couldn't find any results that match your search.`) ) { cy.allure().logStep(`I couldn't find any results that match your search.`); cy.wait(Timeouts.MEDIUM_TIMEOUT_30_SEC.timeout); cy.get(chatBookingSelectors.letsGoButton).as('letsGoButton'); cy.get('@letsGoButton').should('be.enabled'); cy.get('@letsGoButton').scrollIntoView(); cy.get('@letsGoButton').click({ force: true }); } }); } else { cy.get(chatBookingSelectors.letsGoButton) .should('be.enabled') .click({ force: true }); } } static flightCheckout(flightBookingParams: FlightBookingParams) { FlightCheckout.waitToPageBeLoaded(); FlightCheckout.expectNumberOfTravelers(1); ChatBooking.expectFlightSummaryIsCorrect(flightBookingParams.flightTripType); FlightCheckout.verifyFlightLocation(flightBookingParams); FlightCheckout.saveTripInformation(); FlightCheckout.checkCancellationPolicy(); FlightCheckout.acceptOutOfPolicyFlight(); FlightCheckout.updateContactDetails(); FlightCheckout.validateIfPassportAndVisaInfoRequired(); FlightCheckout.checkIn(flightBookingParams.checkInType); FlightCheckout.bookAndPay(flightBookingParams); FlightCheckout.expectFlightSuccessfullyConfirmed( flightBookingParams.flightConfirmText ); } static expectHotelLocationIsCorrect() { cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout); cy.get(hotelSearchResultSelector.selectHotel).should('be.visible'); cy.task('getDataFromCache', 'locationText').then((chatLocationInput: any) => { cy.log('chat Location Input ' + chatLocationInput); HotelSearchResults.getHotelLocationInput(); cy.task('getDataFromCache', 'getHotelLocationInput').then( (getHotelLocationInputText: any) => { cy.log('Hotel location from search result' + getHotelLocationInputText); expect(getHotelLocationInputText).to.equal(chatLocationInput); } ); }); } static expectHotelDatesAreCorrect() { cy.get(hotelSearchResultSelector.selectHotel).should('be.visible'); cy.task('getDataFromCache', 'selectedCheckInDate').then( (selectedCheckInDate: any) => { cy.task('getDataFromCache', 'selectedCheckoutDate').then( (selectedCheckoutDate: any) => { const checkInDate = new Date(selectedCheckInDate); const checkoutDate = new Date(selectedCheckoutDate); const checkoutYear = checkInDate.getFullYear(); const formatter = new Intl.DateTimeFormat('en-US', options); const checkInFormatted = formatter.format(checkInDate); const checkoutFormatted = formatter.format(checkoutDate); const checkInFormattedWithoutYear = checkInFormatted.replace(/,\s\d{4}$/, ''); const checkoutFormattedWithoutYear = checkoutFormatted.replace( /,\s\d{4}$/, '' ); const formattedActual = `${checkInFormattedWithoutYear} - ${checkoutFormattedWithoutYear}, ${checkoutYear}`; HotelSearchResults.getDatesFromCalendar(); cy.task('getDataFromCache', 'getDatesFromCalendar').then((dates: any) => { cy.log('chat box date:' + formattedActual); cy.log('hotel search results dates:' + dates); expect(dates).to.equal(formattedActual); }); } ); } ); } static expectFlightSummaryIsCorrect(flightType: string) { switch (flightType) { case 'ONEWAY': flightType = 'One-way'; break; case 'ROUNDTRIP': flightType = 'Roundtrip'; break; } cy.get(utilitySelector.checkoutSummary).should('contain.text', flightType); cy.task('getDataFromCache', 'selectedCheckInDate').then( (selectedCheckInDate: any) => { cy.task('getDataFromCache', 'selectedCheckoutDate').then( (selectedCheckoutDate: any) => { const checkInDate = new Date(selectedCheckInDate); const checkoutDate = new Date(selectedCheckoutDate); const formatter = new Intl.DateTimeFormat('en-US', options); const checkInFormatted = formatter.format(checkInDate); const checkoutFormatted = formatter.format(checkoutDate); const checkInFormattedWithoutYear = checkInFormatted.replace(/,\s\d{4}$/, ''); const checkoutFormattedWithoutYear = checkoutFormatted.replace( /,\s\d{4}$/, '' ); cy.get(utilitySelector.checkoutSummary).then((checkoutSummary) => { const summaryText = checkoutSummary.text(); expect(summaryText).to.contain(checkInFormattedWithoutYear); expect(summaryText).to.contain(checkoutFormattedWithoutYear); }); } ); } ); } static changeHotelBookingFlow(location: string) { cy.wait(Timeouts.SHORT_TIMEOUT_5_SEC.timeout); cy.get(chatBookingSelectors.formFields).contains(Directions.HOTEL_LOCATION).click(); cy.get(chatBookingSelectors.airportInput(Directions.HOTEL_LOCATION)).type(location); cy.wait('@waitForLocation'); cy.get(chatBookingSelectors.airportsFromAutocomplete(location)).click(); this.hotelCheckout(); } }