All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.redhat.darcy.webdriver.WebDriverBrowser Maven / Gradle / Ivy

Go to download

An implementation of darcy and darcy-web that uses Selenium WebDriver as the automation library backend.

The newest version!
/*
 Copyright 2014 Red Hat, Inc. and/or its affiliates.

 This file is part of darcy-webdriver.

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see .
 */

package com.redhat.darcy.webdriver;

import static com.redhat.synq.Synq.after;

import com.redhat.darcy.ui.DarcyException;
import com.redhat.darcy.ui.FindableNotPresentException;
import com.redhat.darcy.ui.api.Locator;
import com.redhat.darcy.ui.api.Transition;
import com.redhat.darcy.ui.api.View;
import com.redhat.darcy.ui.api.elements.Element;
import com.redhat.darcy.ui.internal.SimpleTransition;
import com.redhat.darcy.web.api.Alert;
import com.redhat.darcy.web.api.Browser;
import com.redhat.darcy.web.api.CookieManager;
import com.redhat.darcy.web.api.Frame;
import com.redhat.darcy.web.api.ViewUrl;
import com.redhat.darcy.web.api.WebSelection;
import com.redhat.darcy.webdriver.internal.DelegatingWebContext;
import com.redhat.darcy.webdriver.internal.TargetedWebDriver;
import com.redhat.darcy.webdriver.internal.WebDriverCookieManager;
import com.redhat.darcy.webdriver.internal.WebDriverWebContext;
import com.redhat.darcy.webdriver.internal.WebDriverWebSelection;
import com.redhat.darcy.webdriver.internal.WrapsTargetedDriver;
import com.redhat.synq.Event;

import org.hamcrest.Matcher;
import org.openqa.selenium.NoSuchFrameException;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.remote.SessionNotFoundException;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * The main wrapper around a {@link org.openqa.selenium.WebDriver} in order to implement {@link
 * com.redhat.darcy.web.api.Browser}. This class also implements {@link com.redhat.darcy.web.api.Frame},
 * which is a subset of the Browser API.
 * 

* There is one key difference between a Browser in Darcy and a WebDriver in Selenium. In Darcy, a * Browser is one:one with a specific window/tab or frame. In WebDriver, a single WebDriver * connection may manage many resulting windows or frames. It is assumed that the WebDriver passed * to this class is pointed at a specific target. *

