qe-fe-automation
Version:
FE test automation framework using cypress
367 lines (327 loc) • 15.5 kB
text/typescript
import { Logs, Timeouts, Utility } from '@utility-lib/index';
import { FlightReSearchUtility, FlightBookingParams } from '@flight-modal/index';
import { Flights } from '@flight-lib/index';
export const flightSearchResultSelector = {
flightResultLoadedCount: '[qaId^="flightResultCountText"]',
flightFareRow: '[qaId^="flightFareRow"]',
selectFareType: '[qaId^="flightFareCard"]',
selectFlight: '[qaId="selectFlightButton"]',
bundleFlightCard: '[qaId^="flightBundleCard"]',
changeDepartureFlight: '[class^="flight-departure-card__change"]',
passengersTag: '.flight-header__user-multiple__label',
filterByAirLine: '[headerlabel="Airlines"]',
filterAirLineSelector: '.filter-boolean__label',
flightHeaderSearchInfo: '.flight-header__info',
flightMultiHeaderSearchPanel: 'ta-search-form-flight-multi-minimized',
flightNoResultSection: '.flight-no-results',
loyaltyCardFilterButton: '[title="Airlines"] [data-testid="activeFilter"]',
selectLoyaltyCard: '[qaId="flightFilterInClubFilter"] [class="mat-checkbox-frame"]'
};
export class FlightSearchResults {
// one way flight
static onewaySearchResult(flightParams: FlightBookingParams) {
FlightReSearchUtility.isNoResultFoundWrapper(() => {
cy.get(flightSearchResultSelector.flightFareRow).then((fareRows) => {
const randomOrderedArray = FlightSearchResults.getRandomArrayWithLength(fareRows.length);
FlightSearchResults.selectFirstAvailableOnewayFlight(fareRows.length, 0, randomOrderedArray);
});
}, flightParams);
}
static onewayMockSearchResult() {
cy.get(flightSearchResultSelector.flightFareRow)
.eq(0)
.find(flightSearchResultSelector.selectFareType)
.eq(0)
.click({ force: true });
cy.wait(['@waitForDepartureFlightFares', '@waitForDepartureFlightValidation']);
cy.get(flightSearchResultSelector.selectFlight).eq(0).click({ force: true });
}
static roundtripMockSearchResult() {
cy.get(flightSearchResultSelector.flightFareRow)
.eq(0)
.find(flightSearchResultSelector.selectFareType)
.eq(0)
.click({ force: true });
cy.wait(['@waitForDepartureFlightFares', '@waitForDepartureFlightValidation']);
cy.get(flightSearchResultSelector.selectFlight).eq(0).click({ force: true });
cy.wait('@waitForReturnFlight');
cy.get(flightSearchResultSelector.flightFareRow)
.eq(0)
.find(flightSearchResultSelector.selectFareType)
.eq(0)
.click({ force: true });
cy.wait(['@waitForReturnFlightFares', '@waitForReturnFlightValidation']);
cy.get(flightSearchResultSelector.selectFlight).eq(0).click({ force: true });
}
static multiCityBundleMockSearchResult() {
cy.get(flightSearchResultSelector.bundleFlightCard)
.eq(0)
.find(flightSearchResultSelector.selectFlight)
.eq(0)
.click({ force: true });
}
static selectFirstAvailableOnewayFlight(maxIndex: number, currentIndex: number, randomOrderedArray: number[]) {
cy.log(`flight search result - selectFirstAvailableOnewayFlight - currentIndex ${currentIndex}`);
cy.get(flightSearchResultSelector.flightFareRow)
.eq(randomOrderedArray[currentIndex])
.find(flightSearchResultSelector.selectFareType)
.eq(0)
.click({ force: true });
cy.wait(['@waitForDepartureFlightFares', '@waitForDepartureFlightValidation']);
cy.get(flightSearchResultSelector.selectFlight).eq(0).click({ force: true });
cy.wait('@waitForOnewayFlightContract').then((xhr) => {
cy.log(
`flight search result - selectFirstAvailableOnewayFlight - waitForFlightContract - response code ${xhr.response?.statusCode} - currentIndex ${currentIndex}`
);
if (xhr.response?.statusCode !== 200) {
if (maxIndex === currentIndex + 1) {
// for now, let test pass gracefully
} else {
cy.log(`flight search result - selectFirstAvailableOnewayFlight - recursion - currentIndex ${currentIndex}`);
FlightSearchResults.selectFirstAvailableOnewayFlight(maxIndex, currentIndex + 1, randomOrderedArray);
}
} else {
cy.log(
`flight search result - selectFirstAvailableOnewayFlight - proceed to contract page - currentIndex ${currentIndex}`
);
}
});
}
// round trip flight
static roundtripSearchResult(flightParams: FlightBookingParams) {
FlightReSearchUtility.isNoResultFoundWrapper(() => {
cy.get(flightSearchResultSelector.flightFareRow).then((fareRows) => {
const randomOrderedDepartureArray = FlightSearchResults.getRandomArrayWithLength(fareRows.length);
FlightSearchResults.selectFirstAvailableRoundtripDepartureFlight(
fareRows.length,
0,
randomOrderedDepartureArray
);
});
}, flightParams);
}
// this is a double recursion on both departure flight and return flight
static selectFirstAvailableRoundtripDepartureFlight(
maxDepartureIndex: number,
currentDepartureIndex: number,
randomOrderedDepartureArray: number[]
) {
cy.log(
`flight search result - selectFirstAvailableRoundtripDepartureFlight - currentDepartureIndex ${currentDepartureIndex}`
);
cy.get(flightSearchResultSelector.flightFareRow)
.eq(randomOrderedDepartureArray[currentDepartureIndex])
.find(flightSearchResultSelector.selectFareType)
.eq(0)
.click({ force: true });
cy.wait(['@waitForDepartureFlightFares', '@waitForDepartureFlightValidation']);
cy.get(flightSearchResultSelector.selectFlight).eq(0).click({ force: true });
cy.wait('@waitForReturnFlight');
// wait for page to load
cy.get(flightSearchResultSelector.flightResultLoadedCount, Timeouts.MEDIUM_TIMEOUT_60_SEC).should('exist');
cy.log(
`flight search result - selectFirstAvailableRoundtripDepartureFlight - get list of return flights - currentDepartureIndex ${currentDepartureIndex}`
);
// once i get return flight, i need to recursion on the return flight as well
cy.get(flightSearchResultSelector.flightFareRow).then((fareRows) => {
const randomOrderedReturnArray = FlightSearchResults.getRandomArrayWithLength(fareRows.length);
FlightSearchResults.selectFirstAvailableRoundtripReturnFlight(
maxDepartureIndex,
currentDepartureIndex,
fareRows.length,
0,
randomOrderedDepartureArray,
randomOrderedReturnArray
);
});
}
// eslint-disable-next-line max-params
static selectFirstAvailableRoundtripReturnFlight(
maxDepartureIndex: number,
currentDepartureIndex: number,
maxReturnIndex: number,
currentReturnIndex: number,
randomOrderedDepartureArray: number[],
randomOrderedReturnArray: number[]
) {
cy.log(
`flight search result - selectFirstAvailableRoundtripReturnFlight - currentDepartureIndex ${currentDepartureIndex} - currentReturnIndex ${currentReturnIndex}`
);
cy.get(flightSearchResultSelector.flightFareRow)
.eq(randomOrderedReturnArray[currentReturnIndex])
.find(flightSearchResultSelector.selectFareType)
.eq(0)
.click({ force: true });
cy.wait(['@waitForReturnFlightFares', '@waitForReturnFlightValidation']);
cy.get(flightSearchResultSelector.selectFlight).eq(0).click({ force: true });
cy.wait('@waitForRoundtripFlightContract').then((xhr) => {
cy.log(
`flight search result - selectFirstAvailableRoundtripReturnFlight - waitForFlightContract - response code ${xhr.response?.statusCode} - currentDepartureIndex ${currentDepartureIndex} - currentReturnIndex ${currentReturnIndex}`
);
if (xhr.response?.statusCode !== 200) {
if (maxReturnIndex === currentReturnIndex + 1) {
// this means return flight loops to the last one, now bump the departure flight
// unless departure flight also loops to the last one
if (maxDepartureIndex === currentDepartureIndex + 1) {
// for now, let test pass gracefully
} else {
cy.log(
`flight search result - selectFirstAvailableRoundtripReturnFlight - recursion on departure flight - currentDepartureIndex ${currentDepartureIndex} - currentReturnIndex ${currentReturnIndex}`
);
// go back to deparutre page
cy.get(flightSearchResultSelector.changeDepartureFlight).click({
force: true
});
// wait for page to load
cy.get(flightSearchResultSelector.flightResultLoadedCount, Timeouts.MEDIUM_TIMEOUT_60_SEC).should('exist');
FlightSearchResults.selectFirstAvailableRoundtripDepartureFlight(
maxDepartureIndex,
currentDepartureIndex + 1,
randomOrderedDepartureArray
);
}
} else {
cy.log(
`flight search result - selectFirstAvailableRoundtripReturnFlight - recursion on return flight - currentDepartureIndex ${currentDepartureIndex} - currentReturnIndex ${currentReturnIndex}`
);
FlightSearchResults.selectFirstAvailableRoundtripReturnFlight(
maxDepartureIndex,
currentDepartureIndex,
maxReturnIndex,
currentReturnIndex + 1,
randomOrderedDepartureArray,
randomOrderedReturnArray
);
}
} else {
cy.log(
`flight search result - selectFirstAvailableRoundtripReturnFlight - proceed to contract page - currentDepartureIndex ${currentDepartureIndex} - currentReturnIndex ${currentReturnIndex}`
);
}
});
}
// bundle flight
static bundleSearchResult(flightParams: FlightBookingParams) {
FlightReSearchUtility.isNoResultFoundWrapper(() => {
cy.get(flightSearchResultSelector.bundleFlightCard).then((bundles) => {
const randomOrderedArray = FlightSearchResults.getRandomArrayWithLength(bundles.length);
FlightSearchResults.selectFirstAvailableBundleFlight(bundles.length, 0, randomOrderedArray);
});
}, flightParams);
}
static selectFirstAvailableBundleFlight(maxIndex: number, currentIndex: number, randomOrderedArray: number[]) {
cy.log(`flight search result - selectFirstAvailableBundleFlight - currentIndex ${currentIndex}`);
cy.get(flightSearchResultSelector.bundleFlightCard)
.eq(randomOrderedArray[currentIndex])
.find(flightSearchResultSelector.selectFlight)
.eq(0)
.click({ force: true });
cy.wait('@waitForBundleFlightContract').then((xhr) => {
cy.log(
`flight search result - selectFirstAvailableBundleFlight - waitForFlightContract - response code ${xhr.response?.statusCode} - currentIndex ${currentIndex}`
);
if (xhr.response?.statusCode !== 200) {
if (maxIndex === currentIndex + 1) {
// for now, let test pass gracefully
} else {
cy.log(`flight search result - selectFirstAvailableBundleFlight - recursion - currentIndex ${currentIndex}`);
FlightSearchResults.selectFirstAvailableBundleFlight(maxIndex, currentIndex + 1, randomOrderedArray);
}
} else {
cy.log(
`flight search result - selectFirstAvailableBundleFlight - proceed to contract page - currentIndex ${currentIndex}`
);
}
});
}
static getRandomArrayWithLength(arrayLength: number): number[] {
const result = Array.from(Array(arrayLength).keys());
let currentIndex = result.length,
randomIndex;
// shuffle the array to random
while (currentIndex > 0) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
[result[currentIndex], result[randomIndex]] = [result[randomIndex], result[currentIndex]];
}
return result;
}
static multicityFlexSearchResult(flightParams: FlightBookingParams) {
FlightReSearchUtility.isNoResultFoundWrapper(() => {
cy.intercept('POST', '**/api/v1/trip/flight/bundle/flexible/searches/**/1**').as('waitForNextLegFlight');
FlightSearchResults.flexFlightSearchResult(0);
cy.allure().logStep('flight - search result - multi city flex flight - go to next leg flights');
cy.wait('@waitForNextLegFlight');
FlightReSearchUtility.isNoResultFoundWrapper(() => {
cy.intercept('POST', '**/api/v1/trip/flight/bundle/flexible/searches/**/contract**').as(
'waitForFlightContract'
);
FlightSearchResults.flexFlightSearchResult(1);
cy.allure().logStep('flight - multi city flex flight - search result - get contract');
cy.wait('@waitForFlightContract');
FlightReSearchUtility.switchLocationIfSearchResultEmpty(flightParams);
}, flightParams);
}, flightParams);
}
static flexFlightSearchResult(index: number) {
cy.allure().logStep('flight - search result - multi city flex flight - pick random fare group');
cy.intercept('GET', `**/api/v1/trip/flight/bundle/flexible/searches/**/${index}/flights/**/fares`).as(
'waitForFlexibleFlightFares'
);
cy.intercept('GET', `**/api/v1/trip/flight/bundle/flexible/searches/**/${index}/flights/**/validate**`).as(
'waitForFlexibleFlightValidation'
);
cy.get(flightSearchResultSelector.selectFareType).then((fares) => {
fares[Math.floor(Math.random() * fares.length)].click();
});
cy.wait(['@waitForFlexibleFlightFares', '@waitForFlexibleFlightValidation']);
cy.allure().logStep('flight - search result - multi city flex flight - pick a fare');
cy.get(flightSearchResultSelector.selectFlight).eq(0).click({ force: true });
}
public static isNoResultFound(): Cypress.Chainable<boolean> {
return cy.checkIfExist(flightSearchResultSelector.flightNoResultSection);
}
static clickOnFlightHeaderSearchInfoPanel(isItMultiCitySearch: boolean) {
if (isItMultiCitySearch) {
cy.get(flightSearchResultSelector.flightMultiHeaderSearchPanel).click();
} else {
cy.clickIfExist(flightSearchResultSelector.flightHeaderSearchInfo, Timeouts.SHORT_TIMEOUT_3_SEC);
}
}
static selectFutureFlightDate() {
Utility.selectFutureDate(2);
}
static setOrigin(location: string) {
Flights.setOrigin(location);
}
static setDestination(location: string) {
Flights.setDestination(location);
}
static searchFlight() {
Flights.searchFlight();
}
static verifyNumberOfBookings() {
cy.allure().logStep('verify number of bookings is not 0');
cy.get(flightSearchResultSelector.flightNoResultSection, Timeouts.MEDIUM_TIMEOUT_60_SEC).should('not.be.exist');
}
static verifyNumberOfPassengers(numberOfPassengers: number) {
cy.allure().logStep(`verify number of passengers is ${numberOfPassengers}`);
cy.get(flightSearchResultSelector.passengersTag).contains(`${numberOfPassengers} Passengers`);
}
static filterByAirLine(airLine: string) {
cy.allure().logStep('filter by air line');
cy.get(flightSearchResultSelector.filterByAirLine).click();
cy.get(flightSearchResultSelector.filterAirLineSelector).contains(airLine).click();
cy.wait('@waitForFlightStatus').then((xhr) => {
Logs.cypressResponseLog('AIRLINE RESPONSE', xhr);
});
}
static addLoyaltyCardFilter() {
cy.get(flightSearchResultSelector.loyaltyCardFilterButton).click();
cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
cy.get(flightSearchResultSelector.selectLoyaltyCard).click({
force: true
});
cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
}
}