Java tutorial
/** * Copyright 2015 Q24 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.kahu.hawaii.cucumber.glue.html; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.openqa.selenium.support.ui.ExpectedConditions.invisibilityOfElementLocated; import static org.openqa.selenium.support.ui.ExpectedConditions.not; import static org.openqa.selenium.support.ui.ExpectedConditions.textToBePresentInElement; import static org.openqa.selenium.support.ui.ExpectedConditions.textToBePresentInElementLocated; import static org.openqa.selenium.support.ui.ExpectedConditions.textToBePresentInElementValue; import static org.openqa.selenium.support.ui.ExpectedConditions.titleContains; import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.List; import java.util.Properties; import java.util.concurrent.TimeUnit; import org.apache.commons.lang.StringUtils; import org.hamcrest.Matchers; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.OutputType; import org.openqa.selenium.Proxy; import org.openqa.selenium.TimeoutException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.opera.OperaDriver; import org.openqa.selenium.phantomjs.PhantomJSDriver; import org.openqa.selenium.phantomjs.PhantomJSDriverService; import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.safari.SafariDriver; import org.openqa.selenium.support.events.EventFiringWebDriver; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import com.gargoylesoftware.htmlunit.BrowserVersion; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.mdimension.jchronic.Chronic; import com.mdimension.jchronic.Options; import com.mdimension.jchronic.utils.Span; import cucumber.api.DataTable; import cucumber.api.Scenario; import cucumber.api.Transform; import cucumber.api.Transformer; import cucumber.api.java.After; import cucumber.api.java.Before; import cucumber.api.java.en.Then; import cucumber.api.java.en.When; public class HtmlSteps { private static final String PROXY_HOST_KEY = "test.proxyHost"; private static final String PROXY_PORT_KEY = "test.proxyPort"; private final String browser; private final boolean remote; private final String baseUrl; private final String relativeUrl; private final int timeout; private final String seleniumHub; private final boolean embedScreenshot; private EventFiringWebDriver webDriver; private boolean acceptCookies; public HtmlSteps() { Properties properties = System.getProperties(); this.browser = properties.containsKey("test.browser") ? System.getProperty("test.browser") : "chrome"; this.remote = properties.containsKey("test.remote") ? Boolean.parseBoolean(System.getProperty("test.remote")) : false; this.baseUrl = properties.containsKey("test.base.url") ? System.getProperty("test.base.url") : "http://target.kahuna.loc:8888"; this.seleniumHub = properties.containsKey("test.selenium.hub") ? System.getProperty("test.selenium.hub") : "http://localhost:4444/wd/hub"; this.relativeUrl = properties.containsKey("test.relative.url") ? System.getProperty("test.relative.url") : ""; this.timeout = properties.containsKey("test.timeout") ? Integer.parseInt(System.getProperty("test.timeout")) : 10; this.acceptCookies = properties.containsKey("test.disable.accept.cookies") ? !Boolean.parseBoolean(System.getProperty("test.disable.accept.cookies")) : true; this.embedScreenshot = properties.containsKey("test.embed.screenshot") ? Boolean.parseBoolean(System.getProperty("test.embed.screenshot")) : true; } public WebDriver getWebDriver() { return this.webDriver; } public String getBaseUrl() { return baseUrl; } /** * An expectation for checking the current url of a page. * * @param url * the expected url, which must be an exact match * @return true when the url matches, false otherwise * @see https://code.google.com/p/selenium/issues/detail?id=6842 */ public static ExpectedCondition<Boolean> currentUrlIs(final String url) { return driver -> { String currentUrl = driver.getCurrentUrl(); return currentUrl == null ? false : currentUrl.equals(url); }; } /** * An expectation for checking that the current url contains a * case-sensitive substring * * @param url * the fragment of url expected * @return true when the url matches, false otherwise * @see https://code.google.com/p/selenium/issues/detail?id=6842 */ public static ExpectedCondition<Boolean> currentUrlContains(final String url) { return driver -> { String currentUrl = driver.getCurrentUrl(); return currentUrl == null ? false : currentUrl.contains(url); }; } @Before("@web") public void beforeScenario() throws Exception { WebDriver driver; if (StringUtils.containsIgnoreCase(browser, "chrome")) { if (remote) { DesiredCapabilities capabilities = DesiredCapabilities.chrome(); driver = createRemoteWebDriverForCapabilities(capabilities); } else { driver = new ChromeDriver(); } } else if (StringUtils.containsIgnoreCase(browser, "opera")) { if (remote) { DesiredCapabilities capabilities = DesiredCapabilities.operaBlink(); driver = createRemoteWebDriverForCapabilities(capabilities); } else { driver = new OperaDriver(); } } else if (StringUtils.containsIgnoreCase(browser, "firefox")) { if (remote) { DesiredCapabilities capabilities = DesiredCapabilities.firefox(); driver = createRemoteWebDriverForCapabilities(capabilities); } else { driver = new FirefoxDriver(); } } else if (StringUtils.containsIgnoreCase(browser, "htmlunit")) { driver = new HtmlUnitDriver(BrowserVersion.CHROME); } else if (StringUtils.containsIgnoreCase(browser, "iexplore")) { if (remote) { DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer(); driver = createRemoteWebDriverForCapabilities(capabilities); } else { driver = new InternetExplorerDriver(); } } else if (StringUtils.containsIgnoreCase(browser, "phantom")) { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, getOsSpecificPhantomDriverPath()); Proxy proxy = getHttpProxy(); if (proxy != null) { capabilities.setCapability(CapabilityType.PROXY, getHttpProxy()); } driver = new PhantomJSDriver(capabilities); } else if (StringUtils.containsIgnoreCase(browser, "safari")) { if (remote) { DesiredCapabilities capabilities = DesiredCapabilities.safari(); driver = createRemoteWebDriverForCapabilities(capabilities); } else { driver = new SafariDriver(); } } else { throw new IllegalStateException("Unsupported browser specified"); } webDriver = new EventFiringWebDriver(driver); webDriver.manage().deleteAllCookies(); turnOnImplicitWaits(); } private WebDriver createRemoteWebDriverForCapabilities(DesiredCapabilities capabilities) throws Exception { WebDriver driver; Proxy proxy = getHttpProxy(); if (proxy != null) { capabilities.setCapability(CapabilityType.PROXY, getHttpProxy()); } driver = new RemoteWebDriver(new URL(seleniumHub), capabilities); return driver; } private String getOsSpecificPhantomDriverPath() { String osName = System.getProperty("os.name").toLowerCase(); String returnPath = "bin/linux/phantomjs"; if (osName.contains("windows")) { returnPath = "bin/windows/phantomjs"; } else if (osName.contains("mac")) { returnPath = "bin/mac/phantomjs"; } return returnPath; } @After("@web") public void afterScenario(Scenario scenario) { if (scenario.isFailed() && embedScreenshot) { try { byte[] screenshot = webDriver.getScreenshotAs(OutputType.BYTES); scenario.embed(screenshot, "image/png"); } catch (WebDriverException somePlatformsDontSupportScreenshots) { System.err.println(somePlatformsDontSupportScreenshots.getMessage()); } } webDriver.quit(); webDriver = null; } @When("^I visit page \"([^\"]*)\"$") public void I_visit_page(String path) throws Throwable { webDriver.get(getUrl() + path); waitForLoad(); } @When("^I visit page \"([^\"]*)\" and accept cookies$") public void I_visit_page_and_accept_cookies(String path) throws Throwable { webDriver.get(getUrl() + path); acceptCookies(); waitForLoad(); } public void waitForLoad() { ExpectedCondition<Boolean> pageLoadCondition = driver -> ((JavascriptExecutor) driver) .executeScript("return document.readyState").equals("complete"); WebDriverWait wait = new WebDriverWait(webDriver, 30); wait.until(pageLoadCondition); } public void waitForJQueryToFinish() { try { ExpectedCondition<Boolean> ajaxCondition = driver -> (Boolean) ((JavascriptExecutor) driver) .executeScript("return window.jQuery != undefined && jQuery.active === 0"); WebDriverWait wait = new WebDriverWait(webDriver, 30); wait.until(ajaxCondition); } catch (TimeoutException e) { // this is a timeout (obviously) but since we were supposed to wait anyway, swallow the exception } } @When("^I wait for jQuery to finish$") public void I_wait_for_JQuery_to_finish() throws Throwable { waitForJQueryToFinish(); } public void waitForAngularJSToFinish() { try { ExpectedCondition<Boolean> ajaxCondition = driver -> (Boolean) ((JavascriptExecutor) driver) .executeScript( "return window.angular != undefined && angular.element(document.body).injector().get('$http').pendingRequests.length === 0"); WebDriverWait wait = new WebDriverWait(webDriver, 30); wait.until(ajaxCondition); } catch (TimeoutException e) { // this is a timeout (obviously) but since we were supposed to wait anyway, swallow the exception } } @When("^I wait for AngularJS to finish$") public void I_wait_for_AngularJS_to_finish() throws Throwable { waitForAngularJSToFinish(); } @When("^I accept cookies$") public void I_accept_cookies() throws Throwable { acceptCookies(); } @When("^I fill \"([^\"]*)\" in field \"([^\"]*)\"$") public void I_fill_in_field(String value, String id) throws Throwable { findElementById(id).sendKeys(value); } @When("^I clear field \"([^\"]*)\"$") public void I_clear_field(String id) throws Throwable { findElementById(id).clear(); } @When("^I fill date (.*) in field \"([^\"]*)\"$") public void I_fill_date_in_field(@Transform(ChronicConverter.class) Calendar cal, String id) throws Throwable { findElementById(id).sendKeys(formatDate(cal)); } @When("^I fill time (.*) in field \"([^\"]*)\"$") public void I_fill_time_in_field(@Transform(ChronicConverter.class) Calendar cal, String id) throws Throwable { findElementById(id).sendKeys(formatTime(cal)); } @When("^I choose radio button \"([^\"]*)\"$") public void I_choose_radio_button(String id) throws Throwable { I_check_checkbox(id); } @When("^I check checkbox \"([^\"]*)\"$") /** * Checkboxes are not visible themselves because of the CSS used. Instead, we click on the label belonging to them with the label'for' * Note: because of this approach this method is tight to the implementation I will not just click on checkbox; don't like it; needs refactoring. * @param id, the 'label for' identifier * @throws Throwable */ public void I_check_checkbox(String id) throws Throwable { List<WebElement> elements = webDriver.findElements(By.cssSelector("label[for='" + id + "']")); WebElement element = null; if (elements != null) { if (elements.size() > 1) { element = findVisibleElement(By.cssSelector("label[for='" + id + "']:first-child")); } else { element = findVisibleElement(By.cssSelector("label[for='" + id + "']")); } } else { fail("Checkbox element label[for='" + id + "'] not found"); } scrollToElement(element); moveTo(element).click().perform(); // While fixing SUPDEV-1903 I refactored above code. // However above code worked as after fixing the issues with the quotes. // I keep code below just for reference if we look into this in the future. // WebElement element = findElement(By.id(id)); // // find label // if (element != null) { // WebElement labelElement = element.findElement(By.xpath(".//ancestor::label[@for='" + id + "']")); // scrollToElement(labelElement); // labelElement.click(); // } else { // fail("Checkbox element \"" + id + "\" not found"); // } } @When("^I select \"([^\"]*)\" from drop-down list \"([^\"]*)\"$") public void I_select_from_drop_down_list(String value, String id) throws Throwable { WebElement element = findElementById(id); List<WebElement> options = element.findElements(By.tagName("option")); for (WebElement option : options) { if (option.getText().equals(value) || option.getAttribute("value").equals(value)) { moveTo(option).click().perform(); break; } } } @When("^I fill in the form?$") public void I_fill_in_the_form(DataTable data) throws Throwable { I_fill_in_the_fields(data); } @When("^I fill in the fields?$") public void I_fill_in_the_fields(DataTable data) throws Throwable { for (List<String> row : data.raw()) { String id = row.get(0); String value = row.get(1); WebElement element = findVisibleElementById(id); String tagName = element.getTagName(); String type = element.getAttribute("type"); if ("input".equalsIgnoreCase(tagName)) { if ("checkbox".equalsIgnoreCase(type)) { moveTo(element).click().perform(); } else if ("radio".equalsIgnoreCase(type)) { moveTo(element).click().perform(); } else { if (value != null) { if (value.startsWith("date:")) { String chronic = value.replaceFirst("date:", "").trim(); Calendar cal = parseChronic(chronic); element.sendKeys(formatDate(cal)); } else if (value.startsWith("time:")) { String chronic = value.replaceFirst("time:", "").trim(); Calendar cal = parseChronic(chronic); element.sendKeys(formatTime(cal)); } else { element.sendKeys(value); } } } } else if ("select".equalsIgnoreCase(tagName)) { List<WebElement> options = element.findElements(By.tagName("option")); for (WebElement option : options) { if (option.getText().equals(value) || option.getAttribute("value").equals(value)) { moveTo(option).click().perform(); break; } } } else if ("label".equalsIgnoreCase(tagName)) { moveTo(element).click().perform(); } else { element.sendKeys(value); } } } @When("^I click on button \"([^\"]*)\"$") public void I_click_on_button(String id) throws Throwable { WebElement element = findVisibleAndClickableElement(By.id(id)); moveTo(element).click().perform(); } @When("^I click on button with text \"([^\"]*)\"$") public void I_click_on_button_with_text(String text) throws Throwable { WebElement element = findVisibleElement(By.xpath("//button[text()='" + text + "']")); moveTo(element).click().perform(); } @When("^I click on button with text containing \"([^\"]*)\"$") public void I_click_on_button_with_text_containing(String text) throws Throwable { WebElement element = findVisibleElement(By.xpath("//button[contains(text(), '" + text + "')]")); moveTo(element).click().perform(); } @When("^I click on element \"([^\"]*)\"$") public void I_click_on_element(String id) throws Throwable { WebElement element = findVisibleElementById(id); moveTo(element).click().perform(); } @When("^I click on element with id \"([^\"]*)\"$") public void I_click_on_element_with_id(String id) throws Throwable { WebElement element = findVisibleElementById(id); moveTo(element).click().perform(); } @When("^I click on link \"([^\"]*)\"$") public void I_click_on_link(String id) throws Throwable { WebElement element = findVisibleElement(By.cssSelector("a#" + id)); moveTo(element).click().perform(); } @When("^I click on link with text \"([^\"]*)\"$") public void I_click_on_link_with_text(String linkText) throws Throwable { WebElement element = findVisibleElement(By.linkText(linkText)); moveTo(element).click().perform(); } @When("^I click on link with text containing \"([^\"]*)\"$") public void I_click_on_link_with_text_containing(String linkText) throws Throwable { WebElement element = findVisibleElement(By.partialLinkText(linkText)); moveTo(element).click().perform(); } @When("^I wait (\\d+) seconds?$") public void I_wait_seconds(int seconds) throws Throwable { if (seconds > 0) { int millis = seconds * 1000; Object lock = new Object(); synchronized (lock) { try { lock.wait(millis); } catch (InterruptedException e) { // ignore } } } } @When("^I select an iframe with name \"([^\"]*)\"$") public void I_select_an_iframe_with_name(String text) throws Throwable { webDriver.switchTo().frame(text); } @When("^I select the parent window") public void I_select_the_parent_window() throws Throwable { webDriver.switchTo().defaultContent(); } @When("^I click on input with value \"([^\"]*)\"$") public void I_click_on_input_with_value(String text) throws Throwable { WebElement element = findElement(By.xpath("//input[contains(@value,'" + text + "')]")); moveTo(element).click().perform(); } @Then("^current url should be \"([^\"]*)\"$") public void current_url_should_be(String url) throws Throwable { try { waitUntil(currentUrlIs(url)); } catch (TimeoutException e) { assertThat(webDriver.getCurrentUrl(), is(equalTo(url))); } } @Then("^current url should not be \"([^\"]*)\"$") public void current_url_should_not_be(String url) throws Throwable { try { waitUntil(not(currentUrlIs(url))); } catch (TimeoutException e) { assertThat(webDriver.getCurrentUrl(), is(Matchers.not(equalTo(url)))); } } @Then("^current url should contain \"([^\"]*)\"$") public void current_url_should_contain(final String url) throws Throwable { try { waitUntil(currentUrlContains(url)); } catch (TimeoutException e) { assertThat(webDriver.getCurrentUrl(), containsString(url)); } } @Then("^current url should not contain \"([^\"]*)\"$") public void current_url_should_not_contain(String url) throws Throwable { try { waitUntil(not(currentUrlContains(url))); } catch (TimeoutException e) { assertThat(webDriver.getCurrentUrl(), Matchers.not(containsString(url))); } } @Then("^page title should be \"([^\"]*)\"$") public void page_title_should_be(String title) throws Throwable { try { waitUntil(titleIs(title)); } catch (TimeoutException e) { assertThat(webDriver.getTitle(), is(equalTo(title))); } } @Then("^page title should not be \"([^\"]*)\"$") public void page_title_should_not_be(String title) throws Throwable { try { waitUntil(not(titleIs(title))); } catch (TimeoutException e) { assertThat(webDriver.getTitle(), is(Matchers.not(equalTo(title)))); } } @Then("^page title should contain \"([^\"]*)\"$") public void page_title_should_contain(String title) throws Throwable { try { waitUntil(titleContains(title)); } catch (TimeoutException e) { assertThat(webDriver.getTitle(), containsString(title)); } } @Then("^page title should not contain \"([^\"]*)\"$") public void page_title_should_not_contain(String title) throws Throwable { try { waitUntil(not(titleContains(title))); } catch (TimeoutException e) { assertThat(webDriver.getTitle(), Matchers.not(containsString(title))); } } @Then("^page should contain element \"([^\"]*)\"$") public void page_should_contain_element(String id) throws Throwable { try { findElement(By.id(id)); } catch (NoSuchElementException e) { fail("page did not contain element with id \"" + id + "\""); } } @Then("^page should not contain element \"([^\"]*)\"$") public void page_should_not_contain_element(String id) throws Throwable { try { findElement(By.id(id)); fail("page did contain element with id \"" + id + "\""); } catch (NoSuchElementException e) { // pass } } @Then("^page should contain element with id \"([^\"]*)\"$") public void page_should_contain_element_with_id(String id) throws Throwable { try { findElement(By.id(id)); } catch (NoSuchElementException e) { fail("page did not contain element with id \"" + id + "\""); } } @Then("^page should not contain element with id \"([^\"]*)\"$") public void page_should_not_contain_element_with_id(String id) throws Throwable { try { findElement(By.id(id)); fail("page did contain element with id \"" + id + "\""); } catch (NoSuchElementException e) { // pass } } @Then("^page should contain element with class name \"([^\"]*)\"$") public void page_should_contain_element_with_class_name(String className) throws Throwable { try { findElement(By.className(className)); } catch (NoSuchElementException e) { fail("page did not contain element with class name \"" + className + "\""); } } @Then("^page should not contain element with class name \"([^\"]*)\"$") public void page_should_not_contain_element_with_class_name(String className) throws Throwable { try { findElement(By.className(className)); fail("page did contain element with class name \"" + className + "\""); } catch (NoSuchElementException e) { // pass } } @Then("^page element \"([^\"]*)\" should be visible$") public void page_element_should_be_visible(String id) throws Throwable { try { waitUntil(visibilityOfElementLocated(By.id(id))); } catch (TimeoutException e) { fail("element with id \"" + id + "\" was not visible"); } } @Then("^page element \"([^\"]*)\" should not be visible$") public void page_element_should_not_be_visible(String id) throws Throwable { try { waitUntil(invisibilityOfElementLocated(By.id(id))); } catch (TimeoutException e) { fail("element with id \"" + id + "\" was visible"); } } @Then("^page element \"([^\"]*)\" should contain text \"([^\"]*)\"$") public void page_element_should_contain_text(String id, String text) throws Throwable { try { waitUntil(textToBePresentInElementLocated(By.id(id), text)); } catch (TimeoutException e) { try { WebElement element = findElementById(id); fail("element with id \"" + id + "\" did not contain text \"" + text + "\"; visible content of element was: " + element.getText()); } catch (NoSuchElementException e2) { fail("element with id \"" + id + "\" did not contain text \"" + text + "\"; element not found"); } } } @Then("^page element \"([^\"]*)\" should not contain text \"([^\"]*)\"$") public void page_element_should_not_contain_text(String id, String text) throws Throwable { try { waitUntil(not(textToBePresentInElementLocated(By.id(id), text))); } catch (TimeoutException e) { try { WebElement element = findElementById(id); fail("element with id \"" + id + "\" did contain text \"" + text + "\"; visible content of element was: " + element.getText()); } catch (NoSuchElementException e2) { fail("element with id \"" + id + "\" did contain text \"" + text + "\"; element not found"); } } } @Then("^page element \"([^\"]*)\" should contain class name \"([^\"]*)\"$") public void page_element_should_contain_class_name(String id, String className) throws Throwable { try { WebElement element = findElementById(id); if (!element.getAttribute("class").contains(className)) { fail("element with id \"" + id + "\" did not contain element with class name \"" + className + "\""); } } catch (NoSuchElementException e) { fail("element with id \"" + id + "\" not found"); } } @Then("^page element \"([^\"]*)\" should contain element with class name \"([^\"]*)\"$") public void page_element_should_contain_element_with_class_name(String id, String className) throws Throwable { try { findElement(By.cssSelector("#" + id + " ." + className)); } catch (NoSuchElementException e) { fail("element with id \"" + id + "\" not found"); } } @Then("^page element \"([^\"]*)\" should not contain element with class name \"([^\"]*)\"$") public void page_element_should_not_contain_element_with_class_name(String id, String className) throws Throwable { try { findElement(By.cssSelector("#" + id + " ." + className)); fail("element with id \"" + id + "\" did contain element with class name \"" + className + "\""); } catch (NoSuchElementException e) { // pass } } @Then("^page element \"([^\"]*)\" should contain visible element with class name \"([^\"]*)\"$") public void page_element_should_contain_visible_element_with_class_name(String id, String className) throws Throwable { try { waitUntil(visibilityOfElementLocated(By.cssSelector("#" + id + " ." + className))); } catch (TimeoutException e) { fail("element with id \"" + id + "\" did not contain visible element with class name \"" + className + "\""); } } @Then("^page element \"([^\"]*)\" should contain invisible element with class name \"([^\"]*)\"$") public void page_element_should_contain_invisible_element_with_class_name(String id, String className) throws Throwable { try { waitUntil(invisibilityOfElementLocated(By.cssSelector("#" + id + " ." + className))); } catch (TimeoutException e) { fail("element with id \"" + id + "\" did not contain invisible element with class name \"" + className + "\""); } } @Then("^page element with id \"([^\"]*)\" should be visible$") public void page_element_with_id_should_be_visible(String id) throws Throwable { try { waitUntil(visibilityOfElementLocated(By.id(id))); } catch (TimeoutException e) { fail("element with id \"" + id + "\" was not visible"); } } @Then("^page element with id \"([^\"]*)\" should not be visible$") public void page_element_with_id_should_not_be_visible(String id) throws Throwable { try { waitUntil(invisibilityOfElementLocated(By.id(id))); } catch (TimeoutException e) { fail("element with id \"" + id + "\" was visible"); } } @Then("^page element with id \"([^\"]*)\" should contain text \"([^\"]*)\"$") public void page_element_with_id_should_contain_text(String id, String text) throws Throwable { try { waitUntil(textToBePresentInElementLocated(By.id(id), text)); } catch (TimeoutException e) { try { WebElement element = findElementById(id); fail("element with id \"" + id + "\" did not contain text \"" + text + "\"; visible content of element was: " + element.getText()); } catch (NoSuchElementException e2) { fail("element with id \"" + id + "\" did not contain text \"" + text + "\"; element not found"); } } } @Then("^page element with id \"([^\"]*)\" should not contain text \"([^\"]*)\"$") public void page_element_with_id_should_not_contain_text(String id, String text) throws Throwable { try { waitUntil(not(textToBePresentInElementLocated(By.id(id), text))); } catch (TimeoutException e) { try { WebElement element = findElementById(id); fail("element with id \"" + id + "\" did contain text \"" + text + "\"; visible content of element was: " + element.getText()); } catch (NoSuchElementException e2) { fail("element with id \"" + id + "\" did contain text \"" + text + "\"; element not found"); } } } @Then("^page element with id \"([^\"]*)\" should contain element with class name \"([^\"]*)\"$") public void page_element_with_id_should_contain_element_with_class_name(String id, String className) throws Throwable { try { findElement(By.cssSelector("#" + id + " ." + className)); } catch (NoSuchElementException e) { fail("element with id \"" + id + "\" did not contain element with class name \"" + className + "\""); } } @Then("^page element with id \"([^\"]*)\" should not contain element with class name \"([^\"]*)\"$") public void page_element_with_id_should_not_contain_element_with_class_name(String id, String className) throws Throwable { try { findElement(By.cssSelector("#" + id + " ." + className)); fail("element with id \"" + id + "\" did contain element with class name \"" + className + "\""); } catch (NoSuchElementException e) { // pass } } @Then("^page element with id \"([^\"]*)\" should contain visible element with class name \"([^\"]*)\"$") public void page_elemen_with_id_should_contain_visible_element_with_class_name(String id, String className) throws Throwable { try { waitUntil(visibilityOfElementLocated(By.cssSelector("#" + id + " ." + className))); } catch (TimeoutException e) { fail("element with id \"" + id + "\" did not contain visible element with class name \"" + className + "\""); } } @Then("^page element with id \"([^\"]*)\" should contain invisible element with class name \"([^\"]*)\"$") public void page_element_with_id_should_contain_invisible_element_with_class_name(String id, String className) throws Throwable { try { waitUntil(invisibilityOfElementLocated(By.cssSelector("#" + id + " ." + className))); } catch (TimeoutException e) { fail("element with id \"" + id + "\" did not contain invisible element with class name \"" + className + "\""); } } @Then("^page element with id \"([^\"]*)\" should have class \"([^\"]*)\"$") public void page_element_with_id_should_have_class(String id, String className) throws Throwable { try { findElement(By.cssSelector("#" + id + "." + className)); } catch (NoSuchElementException e) { fail("element with id \"" + id + "\" did not have class name \"" + className + "\""); } } @Then("^page element with class name \"([^\"]*)\" should be visible$") public void page_element_with_class_name_should_be_visible(String className) throws Throwable { try { waitUntil(visibilityOfElementLocated(By.className(className))); } catch (TimeoutException e) { fail("element with class name \"" + className + "\" was not visible"); } } @Then("^page element with class name \"([^\"]*)\" should not be visible$") public void page_element_with_class_name_should_not_be_visible(String className) throws Throwable { try { waitUntil(invisibilityOfElementLocated(By.className(className))); } catch (TimeoutException e) { fail("element with class name \"" + className + "\" was visible"); } } @Then("^page element with class name \"([^\"]*)\" should contain text \"([^\"]*)\"$") public void page_element_with_class_name_should_contain_text(String className, String text) throws Throwable { try { waitUntil(textToBePresentInElementLocated(By.className(className), text)); } catch (TimeoutException e) { try { WebElement element = findElement(By.className(className)); fail("element with class name \"" + className + "\" did not contain text \"" + text + "\"; visible content of element was: " + element.getText()); } catch (NoSuchElementException e2) { fail("element with class name \"" + className + "\" did not contain text \"" + text + "\"; element not found"); } } } @Then("^page element with class name \"([^\"]*)\" should not contain text \"([^\"]*)\"$") public void page_element_with_class_name_should_not_contain_text(String className, String text) throws Throwable { try { waitUntil(not(textToBePresentInElementLocated(By.className(className), text))); } catch (TimeoutException e) { try { WebElement element = findElement(By.className(className)); fail("element with class name \"" + className + "\" did contain text \"" + text + "\"; visible content of element was: " + element.getText()); } catch (NoSuchElementException e2) { fail("element with class name \"" + className + "\" did contain text \"" + text + "\"; element not found"); } } } @Then("^page element with class name \"([^\"]*)\" should contain element with class name \"([^\"]*)\"$") public void page_element_with_class_name_should_contain_element_with_class_name(String parent, String className) throws Throwable { try { findElement(By.cssSelector("." + parent + " ." + className)); } catch (NoSuchElementException e) { fail("element with class name \"" + parent + "\" did not contain element with class name \"" + className + "\""); } } @Then("^page element with class name \"([^\"]*)\" should not contain element with class name \"([^\"]*)\"$") public void page_element_with_class_name_should_not_contain_element_with_class_name(String parent, String className) throws Throwable { try { findElement(By.cssSelector("." + parent + " ." + className)); fail("element with class name \"" + parent + "\" did contain element with class name \"" + className + "\""); } catch (NoSuchElementException e) { // pass } } @Then("^page element with class name \"([^\"]*)\" should contain visible element with class name \"([^\"]*)\"$") public void page_elemen_with_class_name_should_contain_visible_element_with_class_name(String parent, String className) throws Throwable { try { waitUntil(visibilityOfElementLocated(By.cssSelector("." + parent + " ." + className))); } catch (TimeoutException e) { fail("element with class name \"" + parent + "\" did not contain visible element with class name \"" + className + "\""); } } @Then("^page element with class name \"([^\"]*)\" should contain invisible element with class name \"([^\"]*)\"$") public void page_element_with_class_name_should_contain_invisible_element_with_class_name(String parent, String className) throws Throwable { try { waitUntil(invisibilityOfElementLocated(By.cssSelector("." + parent + " ." + className))); } catch (TimeoutException e) { fail("element with class name \"" + parent + "\" did not contain invisible element with class name \"" + className + "\""); } } @Then("^field \"([^\"]*)\" should contain value \"([^\"]*)\"$") public void field_should_contain_value(String id, String value) throws Throwable { try { waitUntil(textToBePresentInElementValue(By.id(id), value)); } catch (TimeoutException e) { try { WebElement element = findElementById(id); fail("field with id \"" + id + "\" did not contain value \"" + value + "\"; value of field was: " + element.getAttribute("value")); } catch (NoSuchElementException e2) { fail("field with id \"" + id + "\" did not contain value \"" + value + "\"; field not found"); } } } @Then("^field \"([^\"]*)\" should not contain value \"([^\"]*)\"$") public void field_should_not_contain_value(String id, String value) throws Throwable { try { waitUntil(not(textToBePresentInElementValue(By.id(id), value))); } catch (TimeoutException e) { try { WebElement element = findElementById(id); fail("field with id \"" + id + "\" did contain value \"" + value + "\"; value of field was: " + element.getAttribute("value")); } catch (NoSuchElementException e2) { fail("field with id \"" + id + "\" did contain value \"" + value + "\"; field not found"); } } } @Then("^body should contain text \"([^\"]*)\"$") public void body_should_contain_text(String text) throws Throwable { // assertThat(findVisibleElement(By.tagName("body")).getText().contains(text), // is(equalTo(true))); try { WebElement element = webDriver.findElement(By.tagName("body")); waitUntil(textToBePresentInElement(element, text)); } catch (TimeoutException e) { fail("body did not contain text \"" + text + "\"; text not found"); } } /** * Undocumented feature for testing purpose. */ @Then("^page should contain element with xpath expression \"([^\"]*)\"$") public void page_should_contain_element_with_xpath_expression(String xpath) throws Throwable { try { findElement(By.xpath(xpath)); } catch (NoSuchElementException e) { fail("page did not contain element with xpath expression \"" + xpath + "\""); } } /** * Undocumented feature for testing purpose. */ @Then("^page should not contain element with xpath expression \"([^\"]*)\"$") public void page_should_not_contain_element_with_xpath_expression(String xpath) throws Throwable { try { findElement(By.xpath(xpath)); fail("page did contain element with xpath expression \"" + xpath + "\""); } catch (NoSuchElementException e) { // pass } } public String getUrl() { return baseUrl + relativeUrl; } private Proxy getHttpProxy() { Proxy proxy = null; String proxyHost = System.getProperty(PROXY_HOST_KEY); String proxyPort = System.getProperty(PROXY_PORT_KEY); if (proxyHost != null && proxyPort != null) { proxy = new Proxy(); proxy.setHttpProxy(proxyHost + ":" + proxyPort); proxy.setProxyType(Proxy.ProxyType.MANUAL); proxy.setSslProxy(proxyHost + ":" + proxyPort); } return proxy; } /** * Find the first {@link org.openqa.selenium.WebElement} using the given * method. * * @param by * The locating mechanism * @return The first matching element on the current page * @throws org.openqa.selenium.NoSuchElementException * If no matching elements are found * @see org.openqa.selenium.WebDriver#findElement(org.openqa.selenium.By) */ public WebElement findElement(By by) { return webDriver.findElement(by); } /** * Find the first {@link org.openqa.selenium.WebElement} using the given * method. * * @param by * The locating mechanism * @return The first matching element on the current page * @throws org.openqa.selenium.NoSuchElementException * If no matching elements are found * @see org.openqa.selenium.WebDriver#findElement(org.openqa.selenium.By) */ public WebElement findVisibleElement(By by) { waitUntil(visibilityOfElementLocated(by)); return findElement(by); } public WebElement findVisibleAndClickableElement(By by) { // waitUntil(elementToBeClickable(by)); waitUntil(visibilityOfElementLocated(by)); // waitUntil(elementToBeClickable(by)); return findElement(by); } public WebElement findVisibleElementById(String id) { return findVisibleElement(By.id(id)); } /** * Find the first {@link org.openqa.selenium.WebElement} for the given id. * * @param id * The value of the "id" attribute to search for * @return The first matching element on the current page * @throws AssertionError * If no matching elements are found * @see org.openqa.selenium.WebDriver#findElement(org.openqa.selenium.By) * @see org.openqa.selenium.By.ById */ public WebElement findElementById(String id) { try { // waitUntil(presenceOfElementLocated(By.id(id))); WebElement element = webDriver.findElement(By.id(id)); // Scroll to the element, this due to some dirty radiobutton tricks. // And force it a bit more to to center // And yes, do this for all elements. ( This is a known ChromeDriver // V2.12 bug, if the element is not in the // visible area then you 'can' have some troubles. ). Works for all // elements too ;-) scrollToElement(element); return element; } catch (NoSuchElementException e) { throw new AssertionError("Element with id <" + id + "> not found"); } } /** * Scroll to the element, this due to some dirty radiobutton tricks. And * force it a bit more to to center // And yes, do this for all elements. ( * This is a known ChromeDriver V2.12 bug, if the element is not in the // * visible area then you 'can' have some troubles. ). Works for all elements * too ;-) * * @param element */ public void scrollToElement(WebElement element) { int y_coor = 0; try { y_coor = element.getLocation().y - 100; ((JavascriptExecutor) webDriver).executeScript("window.scrollTo(0," + y_coor + ")"); } catch (Exception e) { throw new AssertionError("Could not scroll to element"); } } /** * Scroll to classname. This is a known ChromeDriver V2.12 bug, if the * element is not in the // visible area then you 'can' have some troubles. */ public void scrollToClass(String classname) { WebElement element = findElement(By.className(classname)); scrollToElement(element); } /** * Scroll to id. This is a known ChromeDriver V2.12 bug, if the element is * not in the // visible area then you 'can' have some troubles. */ public void scrollToID(String id) { WebElement element = findElementById(id); scrollToElement(element); } /** * Repeatedly applies this instance's input value to the given function * until one of the following occurs: * <ol> * <li>the function returns neither null nor false,</li> * <li>the function throws an unignored exception,</li> * <li>the timeout expires, * <li> * <li>the current thread is interrupted</li> * </ol> * * @param isTrue * the parameter to pass to the * {@link org.openqa.selenium.support.ui.ExpectedCondition} * @param <V> * The function's expected return type. * @return The functions' return value if the function returned something * different from null or false before the timeout expired. * @throws org.openqa.selenium.TimeoutException * If the timeout expires. */ public <V> V waitUntil(Function<? super WebDriver, V> isTrue) { WebDriverWait wait = new WebDriverWait(webDriver, timeout); return wait.until(isTrue); } /** * Repeatedly applies this instance's input value to the given predicate * until the timeout expires or the predicate evaluates to true. * * @param isTrue * The predicate to wait on. * @throws org.openqa.selenium.TimeoutException * If the timeout expires. */ public void waitUntil(Predicate<WebDriver> isTrue) { WebDriverWait wait = new WebDriverWait(webDriver, timeout); wait.until(isTrue); } /** * Parses a chronic string to a Calendar object. */ public Calendar parseChronic(String value) { ChronicConverter chronicConverter = new ChronicConverter(); return chronicConverter.transform(value); } /** * Formats a calendar to a date string. */ public String formatDate(Calendar cal) { DateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); return sdf.format(cal.getTime()); } /** * Formats a calendar to a time string. */ public String formatTime(Calendar cal) { DateFormat sdf = new SimpleDateFormat("hh:mm"); return sdf.format(cal.getTime()); } public void acceptCookies() { // accept cookies popup if (acceptCookies) { try { WebDriverWait wait = new WebDriverWait(webDriver, 2); // wait // max 2 // seconds wait.until(ExpectedConditions.elementToBeClickable(By.className("cookie-yes"))); turnOffImplicitWaits(); WebElement element = findElement(By.className("cookie-yes")); moveTo(element).click().perform(); Object lock = new Object(); synchronized (lock) { try { lock.wait(1000); // wait 1 second to allow cookie popup // to be closed } catch (InterruptedException e) { // ignore } } } catch (NoSuchElementException e) { // ignore, cookie popup not displayed } catch (TimeoutException e) { // ignore, cookie popup not displayed } turnOnImplicitWaits(); acceptCookies = false; } } private void turnOnImplicitWaits() { webDriver.manage().timeouts().implicitlyWait(timeout, TimeUnit.SECONDS); } private void turnOffImplicitWaits() { webDriver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); } /** * Transformer for chronic values. */ public static class ChronicConverter extends Transformer<Calendar> { private static Options options = new Options(); @Override public Calendar transform(String value) { Span span = Chronic.parse(value, options); return span.getEndCalendar(); } } public Actions moveTo(WebElement element) { Actions actions = new Actions(webDriver); return actions.moveToElement(element); } }