* Implementation of {@link com.redhat.darcy.web.api.Browser} is straightforward, however, in addition * to forwarding calls to the relevant WebDriver method, we will use our page object structure to * wait for those page objects to load as is required by implementers. * * @see com.redhat.darcy.webdriver.internal.TargetedWebDriver */ public class WebDriverBrowser implements Browser, Frame, WebDriverWebContext, WrapsTargetedDriver { private final TargetedWebDriver driver; private final WebDriverWebContext webContext; /** * @param driver A WebDriver implementation to wrap, pointed at some target (like a specific * frame or window), in order to control a browser window or frame. * @param webContext A WebContext that represents the driver in order to find elements and other * contexts. This class implements WebContext by forwarding to this * implementation. */ public WebDriverBrowser(TargetedWebDriver driver, WebDriverWebContext webContext) { this.driver = Objects.requireNonNull(driver, "driver"); this.webContext = Objects.requireNonNull(webContext, "webContext"); } /** * @param driver A WebDriver implementation to wrap, pointed at some target (like a specific * frame or window). * @param parentContext A parent context that can find other contexts (windows, frames). This * class implements ParentContext by forwarding to this implementation. The * parent context must be scoped to the same target as {@code driver}. * @param elementContext An element context that can find other elements. This class implements * ElementContext by forwarding to this implementation. The element * context must be scoped to the same target as {@code driver}. */ public WebDriverBrowser(TargetedWebDriver driver, WebDriverParentContext parentContext, WebDriverElementContext elementContext) { this(driver, new DelegatingWebContext(elementContext, parentContext)); } @Override public boolean isPresent() { return driver.isPresent(); } @Override public Event open(ViewUrl viewUrl) { Objects.requireNonNull(viewUrl); return open(viewUrl.url(), viewUrl.destination()); } @Override public Event open(String url, T destination) { Objects.requireNonNull(url); Objects.requireNonNull(destination); return after(() -> attempt(() -> driver.get(url))) .expect(transition().to(destination)); } @Override public String getCurrentUrl() { return attemptAndGet(driver::getCurrentUrl); } @Override public String getTitle() { return attemptAndGet(driver::getTitle); } @Override public String getSource() { return attemptAndGet(driver::getPageSource); } @Override public Event back(T destination) { Objects.requireNonNull(destination); return after(() -> attempt(() -> driver.navigate().back())) .expect(transition().to(destination)); } @Override public Event forward(T destination) { Objects.requireNonNull(destination); return after(() -> attempt(() -> driver.navigate().forward())) .expect(transition().to(destination)); } @Override public Event refresh(T destination) { Objects.requireNonNull(destination); return after(() -> attempt(() -> driver.navigate().refresh())) .expect(transition().to(destination)); } @Override public CookieManager cookies() { return new WebDriverCookieManager(driver); } @Override public void close() { attempt(driver::close); } @Override public void closeAll() { // TODO: Any harm in calling this with no windows open? driver.quit(); } @Override public void takeScreenshot(OutputStream outputStream) { try (OutputStream stream = outputStream) { byte[] data = attemptAndGet(() -> driver.getScreenshotAs(OutputType.BYTES)); stream.write(data); stream.flush(); } catch (IOException e) { throw new DarcyException("Could not take screenshot", e); } } @Override public WebSelection find() { return new WebDriverWebSelection(this); } @Override public Transition transition() { return new SimpleTransition(this); } @Override public Alert alert() { return webContext.alert(); } @Override public List findAllById(Class type, String id) { return attemptAndGet(() -> webContext.findAllById(type, id)); } @Override public List findAllByName(Class type, String name) { return attemptAndGet(() -> webContext.findAllByName(type, name)); } @Override public List findAllByXPath(Class type, String xpath) { return attemptAndGet(() -> webContext.findAllByXPath(type, xpath)); } @Override public List findAllByChained(Class type, Locator... locators) { return attemptAndGet(() -> webContext.findAllByChained(type, locators)); } @Override public List findAllByLinkText(Class type, String linkText) { return attemptAndGet(() -> webContext.findAllByLinkText(type, linkText)); } @Override public List findAllByTextContent(Class type, String textContent) { return attemptAndGet(() -> webContext.findAllByTextContent(type, textContent)); } @Override public List findAllByPartialTextContent(Class type, String partialTextContent) { return attemptAndGet(() -> webContext.findAllByPartialTextContent(type, partialTextContent)); } @Override public List findAllByNested(Class type, Element parent, Locator child) { return attemptAndGet(() -> webContext.findAllByNested(type, parent, child)); } @Override public T findById(Class type, String id) { return attemptAndGet(() -> webContext.findById(type, id)); } @Override public List findAllByHtmlTag(Class type, String tag) { return attemptAndGet(() -> webContext.findAllByHtmlTag(type, tag)); } @Override public List findAllByCss(Class type, String css) { return attemptAndGet(() -> webContext.findAllByCss(type, css)); } @Override public List findAllByClassName(Class type, String className) { return attemptAndGet(() -> webContext.findAllByClassName(type, className)); } @Override public T findByName(Class type, String name) { return attemptAndGet(() -> webContext.findByName(type, name)); } @Override public T findByXPath(Class type, String xpath) { return attemptAndGet(() -> webContext.findByXPath(type, xpath)); } @Override public T findByLinkText(Class type, String linkText) { return attemptAndGet(() -> webContext.findByLinkText(type, linkText)); } @Override public T findByChained(Class type, Locator... locators) { return attemptAndGet(() -> webContext.findByChained(type, locators)); } @Override public T findByTextContent(Class type, String textContent) { return attemptAndGet(() -> webContext.findByTextContent(type, textContent)); } @Override public T findByPartialTextContent(Class type, String partialTextContent) { return attemptAndGet(() -> webContext.findByPartialTextContent(type, partialTextContent)); } @Override public T findByHtmlTag(Class type, String tag) { return attemptAndGet(() -> webContext.findByHtmlTag(type, tag)); } @Override public T findByCss(Class type, String css) { return attemptAndGet(() -> webContext.findByCss(type, css)); } @Override public T findByClassName(Class type, String className) { return attemptAndGet(() -> webContext.findByClassName(type, className)); } @Override public T findByNested(Class type, Element parent, Locator child) { return attemptAndGet(() -> webContext.findByNested(type, parent, child)); } @Override public List findAllByAttribute(Class type, String attribute, String value) { return attemptAndGet(() -> webContext.findAllByAttribute(type, attribute, value)); } @Override public T findByAttribute(Class type, String attribute, String value) { return attemptAndGet(() -> webContext.findByAttribute(type, attribute, value)); } @Override public List findAllByView(Class type, View view) { return attemptAndGet(() -> webContext.findAllByView(type, view)); } @Override public T findByView(Class type, View view) { return attemptAndGet(() -> webContext.findByView(type, view)); } @Override public List findAllByTitle(Class type, String title) { return attemptAndGet(() -> webContext.findAllByTitle(type, title)); } @Override public T findByTitle(Class type, String title) { return attemptAndGet(() -> webContext.findByTitle(type, title)); } @Override public List findAllByUrl(Class type, Matcher urlMatcher) { return attemptAndGet(() -> webContext.findAllByUrl(type, urlMatcher)); } @Override public T findByUrl(Class type, Matcher urlMatcher) { return attemptAndGet(() -> webContext.findByUrl(type, urlMatcher)); } @Override public TargetedWebDriver getWrappedDriver() { return driver; } /** * Wrapper for interacting with a targeted driver that may or may not actually be present. */ private void attempt(Runnable action) { try { action.run(); } catch (NoSuchFrameException | NoSuchWindowException | SessionNotFoundException e) { throw new FindableNotPresentException(this, e); } } /** * Wrapper for interacting with a targeted driver that may or may not actually be present. * Returns a result. */ private T attemptAndGet(Supplier action) { try { return action.get(); } catch (NoSuchFrameException | NoSuchWindowException | SessionNotFoundException e) { throw new FindableNotPresentException(this, e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy