const Page = require("./Page");
/**
* Ab In Den Urlaub Page Class Methods
*/
class UrlaubPage extends Page {
/**
* Get page elements
* @returns {Object} - page elements
*/
get elements() {
return {
cookieButton: "#CybotCookiebotDialogBodyButtonAccept",
destinationInput: "#idestflat",
locationLayerDiv: "div[class=\"location-layer show-layer-on\"]",
locationLayerHiddenDiv: "div[class=\"location-layer show-layer-on hidden\"]",
aiduacWrapperDiv: "#ac_old > div.ac-box > div.ac-item.location.layer-version > div.aiduac-wrapper.destinations.aiduac-open",
aiduacContentDestinationsLink: "#ac_old div[class=\"aiduac-content destinations\"] a[data-name=\"{txt}\"]",
startDateDiv: "#flattrip > div.form > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-startpage > div > div > div.datepicker-input-wrapper.datepicker-input-wrapper-start > div",
nextStartMonthSpan: "#flattrip > div.form > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-startpage > div > div > div.datepicker-layer.start-input > div.datepicker-header > span.month-button.month-button-next.icon-arrow-right-bold",
selectedStartMonthYearSpan: "#flattrip > div.form > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-startpage > div > div > div.datepicker-layer.start-input > div.datepicker-header > div > span[class=\"\"]",
selectDateTd: "#flattrip > div.form > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-startpage > div > div",
nextReturnMonthSpan: "#flattrip > div.form > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-startpage > div > div > div.datepicker-layer.end-input > div.datepicker-header > span.month-button.month-button-next.icon-arrow-right-bold",
selectedReturnMonthYearSpan: "#flattrip > div.form > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-startpage > div > div > div.datepicker-layer.end-input > div.datepicker-header > div > span[class=\"\"]",
travellerSummaryInput: "#travellerSummary",
travellerLayerDiv: "div[id=\"travellerLayer\"][style=\"\"]",
adultCountDiv: "#adult > div",
adultPlusButton: "#adult > button.plusButton",
adultMinusButton: "#adult > button.minusButton",
travellerApplyButton: "#travellerLayer > div.submit > button",
searchOffersBtn: "#submit",
hotelSelectionPageFirstResMediaDiv: "#hotelList > div.skeleton-wrapper > article:nth-child(1) > div.media.media-fullscreen.js-media.js-showFullscreenSlider.media-loaded",
hotelSelectionPageLoaderSection: "section[id=\"ajaxLoadSkeleton\"][style=\"display: none;\"]",
currentPageNameSpan: "#bookingProcess > div > ul > li.active > span > span",
startDateHotelDiv: "#flattrip > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-formfilter > div > div > div.datepicker-input-wrapper.datepicker-input-wrapper-start > div",
nextStartMonthHotelSpan: "#flattrip > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-formfilter > div > div > div.datepicker-layer.start-input > div.datepicker-header > span.month-button.month-button-next.icon-arrow-right-bold",
selectedStartMonthYearHotelSpan: "#flattrip > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-formfilter > div > div > div.datepicker-layer.start-input > div.datepicker-header > div > span[class=\"\"]",
selectDateHotelTd: "#flattrip > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-formfilter > div > div",
nextReturnMonthHotelSpan: "#flattrip > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-formfilter > div > div > div.datepicker-layer.end-input > div.datepicker-header > span.month-button.month-button-next.icon-arrow-right-bold",
selectedReturnMonthYearHotelSpan: "#flattrip > div._input-box._input-box-icon-set._input-box-size-._input-box-datePickerTwoInputs.datepicker-formfilter > div > div > div.datepicker-layer.end-input > div.datepicker-header > div > span[class=\"\"]",
directFlightHotelInput: "#directFlight",
priceRangeDiv: "#priceRange",
starRatingCatInput: "#optCategory{txt}",
customerReviewSvg: "#hotelFilter > div.filter.filter-kundenbewertung > label:nth-child({txt}) > svg",
hotelsortingSelect: "#hotelsorting > option[value=\"{txt}\"]",
priceBoxStrong: "#hotelList > div.skeleton-wrapper > article > div.content > div.priceBox > div > a > div > strong",
aboutOffersDiv: "#hotelList > div.skeleton-wrapper > article:nth-child(1) > div.content > div.priceBox > a > div",
hotelListHeadSection: "#hotelListHeadSkeleton",
dateOfArrivalLabel: "#offerFilter-arrival div.offerFilter-list label.offerFilter-listItem.checkbox",
hotelDetailsPageAjaxLoadSection: "section[id=\"ajaxLoad\"][class=\"section_ajaxLoad hidden\"]",
offerFilterDiv: "#offerFilter",
skeletonOffersSection: "section[id=\"skeletonOffers\"][class=\"section_skeletonOffers\"]",
hotelDetailsPageFirstOfferSpan: "#skeletonOffers > section.skeleton-offers > article.success:nth-child(1) > div > div.price.js-priceBlock > a > span.text",
hotelDetailsPageHotelNameDiv: "#hotelInfoBox > div.hotel-info-head.has-bookmarks > div.hotel-name-wrapper > div._styling-h1.hotel-name > div",
hotelDetailsPageDurationDeparture: "#skeletonOffers > section.skeleton-offers > article > div > div.duration > div.duration-departure > div > span:nth-child(3)",
hotelDetailsPageDurationReturn: "#skeletonOffers > section.skeleton-offers > article > div > div.duration > div.duration-return > div > span:nth-child(3)",
hotelDetailsPageDurationDepartureTime: "#skeletonOffers > section.skeleton-offers > article:nth-child(1) > div > div.duration > div.duration-departure > div > span:nth-child(1)",
hotelDetailsPageDurationReturnTime: "#skeletonOffers > section.skeleton-offers > article:nth-child(1) > div > div.duration > div.duration-return > div > span:nth-child(1)",
bookingPageHotelNameSpan: "#vacationSummary > ul > ol.content-left > li.hotel-name > span.value",
departureTimeRangeDiv: "#departureTimeRange > div > div:nth-child(1) > div",
arrivalTimeRangeDiv: "#departureTimeRange > div > div:nth-child(3) > div",
returnDepartureTimeRangeDiv: "#returnTimeRange > div > div:nth-child(1) > div",
returnArrivalTimeRangeDiv: "#returnTimeRange > div > div:nth-child(3) > div",
};
}
/**
* Generate Date Selector
* @param {String} dateTd - css or xpath selector element
* @param {Object} dateObject - Date object
* @param {String} input - start / end
* @returns {String} - css selector
*/
generateDateSelector(dateTd, dateObject, input) {
if (this.world.debug) console.log("generateDateSelector");
return `${dateTd} > div.datepicker-layer.${input}-input > div.datepicker-wrapper > div > div > div.month.month-${dateObject.getMonth()}.year-${dateObject.getFullYear()} > table > tbody > tr > td.day.day-${dateObject.getDate()}`;
}
/**
* Generate Offset
* @param {String} time
* @returns {Number}
*/
generateOffset(time, from = 0) {
let offset = ((from > 0) ? ((from - parseInt(time)) * 10) : (parseInt(time) * 10));
offset = (offset > 110) ? 110 : offset;
return offset;
}
/**
* Check the range
* @param {String} a
* @param {String} b
* @param {String} x
* @param {String} y
* @returns {Boolean}
*/
checkRange(a, b, x, y) {
const x1 = parseInt(a.replace(":", ""));
const y1 = parseInt(b.replace(":", ""));
const x2 = parseInt(x.replace(":", ""));
const y2 = parseInt(y.replace(":", ""));
if (x2 <= x1 && y2 >= y1) {
return true;
}
return false;
}
/**
* Click Button
* @param {String} buttonToClick - css or xpath selector element for button
* @param {String} waitForElement - css or xpath selector element for wait
* @param {Boolean} scroll - need scroll or not
* @param {String} scrollToElement - css or xpath selector element for scroll
*/
async clickButton(buttonToClick, waitForElement = "", scroll = true, scrollToElement = "") {
if (this.world.debug) console.log("clickButton");
await this.world.helper.waitFor(buttonToClick);
const el = await this.world.helper.findElement(buttonToClick);
if (scroll) {
const element = (scrollToElement === "") ? el : await this.world.helper.findElement(scrollToElement);
await this.world.helper.scrollToElement(element);
}
await el.click();
if (waitForElement) {
await this.world.helper.waitFor(waitForElement);
}
await this.world.sleep(1000);
}
/**
* Check And Click Or Enter
* @param {String} destination
* @param {WebElement} element - the element
*/
async checkAndClickOrEnter(destination, elementInput) {
if (this.world.debug) console.log("checkAndClickOrEnter");
const { aiduacContentDestinationsLink, aiduacWrapperDiv, locationLayerHiddenDiv } = this.elements;
const link = aiduacContentDestinationsLink.replace("{txt}", destination);
await this.world.helper.waitFor(aiduacWrapperDiv);
await this.world.sleep(2000);
if (this.world.debug) console.log(link);
const els = await this.world.helper.findElements(link);
if (els[0]) {
if (this.world.debug) console.log(els);
await this.clickButton(link, "", false);
} else {
await elementInput.sendKeys(this.world.selenium.Key.ENTER);
}
await this.world.helper.waitFor(locationLayerHiddenDiv);
await this.world.sleep(1000);
}
/**
* Select destination
* @param {String} destination
*/
async selectDestination(destination) {
if (this.world.debug) console.log("selectDestination");
const { destinationInput, locationLayerDiv } = this.elements;
await this.world.helper.waitFor(destinationInput);
const input = await this.world.helper.findElement(destinationInput);
await input.click();
await this.world.helper.waitFor(locationLayerDiv);
await input.sendKeys(destination);
await this.world.sleep(2000);
await this.checkAndClickOrEnter(destination, input);
}
/**
* Click Next Month
* @param {String} locator - css or xpath selector element
*/
async clickNextMonth(locator) {
if (this.world.debug) console.log("clickNextMonth");
await this.world.sleep(50);
const el = await this.world.helper.findElement(locator);
await el.click();
await this.world.sleep(50);
}
/**
* Get Selected Month and Year
* @param {String} locator - css or xpath selector element
* @returns {Object} - selected month and year
*/
async getSelectedMonthYear(locator) {
if (this.world.debug) console.log("getSelectedMonthYear");
const selectedMonth = await this.world.helper.getElementAttribute(locator, "data-month");
const selectedYear = await this.world.helper.getElementAttribute(locator, "data-year");
return {
selectedMonth,
selectedYear,
};
}
/**
* Set Date
* @param {Object} dateObject - Date object
* @param {String} locatorNextMonth - css or xpath selector element for next month
* @param {String} locatorSelectedMonthYear - css or xpath selector element for selected month year
* @param {String} input - start / end
* @param {String} pageName - name of the page
*/
async setDate(dateObject, locatorNextMonth, locatorSelectedMonthYear, input, pageName = "") {
if (this.world.debug) console.log("setDate");
await this.world.sleep(50);
await this.world.helper.waitFor(locatorNextMonth);
let { selectedMonth, selectedYear } = await this.getSelectedMonthYear(locatorSelectedMonthYear);
if (this.world.debug) console.log(`${selectedMonth}/${selectedYear}`);
while (dateObject.getFullYear() > selectedYear) {
await this.clickNextMonth(locatorNextMonth);
const selected = await this.getSelectedMonthYear(locatorSelectedMonthYear);
selectedMonth = selected.selectedMonth;
selectedYear = selected.selectedYear;
if (this.world.debug) console.log(`${selectedMonth}/${selectedYear}`);
}
while (dateObject.getMonth() > selectedMonth) {
await this.clickNextMonth(locatorNextMonth);
const selected = await this.getSelectedMonthYear(locatorSelectedMonthYear);
selectedMonth = selected.selectedMonth;
if (this.world.debug) console.log(`${selectedMonth}/${selectedYear}`);
}
const selectorName = `selectDate${pageName}Td`;
const dateTd = this.elements[selectorName];
if (this.world.debug) console.log(dateTd);
const selectDateTd = this.generateDateSelector(dateTd, dateObject, input);
if (this.world.debug) console.log(selectDateTd);
await this.world.helper.waitFor(selectDateTd);
const el = await this.world.helper.findElement(selectDateTd);
if (!pageName) await this.world.helper.scrollToElement(el);
await el.click();
await this.world.sleep(50);
}
/**
* Set Date Range
* @param {String} startDate
* @param {String} returnDate
* @param {String} locatorStartDate
* @param {String} locatorNextStartMonth
* @param {String} locatorSelectedStartMonthYear
* @param {String} locatorNextReturnMonth
* @param {String} locatorSelectedReturnMonthYear
* @param {String} pageName
*/
async setDateRange(startDate, returnDate, locatorStartDate, locatorNextStartMonth, locatorSelectedStartMonthYear, locatorNextReturnMonth, locatorSelectedReturnMonthYear, pageName = "") {
if (this.world.debug) console.log("setDateRange");
const sDate = new Date(startDate);
const eDate = new Date(returnDate);
const today = new Date();
const lastDate = new Date();
lastDate.setFullYear(lastDate.getFullYear() + 3, lastDate.getMonth() - 1, lastDate.getDate());
if (sDate > today) {
if (eDate >= sDate) {
if (lastDate >= eDate) {
// Select start date
await this.world.helper.waitFor(locatorStartDate);
const el = await this.world.helper.findElement(locatorStartDate);
await el.click();
await this.setDate(sDate, locatorNextStartMonth, locatorSelectedStartMonthYear, "start", pageName);
// Select return date
await this.setDate(eDate, locatorNextReturnMonth, locatorSelectedReturnMonthYear, "end", pageName);
await this.world.sleep(100);
} else {
throw new Error("Return date shouldn't be more than 3 years in advance");
}
} else {
throw new Error("Start date shouldn't be past from the return date");
}
} else {
throw new Error("Start date shouldn't be today or previous");
}
}
/**
* Set Adults
* @param {String} locator - css or xpath selector element
*/
async setAdults(locator) {
if (this.world.debug) console.log("setAdults");
await this.world.sleep(50);
const el = await this.world.helper.findElement(locator);
await this.world.helper.scrollToElement(el);
await el.click();
await this.world.sleep(50);
}
/**
* Set Traveller
* @param {Number} noOfAdults - # of adults
* @param {Number} noOfChildren - # of children
*/
async setTraveller(noOfAdults, noOfChildren = 0) {
if (this.world.debug) console.log("setTraveller");
const adults = parseInt(noOfAdults);
const children = parseInt(noOfChildren);
let el;
const {
travellerSummaryInput, travellerLayerDiv, adultCountDiv, adultPlusButton, adultMinusButton, travellerApplyButton,
} = this.elements;
if (adults > 0 && adults <= 4) {
await this.world.helper.waitFor(travellerSummaryInput);
el = await this.world.helper.findElement(travellerSummaryInput);
await el.click();
await this.world.helper.waitFor(travellerLayerDiv);
let adultCount = await this.world.helper.getElementText(adultCountDiv);
if (this.world.debug) console.log(`${adultCount}`);
while (adults > adultCount) {
await this.setAdults(adultPlusButton);
adultCount = await this.world.helper.getElementText(adultCountDiv);
if (this.world.debug) console.log(`${adultCount}`);
}
while (adults < adultCount) {
await this.setAdults(adultMinusButton);
adultCount = await this.world.helper.getElementText(adultCountDiv);
if (this.world.debug) console.log(`${adultCount}`);
}
await this.world.sleep(100);
await this.world.helper.waitFor(travellerApplyButton);
el = await this.world.helper.findElement(travellerApplyButton);
await el.click();
await this.world.sleep(500);
} else {
throw new Error("No of adults should be within 1 to 4");
}
if (children > 0) {
// TODO: Do nothing now :)
}
}
/**
* Check and Click Cookie Box
*/
async checkAndClickCookieBox() {
if (this.world.debug) console.log("checkAndClickCookieBox");
const { cookieButton } = this.elements;
await this.world.sleep(1000);
const els = await this.world.helper.findElements(cookieButton);
if (els[0]) {
await this.clickButton(cookieButton, "", false);
}
await this.world.sleep(500);
}
/**
* Fill Search Offer Form
* @param {Object} data - form data
*/
async fillSearchOfferForm(data) {
if (this.world.debug) console.log("fillSearchOfferForm");
await this.checkAndClickCookieBox();
if (data.destination) {
await this.selectDestination(data.destination);
}
if (data.startDate && data.returnDate) {
const {
startDateDiv, nextStartMonthSpan, selectedStartMonthYearSpan, nextReturnMonthSpan, selectedReturnMonthYearSpan,
} = this.elements;
await this.setDateRange(data.startDate, data.returnDate, startDateDiv, nextStartMonthSpan, selectedStartMonthYearSpan, nextReturnMonthSpan, selectedReturnMonthYearSpan);
}
if (data.noOfAdults) {
await this.setTraveller(data.noOfAdults);
}
if (data.clickButton) {
const { searchOffersBtn, hotelSelectionPageFirstResMediaDiv } = this.elements;
await this.clickButton(searchOffersBtn, hotelSelectionPageFirstResMediaDiv);
}
}
/**
* Check Page Name
* @param {String} expectedTitle - name of the page
*/
async checkPageName(expectedTitle) {
if (this.world.debug) console.log("checkPageName");
const { currentPageNameSpan } = this.elements;
await this.world.helper.waitFor(currentPageNameSpan);
let actualTitle = await this.world.helper.getElementText(currentPageNameSpan);
actualTitle = actualTitle.replace(". ", "");
this.world.expect(actualTitle).to.equal(expectedTitle);
}
/**
* Change selections and find the best hotel
* @param {Object} data - form data
*/
async findBestHotel(data) {
if (this.world.debug) console.log("findBestHotel");
await this.checkAndClickCookieBox();
const { hotelSelectionPageFirstResMediaDiv, hotelSelectionPageLoaderSection, directFlightHotelInput } = this.elements;
if (data.startDate && data.returnDate) {
const {
startDateHotelDiv, nextStartMonthHotelSpan, selectedStartMonthYearHotelSpan, nextReturnMonthHotelSpan, selectedReturnMonthYearHotelSpan,
} = this.elements;
await this.world.helper.waitFor(hotelSelectionPageLoaderSection);
await this.setDateRange(data.startDate, data.returnDate, startDateHotelDiv, nextStartMonthHotelSpan, selectedStartMonthYearHotelSpan, nextReturnMonthHotelSpan, selectedReturnMonthYearHotelSpan, "Hotel");
}
if (data.clickButton) {
const { searchOffersBtn } = this.elements;
await this.world.helper.waitFor(hotelSelectionPageLoaderSection);
await this.clickButton(searchOffersBtn, hotelSelectionPageFirstResMediaDiv, true, directFlightHotelInput);
}
if (data.starRating) {
const { starRatingCatInput } = this.elements;
const number = (data.starRating === "beliebig") ? -1 : Math.round(parseInt(data.starRating) / 2);
const starRateInput = starRatingCatInput.replace("{txt}", number);
await this.world.helper.waitFor(hotelSelectionPageLoaderSection);
await this.clickButton(starRateInput, hotelSelectionPageFirstResMediaDiv, true, directFlightHotelInput);
await this.world.sleep(1000);
}
if (data.customerReview) {
const { customerReviewSvg, priceRangeDiv } = this.elements;
const custReviewSvg = customerReviewSvg.replace("{txt}", data.customerReview);
await this.world.helper.waitFor(hotelSelectionPageLoaderSection);
await this.clickButton(custReviewSvg, hotelSelectionPageFirstResMediaDiv, true, priceRangeDiv);
await this.world.sleep(1000);
}
if (data.sortBy) {
const { hotelsortingSelect } = this.elements;
const sortingSelect = hotelsortingSelect.replace("{txt}", data.sortBy.replace(" ", "_"));
await this.world.helper.waitFor(hotelSelectionPageLoaderSection);
await this.clickButton(sortingSelect, hotelSelectionPageFirstResMediaDiv);
await this.world.sleep(1000);
}
await this.world.sleep(2000);
}
/**
* Verify Sorted
* @param {String} expectedSortedBy - sorted by
*/
async verifySorted(expectedSortedBy) {
if (this.world.debug) console.log("verifySorted");
if (expectedSortedBy) {
const { priceBoxStrong, hotelSelectionPageLoaderSection } = this.elements;
await this.world.helper.waitFor(hotelSelectionPageLoaderSection);
let actualSort = [];
await this.world.helper.waitFor(priceBoxStrong);
const priceElements = await this.world.helper.findElements(priceBoxStrong);
if (priceElements) {
actualSort = await Promise.all(priceElements.map(async function (priceElement) {
const priceText = await priceElement.getText();
const price = parseInt(priceText.match(/([0-9])+/g).join(""));
return price;
}));
}
const expectedSort = actualSort;
expectedSort.sort(function (a, b) { return b - a; });
this.world.expect(actualSort[0]).to.equal(expectedSort[0]);
await this.world.sleep(100);
}
}
/**
* Select The Most Expensive Hotel
*/
async selectMostExpensiveHotel() {
if (this.world.debug) console.log("selectMostExpensiveHotel");
const {
aboutOffersDiv, hotelDetailsPageFirstOfferSpan, hotelDetailsPageAjaxLoadSection, hotelListHeadSection,
} = this.elements;
await this.clickButton(aboutOffersDiv, "", true, hotelListHeadSection);
await this.world.switchTab(1);
await this.world.helper.waitFor(hotelDetailsPageAjaxLoadSection);
await this.world.helper.waitFor(hotelDetailsPageFirstOfferSpan);
await this.world.sleep(2000);
}
/**
* Find Best Fit
* @param {Object} data - form data
*/
async findBestFit(data) {
if (this.world.debug) console.log("findBestFit");
await this.world.sleep(1000);
await this.checkAndClickCookieBox();
const { hotelDetailsPageAjaxLoadSection, skeletonOffersSection, offerFilterDiv } = this.elements;
await this.world.helper.waitFor(hotelDetailsPageAjaxLoadSection);
const element = await this.world.helper.findElement(offerFilterDiv);
await this.world.helper.scrollToElement(element);
await this.world.sleep(1000);
this.dataInputFindBestFit = data;
if (data.departureTime) {
const { departureTimeRangeDiv } = this.elements;
const xOffset = this.generateOffset(data.departureTime);
if (xOffset > 0) {
await this.world.helper.moveSlider(departureTimeRangeDiv, xOffset, 0);
await this.world.helper.waitFor(skeletonOffersSection);
await this.world.sleep(1000);
}
}
if (data.arrivalTime) {
const { arrivalTimeRangeDiv } = this.elements;
const xOffset = this.generateOffset(data.arrivalTime, 24);
if (xOffset > 0) {
await this.world.helper.moveSlider(arrivalTimeRangeDiv, -xOffset, 0);
await this.world.helper.waitFor(skeletonOffersSection);
await this.world.sleep(1000);
}
}
if (data.returnDepartureTime) {
const { returnDepartureTimeRangeDiv } = this.elements;
const xOffset = this.generateOffset(data.returnDepartureTime);
if (xOffset > 0) {
await this.world.helper.moveSlider(returnDepartureTimeRangeDiv, xOffset, 0);
await this.world.helper.waitFor(skeletonOffersSection);
await this.world.sleep(1000);
}
}
if (data.returnArrivalTime) {
const { returnArrivalTimeRangeDiv } = this.elements;
const xOffset = this.generateOffset(data.returnArrivalTime, 24);
if (xOffset > 0) {
await this.world.helper.moveSlider(returnArrivalTimeRangeDiv, -xOffset, 0);
await this.world.helper.waitFor(skeletonOffersSection);
await this.world.sleep(1000);
}
}
if (data.dateOfArrival) {
const { dateOfArrivalLabel } = this.elements;
await this.world.sleep(2000);
if (data.dateOfArrival) {
let date = data.dateOfArrival.split("-");
date = `${date[2]}.${date[1]}.${date[0]}`;
let ids;
const elements = await this.world.helper.findElements(dateOfArrivalLabel);
if (elements) {
ids = await Promise.all(elements.map(async function (el) {
const text = await el.getText();
let isMatched = text.match(new RegExp(date, "g"));
isMatched = (isMatched) ? isMatched.toString() : isMatched;
if (isMatched === date) {
const id = await el.getAttribute("for");
return id;
}
return null;
}));
}
ids = ids.filter((i) => i); // removing null
if (this.world.debug) console.dir(ids);
const eId = (ids) ? `#${ids[0]}` : null;
if (eId) {
await this.clickButton(eId, skeletonOffersSection, false);
}
await this.world.sleep(1000);
} else {
throw new Error("Date of arrival shouldn't be empty");
}
}
await this.world.sleep(2000);
}
/**
* Count Direct Flights
* @param {Number} count
*/
async countDirectFlights(count) {
if (this.world.debug) console.log("countDirectFlights");
const {
hotelDetailsPageDurationDeparture, hotelDetailsPageDurationReturn, hotelDetailsPageAjaxLoadSection, hotelDetailsPageHotelNameDiv,
} = this.elements;
let departureDirectFlights; let returnDirectFlights;
await this.world.helper.waitFor(hotelDetailsPageAjaxLoadSection);
await this.world.helper.waitFor(hotelDetailsPageHotelNameDiv);
await this.world.sleep(1000);
await this.world.helper.waitFor(hotelDetailsPageDurationDeparture);
let flightElements = await this.world.helper.findElements(hotelDetailsPageDurationDeparture);
if (flightElements) {
departureDirectFlights = await Promise.all(flightElements.map(async function (flightElement) {
const flightText = await flightElement.getText();
const flight = flightText.match(/Direktflug/g);
return flight;
}));
}
departureDirectFlights = departureDirectFlights.filter((i) => i); // removing null
if (this.world.debug) console.log(departureDirectFlights.length);
await this.world.helper.waitFor(hotelDetailsPageDurationReturn);
flightElements = await this.world.helper.findElements(hotelDetailsPageDurationReturn);
if (flightElements) {
returnDirectFlights = await Promise.all(flightElements.map(async function (flightElement) {
const flightText = await flightElement.getText();
const flight = flightText.match(/Direktflug/g);
return flight;
}));
}
returnDirectFlights = returnDirectFlights.filter((i) => i); // removing null
if (this.world.debug) console.log(returnDirectFlights.length);
const totalDirectFlights = departureDirectFlights.length > returnDirectFlights.length ? returnDirectFlights.length : departureDirectFlights.length;
if (this.world.debug) console.log(totalDirectFlights);
try {
this.world.expect(totalDirectFlights).to.be.above(count);
} catch (e) {
await this.world.helper.takeScreenshot();
} finally {
await this.world.attach(`Total direct flights: ${totalDirectFlights}`);
}
await this.world.sleep(2000);
}
/**
* Verify Flight Time Of First Result
*/
async verifyFlightTimeOfFirstResult() {
if (this.world.debug) console.log("verifyFlightTimeOfFirstResult");
const {
hotelDetailsPageDurationDepartureTime, hotelDetailsPageDurationReturnTime, hotelDetailsPageAjaxLoadSection, hotelDetailsPageHotelNameDiv,
} = this.elements;
let departureTimeRange; let returnTimeRange;
await this.world.helper.waitFor(hotelDetailsPageAjaxLoadSection);
await this.world.helper.waitFor(hotelDetailsPageHotelNameDiv);
await this.world.sleep(1000);
await this.world.helper.waitFor(hotelDetailsPageDurationDepartureTime);
departureTimeRange = await this.world.helper.getElementText(hotelDetailsPageDurationDepartureTime);
departureTimeRange = departureTimeRange.match(/[+-]?([0-9]*[:])?[0-9]+/g);
if (this.world.debug) console.dir(departureTimeRange);
let actual = this.checkRange(departureTimeRange[0], departureTimeRange[1], this.dataInputFindBestFit.departureTime, this.dataInputFindBestFit.arrivalTime);
try {
this.world.expect(actual).to.equal(true);
} catch (e) {
await this.world.attach(`Departure time range (${departureTimeRange[0]} - ${departureTimeRange[1]}) doesn't fall within the desired time range`);
await this.world.helper.takeScreenshot();
}
await this.world.helper.waitFor(hotelDetailsPageDurationReturnTime);
returnTimeRange = await this.world.helper.getElementText(hotelDetailsPageDurationReturnTime);
returnTimeRange = returnTimeRange.match(/[+-]?([0-9]*[:])?[0-9]+/g);
if (this.world.debug) console.dir(returnTimeRange);
actual = this.checkRange(returnTimeRange[0], returnTimeRange[1], this.dataInputFindBestFit.returnDepartureTime, this.dataInputFindBestFit.returnArrivalTime);
try {
this.world.expect(actual).to.equal(true);
} catch (e) {
await this.world.attach(`Return time range (${returnTimeRange[0]} - ${returnTimeRange[1]}) doesn't fall within the desired time range`);
await this.world.helper.takeScreenshot();
}
await this.world.sleep(2000);
}
/**
* Select The First Offer
*/
async selectFirstOffer() {
if (this.world.debug) console.log("selectFirstOffer");
const {
hotelDetailsPageHotelNameDiv, hotelDetailsPageFirstOfferSpan, bookingPageHotelNameSpan, offerFilterDiv,
} = this.elements;
await this.world.helper.waitFor(hotelDetailsPageHotelNameDiv);
this.expectedHotelName = await this.world.helper.getElementText(hotelDetailsPageHotelNameDiv);
if (this.world.debug) console.log(this.expectedHotelName);
await this.clickButton(hotelDetailsPageFirstOfferSpan, "", true, offerFilterDiv);
await this.world.switchTab(2);
await this.world.helper.waitFor(bookingPageHotelNameSpan);
await this.world.sleep(2000);
}
/**
* Verify the name of the hotel
*/
async verifyHotelName() {
if (this.world.debug) console.log("verifyHotelName");
if (this.expectedHotelName) {
const { bookingPageHotelNameSpan } = this.elements;
await this.world.helper.waitFor(bookingPageHotelNameSpan);
let actualHotelName = await this.world.helper.getElementText(bookingPageHotelNameSpan);
actualHotelName = actualHotelName.replace("Hotelbeschreibung", "").trim();
if (this.world.debug) console.log(actualHotelName);
this.world.expect(actualHotelName).to.equal(this.expectedHotelName);
await this.world.sleep(2000);
} else {
throw new Error("Couldn't find the hotel name");
}
}
}
module.exports = UrlaubPage;