qe-fe-automation
Version:
FE test automation framework using cypress
375 lines (337 loc) • 13.8 kB
text/typescript
import { Logs, Timeouts } from '@utility-lib/index';
import { Directions } from './booking';
export const chatBookingSelectors = {
chatToggleButton: '[data-testid="ta-chat-toggle-button"]',
chatMessagesViewLoader: '#chat-body [data-testid="Loader"]',
bookTravelButton: '#chat-body [data-testid="Book travel"]',
bookSpecificTravelButton: (travelType: string) =>
`#chat-body [data-testid="${travelType}"]`,
airportInput: (direction: Directions) => `#chat-body input[placeholder="${direction}"]`,
calendarNextMonthButton: '#chat-body .react-calendar__navigation__next-button',
calendarDayButtons: '#chat-body .react-calendar__month-view__days',
disabledCalendarDayButton:
':not(.react-calendar__month-view__days__day--neighboringMonth)',
calendar: '#chat-body .react-calendar',
letsGoButton: '#chat-body [data-testid="Let\'s go!"]',
airportsFromAutocomplete: (airports: string) =>
`#chat-body [data-testid="${airports}"]`,
formFields: '#chat-body [data-testid="micro-form-label"]',
startChatButton: '#chat-body [data-testid="new-chat-button"]',
endChatButton: '#chat-body [data-testid="Nav__closeButton"]',
leaveChatButtons: '[data-testid="leave-chat-confirmation"] [data-testid="btn-group"]',
flightCards: '#chat-body [data-testid="new-flight-info"]',
flightChangeCards: '.swiper-slide > div',
flightCardsList: '[data-testid="new-flight-search-swiper-swiper"]',
chatButton: '#chat-body button',
paginatorNextButton:
'#chat-body [data-testid="swiper-paginator"] [data-testid="right-chevron"]',
chatView: '[data-role="ta-chat-messages-view"]',
getTextsAfterSelectingBookingDetails:
'[class*="messageAnim-enter"] [data-testid="micro-form-label"]',
chatMsgInput: '[data-role="ta-chat-message-input"]',
chatButtonReplyToAva: '[data-testid="ChatButton"]',
needHelpByChat: '[data-testid="needHelpByChat"]',
chatBody: '[data-testid="messages_scroll"] > div',
getChatMsgBody: '[data-role="ta-chat-message-item-body"] P',
getMsg: '[data-testid="messageItem"] p',
chatLogo: '[data-testid="entry__logo"]',
replyToAva: (replyMsg: string) =>
`[data-testid="ChatButton"] [data-testid*="${replyMsg}"]`,
chatInvoiceElement:
'[data-role="ta-chat-message-item-body"] div > div:nth-child(2) > a',
labelMessage: '[data-testid="labelMessage"]'
};
export enum TravelType {
FLIGHT = 'Flight',
HOTEL = 'Hotel',
CAR = 'Car',
TRAIN = 'Train'
}
export class ChatBox {
static openChatWithAva() {
cy.allure().logStep('Open chat with Ava');
this.openChat();
this.startNewChatWithAva();
}
static getCheckInCheckOutDates() {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(chatBookingSelectors.getTextsAfterSelectingBookingDetails)
.contains('Dates')
.siblings()
.invoke('text')
.then((dateRange) => {
cy.log(dateRange);
cy.task('putDataInCache', {
key: 'chatBoxDateRange',
data: dateRange
});
});
cy.allure().logStep(`Get check-in and check-out dates`);
}
static newChatButtonShouldVisible() {
cy.get(chatBookingSelectors.startChatButton).should('be.visible');
cy.allure().logStep('New chat button is visible');
}
static startANewChatOrContinue() {
this.openChat();
cy.get(chatBookingSelectors.chatButtonReplyToAva).then(($buttons) => {
if (!$buttons.length) {
ChatBox.startNewChatWithAva();
}
});
}
static openChat() {
cy.allure().logStep('Open chat');
cy.get(chatBookingSelectors.chatToggleButton).should('be.visible').click();
this.waitUntilChatLoaderDisappears();
}
static closeChat() {
cy.allure().logStep('Close chat');
cy.get(chatBookingSelectors.endChatButton).should('be.visible').click();
}
static confirmCloseChat() {
cy.allure().logStep('Confirm close chat');
cy.get(chatBookingSelectors.leaveChatButtons).contains('Yes, end chat').click();
cy.get(chatBookingSelectors.labelMessage).should('contain.text', 'Chat ended');
cy.allure().logStep(`Chat ended.`);
}
static denyCloseChat() {
cy.allure().logStep('Deny close chat');
cy.get(chatBookingSelectors.leaveChatButtons).contains('Continue chatting').click();
}
static waitUntilChatLoaderDisappears() {
cy.allure().logStep('Wait until chat loader disappears');
cy.get(
chatBookingSelectors.chatMessagesViewLoader,
Timeouts.MEDIUM_TIMEOUT_60_SEC
).should('not.exist');
}
static waitUntilAvaStopTyping() {
cy.allure().logStep('Wait until Ava stop typing');
cy.get(chatBookingSelectors.chatBody, Timeouts.MAX_TIMEOUT_120_SEC)
.contains('Ava is typing')
.should('not.be.visible');
}
static startNewChatWithAva() {
cy.allure().logStep('Start new chat with Ava');
cy.wait(['@waitForInitChatChannel', '@waitForAgentToCatiInProgress']);
this.waitUntilChatLoaderDisappears();
}
static selectBookTravelFlow(travelType: TravelType) {
cy.allure().logStep(`Select ${travelType} travel flow`);
cy.get(chatBookingSelectors.bookTravelButton).click();
cy.get(chatBookingSelectors.bookSpecificTravelButton(travelType)).click();
}
static getHotelLocationText() {
cy.get(chatBookingSelectors.getTextsAfterSelectingBookingDetails)
.contains(Directions.HOTEL_LOCATION)
.siblings()
.invoke('text')
.then((chatLocationInput) => {
cy.log(chatLocationInput);
cy.task('putDataInCache', {
key: 'locationText',
data: chatLocationInput
});
});
cy.allure().logStep(`Get hotel location text`);
}
static selectMsgYouWannaSendBackToAva(conversation: string, fallback?: string) {
if (!fallback) {
cy.get(chatBookingSelectors.replyToAva(conversation)).should('be.visible').click();
cy.allure().logStep(`Select message you wanna send back to Ava: ${conversation}`);
return;
}
cy.get(chatBookingSelectors.chatButtonReplyToAva)
.then(($buttons) => {
if ($buttons.eq(1).text() === conversation) {
return [conversation, fallback];
}
return [fallback];
})
.then((responses) => {
responses.forEach((response) => {
ChatBox.selectMsgYouWannaSendBackToAva(response);
});
});
}
static typeMsgToAva(typeMsg: string) {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(chatBookingSelectors.chatMsgInput).type(`${typeMsg}{enter}`);
cy.allure().logStep(`Type message to Ava: ${typeMsg}`);
}
static verifyIfMsgInputDisplayed() {
cy.allure().logStep('Verify if message input is not displayed');
cy.get(chatBookingSelectors.chatMsgInput).should('exist');
}
static verifyIfMsgInputNotDisplayed() {
cy.allure().logStep('Verify if message input is not displayed');
cy.get(chatBookingSelectors.chatMsgInput).should('not.exist');
}
static getHotelDetailForChange() {
cy.contains(chatBookingSelectors.getMsg, /Hotel in/)
.invoke('text')
.then((text: any) => {
cy.log('Booked hotel details' + text);
this.typeMsgToAva(
`i would like to change hotel, here's the detail ${text} would like different hotel on same dates`
);
this.confirmationMsg();
});
cy.allure().logStep(`Get hotel detail for change`);
}
static changeHotel() {
this.waitUntilChatLoaderDisappears();
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(chatBookingSelectors.chatButtonReplyToAva).then(($elements) => {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
if ($elements.text().includes('Make a second booking')) {
this.selectMsgYouWannaSendBackToAva('Make a second booking');
} else if ($elements.text().includes('Continue to change')) {
cy.contains('Continue to change').click();
}
});
cy.allure().logStep(`Change hotel`);
}
static confirmationMsg() {
cy.get(chatBookingSelectors.getMsg).then(($element) => {
if (
$element
.text()
.includes('Just to confirm, you want to change your hotel booking in ')
) {
this.typeMsgToAva('Far from my destination, so please change it');
}
});
cy.allure().logStep(`Confirmation message`);
}
static changeHotelConversation() {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
cy.get(chatBookingSelectors.getMsg).then(($elements) => {
if ($elements.text().includes('What would you like to do?')) {
this.getHotelDetailForChange();
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
this.waitUntilChatLoaderDisappears();
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
this.confirmationMsg();
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
this.waitUntilChatLoaderDisappears();
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
this.selectMsgToReply();
}
});
cy.allure().logStep(`Change hotel conversation`);
}
static selectMsgToReply() {
cy.get(chatBookingSelectors.chatButtonReplyToAva).then(($elements) => {
if ($elements.length > 0) {
cy.log('wait for chat button to appear');
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
this.changeHotel();
} else {
cy.get(chatBookingSelectors.chatMsgInput)
.its('length')
.then((length) => {
if (length > 0) {
cy.log('wait for chat message input to appear');
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
this.typeMsgToAva('Yes');
cy.log('send msg to ava');
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
} else {
cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
}
});
}
});
cy.allure().logStep(`Select message to reply`);
}
static replyToAva(replyMsg: string) {
cy.wait(Timeouts.SHORT_TIMEOUT_5_SEC.timeout);
cy.get(chatBookingSelectors.replyToAva(replyMsg)).should('be.visible').click();
cy.allure().logStep(`Reply to Ava: ${replyMsg}`);
}
static selectBooking(replyMsg: string, index: number) {
cy.wait(Timeouts.SHORT_TIMEOUT_5_SEC.timeout);
cy.get(chatBookingSelectors.replyToAva(replyMsg))
.should('be.visible')
.eq(index)
.click();
cy.allure().logStep(`Select ${replyMsg} booking number: ${index}`);
}
static expectFurtherAvaConnectToAgent(replyMsg: string) {
cy.wait(Timeouts.MEDIUM_TIMEOUT_10_SEC.timeout);
cy.contains('Continue to change').should('not.exist');
cy.get(`[data-testid="${replyMsg}"]`).should('not.exist');
cy.contains('Let me get an agent to help.').should('be.visible');
cy.allure().logStep(`Ava connect to agent`);
}
static needHelpByChat() {
cy.get(chatBookingSelectors.chatLogo).should('be.visible');
cy.get(chatBookingSelectors.needHelpByChat).should('be.visible').click();
cy.allure().logStep('Need help by chat');
}
static readAvaMsgAndSelectReply(weGotMsgFromAva: string, weReplied: string) {
cy.wait(Timeouts.MEDIUM_TIMEOUT_10_SEC.timeout);
ChatBox.waitUntilAvaStopTyping();
cy.get(chatBookingSelectors.getChatMsgBody).then(($elements) => {
if ($elements.text().includes(weGotMsgFromAva)) {
ChatBox.replyToAva(`${weReplied}`);
cy.allure().logStep(`Message received from Ava: ${weGotMsgFromAva}`);
}
});
cy.allure().logStep(`Message sent to Ava: ${weReplied}`);
}
static readAvaMsgAndTypeReply(weGotMsgFromAva: string, weReplied: string) {
cy.wait(Timeouts.MEDIUM_TIMEOUT_10_SEC.timeout);
ChatBox.waitUntilAvaStopTyping();
cy.get(chatBookingSelectors.getChatMsgBody).then(($elements) => {
cy.allure().logStep(
`Checking if message received from Ava contains: ${weGotMsgFromAva}`
);
if ($elements.text().includes(weGotMsgFromAva)) {
ChatBox.typeMsgToAva(`${weReplied}`);
cy.allure().logStep(`Message received from Ava: ${weGotMsgFromAva}`);
}
});
cy.allure().logStep(`Message sent to Ava: ${weReplied}`);
}
static expectMsgReceivedFromAva(weGotMsgFromAva: string) {
cy.wait(Timeouts.SHORT_TIMEOUT_5_SEC.timeout);
cy.get(chatBookingSelectors.getChatMsgBody).should(
'contain.text',
`${weGotMsgFromAva}`
);
cy.allure().logStep(`Message received from Ava: ${weGotMsgFromAva}`);
}
static validateFlightItinerary(locations: string[]) {
cy.allure().logStep('Validating flight itinerary.');
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 checkinDateToValidation = checkInDate.toDateString().substring(4);
const checkoutDateToValidation = checkoutDate.toDateString().substring(4);
const fromLocation = locations[0].substring(0, 3);
const toLocation = locations[1].substring(0, 3);
this.expectMsgReceivedFromAva(
`Flight from ${fromLocation} to ${toLocation} on ${checkinDateToValidation}. Returning on ${checkoutDateToValidation}`
);
}
);
}
);
}
static checkIfInvoicePresent() {
cy.allure().logStep('Checking if an invoice is present.');
cy.get(chatBookingSelectors.chatInvoiceElement).should('be.visible');
}
static validateInvoiceMsgText(text: string) {
cy.allure().logStep(`Validating if invoice message text is equal "${text}".`);
cy.get(chatBookingSelectors.chatInvoiceElement)
.parents()
.should('contain.text', text);
}
}