Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Dependency directory
node_modules
built/**/*.map
#VSCode files
.vscode/*
features/step_definitions/*.js
features/pages/*.js
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
# SDET-Test-JS
# SDET-Test-JS
Clone the repo
run `npm install`
run `tsc --w`
Run `npm test` to run the scenarios

NOTE: Reporting & Error handling are not working
25 changes: 15 additions & 10 deletions features/VirginHolidaysTest.feature
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
Feature:
@homepage
Feature:Homepage

As a User
I want to check the homepage functionalities
So that I can book my holidays easily

@holiday
Scenario: Add a holiday to hotlist
Given I am on virgin holidays home page
And I do a holiday search
When I add a holiday to a hotlist
Then I can see that a holiday added to the hotlist on top of the page

Scenario: Search hotel options
Given I am on virgin holidays
When I do a hotel search
And I proceed to hotel options page
Then I ca see my board basis


Then I can see that the holiday added to the hotlist on top of the page

@hotel
Scenario: Search hotel options
Given I am on virgin holidays home page
When I do a hotel search
And I proceed to the first hotel options page
Then I can see my board basis
57 changes: 57 additions & 0 deletions features/hooks/ScenarioHook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var _this = this;
Object.defineProperty(exports, "__esModule", { value: true });
var cucumber_1 = require("cucumber");
var basePage_1 = require("../pages/basePage");
var basepage = new basePage_1.BasePage();
var CucumberReportExtension_1 = require("../../reporting/CucumberReportExtension");
var jsonReports = process.cwd() + "/reports/json";
cucumber_1.setDefaultTimeout(10000);
cucumber_1.BeforeAll(function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
CucumberReportExtension_1.CucumberReportExtension.CreateReportFile(jsonReports);
console.log("Before hook executed");
return [2];
});
}); });
cucumber_1.Before(function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
console.log("Before hook executed");
return [2];
});
}); });
34 changes: 34 additions & 0 deletions features/hooks/ScenarioHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { After, AfterAll, Before, BeforeAll, setDefaultTimeout, Status } from "cucumber";
import { Browser } from "selenium-webdriver";
import {BasePage} from "../pages/basePage";
import { driver } from "../pages/basePage";

const basepage: BasePage = new BasePage();
// import { config } from "../features/step_definitions/config";
import { CucumberReportExtension } from "../../reporting/CucumberReportExtension";

const jsonReports = process.cwd() + "/reports/json";

setDefaultTimeout(10000);

BeforeAll(async () => {
CucumberReportExtension.CreateReportFile(jsonReports);
console.log("Before hook executed");
});

Before(async () => {
console.log("Before hook executed");
});

// After(async function(scenario) {
// if (scenario.result.status === Status.FAILED) {
// console.log("After hook executed changed");
// // // screenShot is a base-64 encoded PNG
// // const screenShot = await this.driver.takeScreenshot();
// // this.attach(screenShot, "image/png");
// }
// });
// AfterAll(async (scenario) => {
// console.log("After hook executed changed");
// // return await driver.quit();
// });
31 changes: 31 additions & 0 deletions features/pages/HomePage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var basePage_1 = require("../pages/basePage");
var BASEURL = "https://www.virginholidays.co.uk/";
var SUBMITBUTTON = "#search-panel > div > div > div.sp-tab.sp-selected > form > div.sp-container > div.sp-submit-container > button";
var HOLIDAYTAB = "#search-panel-nav > li:nth-child(1) > button";
var HOTELTAB = "#search-panel-nav > li:nth-child(6) > button";
var SEARCHHEADER = "#app-header";
var WAITTIME = 20000;
var basepage = new basePage_1.BasePage();
var HomePage = (function () {
function HomePage() {
}
HomePage.prototype.goToHomeURL = function () {
return basepage.getURL(BASEURL);
};
HomePage.prototype.getSubmitButton = function () {
return basepage.getElementByCss(SUBMITBUTTON);
};
HomePage.prototype.getHolidayTab = function () {
return basepage.getElementByCss(HOLIDAYTAB);
};
HomePage.prototype.getHotelTab = function () {
return basepage.getElementByCss(HOTELTAB);
};
HomePage.prototype.isSearchHeaderLocated = function () {
return basepage.waitUntilElementLocated(SEARCHHEADER, WAITTIME);
};
return HomePage;
}());
exports.HomePage = HomePage;
35 changes: 35 additions & 0 deletions features/pages/HomePage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {Builder, By, Key, until } from "selenium-webdriver";
import {BasePage} from "../pages/basePage";

const BASEURL = "https://www.virginholidays.co.uk/";
const SUBMITBUTTON = "#search-panel > div > div > div.sp-tab.sp-selected > form > div.sp-container > div.sp-submit-container > button";
const HOLIDAYTAB = "#search-panel-nav > li:nth-child(1) > button";
const HOTELTAB = "#search-panel-nav > li:nth-child(6) > button";
const SEARCHHEADER = "#app-header";
const WAITTIME = 20000;

const basepage: BasePage = new BasePage();

export class HomePage {

public goToHomeURL() {
return basepage.getURL(BASEURL);
}

public getSubmitButton() {
return basepage.getElementByCss(SUBMITBUTTON);
}

public getHolidayTab() {
return basepage.getElementByCss(HOLIDAYTAB);
}

public getHotelTab() {
return basepage.getElementByCss(HOTELTAB);
}

public isSearchHeaderLocated() {
return basepage.waitUntilElementLocated(SEARCHHEADER, WAITTIME);
}

}
16 changes: 16 additions & 0 deletions features/pages/HotListPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {BasePage} from "../pages/basePage";
const basepage: BasePage = new BasePage();
const WAITTIME = 20000;

const FIRSTHOLIDAYITEMHEADING = "section > div:nth-child(1) > div > div.card-block > h4";

export class HotListPage {

public getFirstHolidayItemHeading() {
return basepage.getTextByCss(FIRSTHOLIDAYITEMHEADING);
}

public isFirstHolidayItemVisible() {
return basepage.waitUntilElementLocated(FIRSTHOLIDAYITEMHEADING, WAITTIME);
}
}
57 changes: 57 additions & 0 deletions features/pages/basePage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {Builder, By , Key , until } from "selenium-webdriver";
export const driver = new Builder().forBrowser("chrome").build();

export class BasePage {

public getURL(url: string) {
return driver.get(url);
}

public resizeBrowser(width: number, height: number) {
return driver.manage().window().setSize(width, height);
}
public waitUntilElementLocated(locator: string, time: number) {
return driver.wait(until.elementLocated(By.css(locator)), time);
}

public waitUntilElementVisible(locator: string, time: number) {
return driver.wait(until.elementIsVisible(driver.findElement(By.css(locator))), time);
}

public waitForPageTitle(title: string) {
return driver.wait(until.titleContains(title));
}

public getTextByCss(locator: string) {
return driver.findElement(By.css(locator)).getText();
}

public getElementByCss(locator: string) {
return driver.findElement(By.css(locator));
}

public getElementById(locator: string) {
return driver.findElement(By.id(locator));
}

public getElementByXpath(locator: string) {
return driver.findElement(By.xpath(locator));
}

public getElementByClass(locator: string) {
return driver.findElement(By.className(locator));
}

public scrollDown() {
return driver.executeScript("window.scrollTo(0,600)");
}

public scrollUp() {
return driver.executeScript("window.scrollTo(0,-600)");
}

public closeBrowser() {
return driver.quit();
}

}
39 changes: 39 additions & 0 deletions features/pages/holidaySearchLandingPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {BasePage} from "../pages/basePage";
const basepage: BasePage = new BasePage();

const FIRSTHOLIDAYITEM = "#search-results > article:nth-child(1) > div.card-content > div.card-action > "
+ "div.vhols-hotlist > a > span.hbc-add-content";
const FIRSTHOLIDAYITEMADDHOTLISTLINK = "#search-results > article:nth-child(1) > div.card-content > "
+ "div.card-action > div.vhols-hotlist > a ";
const FIRSTHOLIDAYITEMHEADING = "#search-results > article:nth-child(1) > div.card-content > div.card-detail > header > h2";
const FIRSTHOLIDAYITEMREMOVEHOTLISTLINK = "#search-results > article:nth-child(1) > div.card-content > "
+ "div.card-action > div.vhols-hotlist > a > span.hbc-remove-content-md";
const HOTLISTLINK = "li.mvhtr-entry.mvhtr-hotlist > a ";
const WAITTIME = 20000;

export class HolidaySearchLandingPage {
public getFirstHolidayItem() {
return basepage.getElementByCss(FIRSTHOLIDAYITEM);
}

public isFirstHolidayItemVisible() {
return basepage.waitUntilElementLocated(FIRSTHOLIDAYITEM, WAITTIME);
}

public getFirstHolidayItemHeading() {
return basepage.getTextByCss(FIRSTHOLIDAYITEMHEADING);
}

public getFirstHolidayItemAddToHotlistLink() {
return basepage.getElementByCss(FIRSTHOLIDAYITEMADDHOTLISTLINK);
}

public getHotListLiink() {
return basepage.getElementByCss(HOTLISTLINK);
}

public isFirstHolidayItemRemoveHotlistLinkVisible() {
return basepage.waitUntilElementVisible(FIRSTHOLIDAYITEMREMOVEHOTLISTLINK, WAITTIME);
}

}
25 changes: 25 additions & 0 deletions features/pages/hotelListPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {BasePage} from "./basePage";
const basepage: BasePage = new BasePage();
const FIRSTHOTELITEM = "div.container.application-contents > div > div";
const FIRSTHOTELITEMBOARDBASISINFO = "div.panel-body.ecms-content > div > h2";
const FIRSTHOTELITEMHEADING = "div:nth-child(1) > h1";
const WAITTIME = 20000;

export class HotelListPage {
public isFirstHotelItemVisible() {
return basepage.waitUntilElementVisible(FIRSTHOTELITEM, WAITTIME);
}

public getFirstHolidayItemHeading() {
return basepage.getTextByCss(FIRSTHOTELITEMHEADING);
}

public getFirstHolidayItemBoardBasis() {
return basepage.getElementByCss(FIRSTHOTELITEMBOARDBASISINFO);
}

public isFirstHolidayItemBoardBasis() {
return basepage.waitUntilElementVisible(FIRSTHOTELITEMBOARDBASISINFO, WAITTIME);
}

}
21 changes: 21 additions & 0 deletions features/pages/hotelSearchLandingPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {BasePage} from "../pages/basePage";
const basepage: BasePage = new BasePage();
const FIRSTHOTELITEM = "#search-results > article:nth-child(1)";
const FIRSTHOTELITEMCONTINUEBUTTON = "#search-results > article:nth-child(1) > div.card-content > div.card-action > a";
const FIRSTHOTELITEMHEADING = "#search-results > article:nth-child(1) > div.card-content > div.card-detail > header > h2";
const WAITTIME = 20000;

export class HotelSearchLandingPage {
public isFirstHotelItemVisible() {
return basepage.waitUntilElementLocated(FIRSTHOTELITEM, WAITTIME);
}

public getFirstHolidayItemHeading() {
return basepage.getTextByCss(FIRSTHOTELITEMHEADING);
}

public getFirstHotelItemContinueButton() {
return basepage.getElementByCss(FIRSTHOTELITEMCONTINUEBUTTON);
}

}
Loading