diff --git a/src/main/java/selenium/lissi/LissiHomePage.java b/src/main/java/selenium/lissi/LissiHomePage.java new file mode 100644 index 0000000000000000000000000000000000000000..1dcd1f196275a7c6bbd1fe0ce41378b1cf01c52c --- /dev/null +++ b/src/main/java/selenium/lissi/LissiHomePage.java @@ -0,0 +1,4 @@ +package selenium.lissi; + +public class LissiHomePage { +} diff --git a/src/main/java/selenium/utils/Browser.java b/src/main/java/selenium/utils/Browser.java new file mode 100644 index 0000000000000000000000000000000000000000..1422df79f6f03015cc542e2fbbcfc9c305a67fcf --- /dev/null +++ b/src/main/java/selenium/utils/Browser.java @@ -0,0 +1,348 @@ +package selenium.utils; + +import core.JsonUtils; +import org.apache.commons.io.FileUtils; +import org.junit.Assert; +import org.openqa.selenium.*; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import java.io.*; +import java.net.URL; +import java.net.URLDecoder; +import java.nio.channels.FileChannel; +import java.time.Duration; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + + +public class Browser { + + public static WebDriver driver; + public static WebDriverWait wait; + + public static final String DOWNLOADS_PATH = JsonUtils.getProjectLocation(); + + public static void initChrome() { + + String driverLocation = JsonUtils.getProjectLocation() + "/drivers/chromedriver"; + + System.setProperty("webdriver.chrome.driver", driverLocation); + ChromeOptions options = new ChromeOptions(); + + options.addArguments("--no-sandbox"); + options.addArguments("--disable-dev-shm-usage"); + options.setExperimentalOption("useAutomationExtension", false); + + Map<String, Object> prefs = new HashMap<String, Object>(); + prefs.put("download.default_directory", DOWNLOADS_PATH); + options.setExperimentalOption("prefs", prefs); + + + options.setHeadless(JsonUtils.getIsHeadless()); + + if(JsonUtils.getIsHeadless()){ + options.addArguments("--window-size=1920,1080"); + } + + options.addArguments("--no-experiments"); + options.addArguments("--disable-translate"); + options.addArguments("--no-default-browser-check"); + options.addArguments("--clear-token-service"); + options.addArguments("--disable-default-apps"); + options.addArguments("--enable-logging"); + options.addArguments("--dns-prefetch-disable"); + + + Map<String, Object> deviceMetrics = new HashMap<>(); + Map<String, Object> mobileEmulation = new HashMap<>(); + + switch (JsonUtils.getDeviceType()){ + case "PC": + options.addArguments("--start-maximized"); + break; + case "Mobile": + deviceMetrics.put("width", 375); + deviceMetrics.put("height", 812); + deviceMetrics.put("pixelRatio", 3.0); + + options.addArguments("--start-maximized"); + + mobileEmulation.put("deviceMetrics", deviceMetrics); + mobileEmulation.put("userAgent", "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/78.0.3904.84 Mobile/15E148 Safari/605.1"); + //iPhoneX + //Software Layout engine Software Type Popularity + //Chrome 78 Webkit Web Browser Common + options.setExperimentalOption("mobileEmulation", mobileEmulation); + break; + case "Tablet": + deviceMetrics.put("width", 768); + deviceMetrics.put("height", 1024); + deviceMetrics.put("pixelRatio", 2.0); + + mobileEmulation.put("deviceMetrics", deviceMetrics); + mobileEmulation.put("userAgent", "Mozilla/5.0 (iPad; CPU OS 12_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/75.0.3770.103 Mobile/15E148 Safari/605.1"); + //Software Layout engine Software Type Popularity + //Chrome 77 Webkit Web Browser Common + options.setExperimentalOption("mobileEmulation", mobileEmulation); + break; + } + + options.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.ACCEPT); + + try{ + driver = new ChromeDriver(options); + }catch(WebDriverException ex){ + System.out.println("Info: Failed to start Chrome driver..." + ex.getMessage()); + + try { + Thread.sleep(10_000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + driver = new ChromeDriver(options); + } + + wait = new WebDriverWait(driver, Duration.ofSeconds(10)); + } + + public static void goTo(String url) { + Browser.driver.get(url); + } + + public static String getUrl() throws Throwable { + String url = Browser.driver.getCurrentUrl(); + return url; + } + + /** + + * This function will take screenshot + + * @param webdriver + + * @param fileWithPath + + * @throws Exception + + */ + + public static void takeSnapShot(WebDriver webdriver,String fileWithPath) throws Exception{ + + //Convert web driver object to TakeScreenshot + + TakesScreenshot scrShot =((TakesScreenshot)webdriver); + + //Call getScreenshotAs method to create image file + + File SrcFile=scrShot.getScreenshotAs(OutputType.FILE); + + //Move image file to new destination + + File DestFile=new File(fileWithPath); + + //Copy file at destination + + FileUtils.copyFile(SrcFile, DestFile); + + } + + public static Map<String, String> splitUrl(URL url) throws UnsupportedEncodingException { + Map<String, String> query_pairs = new LinkedHashMap<String, String>(); + String query = url.getQuery(); + String[] pairs = query.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf("="); + query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8")); + } + return query_pairs; + } + + /** + * Validate if the page title have the expected value + * + * @param expectedPageTitle the expected page title + */ + public static void validatePageTitle(String expectedPageTitle) { + try{ + + wait.until(ExpectedConditions.titleIs(expectedPageTitle)); + }catch(TimeoutException ex){ + System.out.println("Info: Expected ignored here: Page title: " + driver.getTitle()); + + driver.navigate().refresh(); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + Assert.assertTrue("The title of the page was not the expected one. \nExpected: " + expectedPageTitle + "\nActual: " + driver.getTitle(), driver.getTitle().equals(expectedPageTitle)); + } + } + + /** + * Validate if an element is displayed or not + * + * @param locator + * @param shouldBeDisplayed + */ + public static void validateIfElementIsDisplayed(By locator, boolean shouldBeDisplayed) { + + if (shouldBeDisplayed) { + + try{ + wait.until(ExpectedConditions.visibilityOfElementLocated(locator)); + }catch(TimeoutException ex){ + wait.until(ExpectedConditions.visibilityOfElementLocated(locator)); + } + } else { + wait.until(ExpectedConditions.invisibilityOfElementLocated(locator)); + return; + } + + WebElement elementToCheck = driver.findElement(locator); + boolean isDisplayed = false; + + try { + isDisplayed = elementToCheck.isDisplayed(); + } catch (StaleElementReferenceException ex) { + + if (shouldBeDisplayed) { + wait.until(ExpectedConditions.visibilityOfElementLocated(locator)); + + isDisplayed = driver.findElement(locator).isDisplayed(); + Assert.assertEquals(shouldBeDisplayed, isDisplayed); + } else { + wait.until(ExpectedConditions.invisibilityOfElementLocated(locator)); + return; + } + } + } + + /** + * Validate if an element is enabled or not + * + * @param locator + * @param shouldBeEnabled + */ + public static void validateElementIsEnabled(By locator, boolean shouldBeEnabled) { + + WebElement elementToCheck = wait.until(ExpectedConditions.visibilityOfElementLocated(locator)); + + boolean isEnabled = elementToCheck.isEnabled(); + + Assert.assertEquals("Element with locator: " + locator.toString() + " was not enabled/disabled when it was expected. ", shouldBeEnabled, isEnabled); + } + + public void validateLinkTextAndHref(String expectedText, String expectedHref) throws Throwable { + By link = By.xpath("//a[text()='" + expectedText + "' and @href='" + expectedHref + "']"); + WebElement actualLink = wait.until(ExpectedConditions.refreshed(ExpectedConditions.elementToBeClickable(link))); + + String actualText = actualLink.getText(); + String actualHref = actualLink.getAttribute("href"); + + if (expectedHref.startsWith("http")) { + expectedHref += "/"; + } + + if (expectedHref.startsWith("#")) { + expectedHref = getUrl().concat(expectedHref); + } + + Assert.assertEquals("There was no link with text: ", expectedText, actualText.trim()); + Assert.assertEquals("There was no link with href: ", expectedHref, actualHref.trim()); + } + + public void validateElementWithPlaceholderExists(String expectedPlaceholder) { + By element = By.xpath("//*[@placeholder='" + expectedPlaceholder + "']"); + wait.until(ExpectedConditions.visibilityOfElementLocated(element)); + + String actualPlaceholder = driver.findElement(element).getAttribute("placeholder"); + + Assert.assertEquals("There was no element with placeholder: " + expectedPlaceholder + "presented on the page", expectedPlaceholder, actualPlaceholder); + } + + public static void tearDown() throws InterruptedException, IOException { + driver.quit(); + } + + public static void deleteFilesFromProfileFolder() throws IOException { + File profileDir = new File(JsonUtils.getProjectLocation() + "/Profile"); + + for (File currentFile : profileDir.listFiles()) { + + if (!currentFile.getName().equals("Default")) { + + if (currentFile.isDirectory()) { + FileUtils.deleteDirectory(currentFile); + } else { + currentFile.delete(); + } + } + } + } + + public static void copyFile(File sourceFile, File destFile) throws IOException { + if(!destFile.exists()) { + destFile.createNewFile(); + } + + FileChannel origin = null; + FileChannel destination = null; + try { + origin = new FileInputStream(sourceFile).getChannel(); + destination = new FileOutputStream(destFile).getChannel(); + + long count = 0; + long size = origin.size(); + while((count += destination.transferFrom(origin, count, size-count))<size); + } + finally { + if(origin != null) { + origin.close(); + } + if(destination != null) { + destination.close(); + } + } + } + + public void setAttribute(WebElement element, String attName, String attValue) { + JavascriptExecutor js = (JavascriptExecutor) driver; + js.executeScript("arguments[0].setAttribute(arguments[1], arguments[2]);", + element, attName, attValue); + } + + public void populateFieldWithPlaceholderWithValue(String placeholder, String value){ + WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@placeholder='" + placeholder + "']"))); + + element.clear(); + element.sendKeys(value); + } + + public void scrollToTheBottomOfThePage(){ + + try { + long lastHeight = (long) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight"); + + while (true) { + ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);"); + Thread.sleep(2000); + + long newHeight = (long) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight"); + if (newHeight == lastHeight) { + break; + } + lastHeight = newHeight; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/selenium/utils/ChangeWindow.java b/src/main/java/selenium/utils/ChangeWindow.java new file mode 100644 index 0000000000000000000000000000000000000000..3aa8fb6289c234575e71feb92896af6631ecb5da --- /dev/null +++ b/src/main/java/selenium/utils/ChangeWindow.java @@ -0,0 +1,17 @@ +package selenium.utils; + +import java.util.Set; + +public class ChangeWindow { + + public static void handleMultipleWindows(String windowTitle) { + Set<String> windows = Browser.driver.getWindowHandles(); + + for (String window : windows) { + Browser.driver.switchTo().window(window); + if (Browser.driver.getTitle().contains(windowTitle)) { + return; + } + } + } +} diff --git a/src/test/java/api/test/core/SeleniumStepDefinitions.java b/src/test/java/api/test/core/SeleniumStepDefinitions.java new file mode 100644 index 0000000000000000000000000000000000000000..1df9cfdab671cf586773ff544b8f7c9ead1d4b70 --- /dev/null +++ b/src/test/java/api/test/core/SeleniumStepDefinitions.java @@ -0,0 +1,52 @@ +package api.test.core; + +import cucumber.api.java.en.And; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.openqa.selenium.Dimension; +import selenium.utils.*; + + +public class SeleniumStepDefinitions extends BaseStepDefinitions { + private static final Logger logger = LogManager.getLogger(SeleniumStepDefinitions.class.getSimpleName()); + + @And("^I close the browser$") + public void iCloseTheBrowser() throws Throwable { + Browser.driver.manage().deleteAllCookies(); + Browser.tearDown(); + logger.debug("BROWSER CLOSED"); + } + + /** + * + * @param browser - acceptable values are Chrome, HTMLUnitDriver + * @throws Throwable + */ + @And("^I start the browser \\{(.*?)\\}$") + public void iStartTheBrowser(String browser) throws Throwable { + switch(browser.toLowerCase()) { + case "chrome": + Browser.initChrome(); + break; + default: + throw new IllegalArgumentException("Invalid browser: " + browser); + } + logger.debug("BROWSER STARTED: {}" , browser); + } + + @And("^I resize the browser to width \\{(.*?)\\} and height \\{(.*?)\\}$") + public void iResizeTheBrowser(int width, int height) throws Throwable { + Dimension dim = new Dimension(width,height); + Browser.driver.manage().window().setSize(dim); + } + + @And("^I refresh the current page$") + public void iRefreshTheCurrentPage(){ + Browser.driver.navigate().refresh(); + } + + @And("^I validate the page title is \\{(.*?)\\}$") + public void i_validate_the_page_title_is(String title) throws Throwable { + Browser.validatePageTitle(title); + } +} diff --git a/src/test/java/api/test/selenium/LissiStepDefinitions.java b/src/test/java/api/test/selenium/LissiStepDefinitions.java new file mode 100644 index 0000000000000000000000000000000000000000..e4991e311448bc3032294f30db96004da611201a --- /dev/null +++ b/src/test/java/api/test/selenium/LissiStepDefinitions.java @@ -0,0 +1,20 @@ +package api.test.selenium; + +import api.test.core.BaseStepDefinitions; +import cucumber.api.java.en.And; +import cucumber.api.java.en.Then; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.openqa.selenium.Dimension; +import selenium.utils.*; + + +public class LissiStepDefinitions extends BaseStepDefinitions { + private static final Logger logger = LogManager.getLogger(LissiStepDefinitions.class.getSimpleName()); + + @Then("^I open Lissi dev website$") + public void iOpenLissiDevWebsite() throws Throwable { + Browser.goTo("https://lissi-demo.gxfs.dev/"); + Browser.validatePageTitle("GAIA-X Federation Services Portal"); + } +} diff --git a/src/test/resources/features/selenium/lissi/HomePage.feature b/src/test/resources/features/selenium/lissi/HomePage.feature new file mode 100644 index 0000000000000000000000000000000000000000..25465c8a4e90cc0ef9e804a52afadad7faf7a0ae --- /dev/null +++ b/src/test/resources/features/selenium/lissi/HomePage.feature @@ -0,0 +1,28 @@ +#Copyright (c) 2018 Vereign AG [https://www.vereign.com] +# +#This is free software: you can redistribute it and/or modify +#it under the terms of the GNU Affero General Public License as +#published by the Free Software Foundation, either version 3 of the +#License, or (at your option) any later version. +# +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU Affero General Public License for more details. +# +#You should have received a copy of the GNU Affero General Public License +#along with this program. If not, see <http://www.gnu.org/licenses/>. + +#https://lissi-demo.gxfs.dev/ +#Author: Rosen Georgiev rosen.georgiev@vereign.com + +@all @selenium @lissi +Feature: Selenium - Lissi - Hope page + + Background: + # Given we are testing the OCM Api + + @test + Scenario: Selenium - Lissi - Open the homa page and verify it - Positive + Given I start the browser {chrome} + Then I open Lissi dev website \ No newline at end of file