diff --git a/.gitignore b/.gitignore index 0e640b8..7a87ce5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ .classpath *.iml /bin/ -.idea \ No newline at end of file +.idea +*.releaseBackup +release.properties diff --git a/.travis.yml b/.travis.yml index 963ad52..8ecc9f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,17 @@ language: java jdk: - oraclejdk8 +sudo: false before_script: - git clone -b travis `git config --get remote.origin.url` target/travis - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" - -script: '[ ${TRAVIS_PULL_REQUEST} = ''false'' ] && mvn clean deploy -P sonatype-oss-release -Dgpg.skip=true --settings target/travis/settings.xml || mvn clean verify --settings target/travis/settings.xml' +script: '[ ${TRAVIS_PULL_REQUEST} = ''false'' ] && mvn clean deploy --settings target/travis/settings.xml || mvn clean verify --settings target/travis/settings.xml' after_success: - - mvn clean jacoco:prepare-agent test jacoco:report coveralls:jacoco + - mvn clean test jacoco:report coveralls:report branches: only: diff --git a/README.md b/README.md index 49a4428..ce7103b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ maven com.redhat.darcy darcy-webdriver - 0.2.2-SNAPSHOT + 0.4.0-SNAPSHOT ``` diff --git a/pom.xml b/pom.xml index fe63abb..5257b08 100644 --- a/pom.xml +++ b/pom.xml @@ -1,103 +1,238 @@ 4.0.0 - - org.sonatype.oss - oss-parent - 7 - - com.redhat.darcy darcy-webdriver - 0.2.2-SNAPSHOT + 0.4.0-SNAPSHOT jar ${project.groupId}:${project.artifactId} An implementation of darcy and darcy-web that uses Selenium WebDriver as the automation library backend. https://github.com/darcy-framework/darcy-webdriver - - - GNU General Public License, Version 3 - https://www.gnu.org/licenses/gpl-3.0.txt - repo - - + + 0.1.2-SNAPSHOT + 0.3.0-SNAPSHOT + 3.4.0 + 1.5 + 4.0-beta5 + 3.3.1 - - scm:git:https://github.com/darcy-framework/darcy-webdriver.git - scm:git:git@github.com:darcy-framework/darcy-webdriver.git - https://github.com/darcy-framework/darcy-webdriver - + 4.12 + 2.0.26-beta - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - true - - 1.8 - 1.8 - - - - org.eluder.coveralls - coveralls-maven-plugin - 2.2.0 - - - org.jacoco - jacoco-maven-plugin - 0.7.1.201405082137 - - - + 3.5 + 2.19.1 + 2.4 + 2.5.3 + 2.10.3 + 4.1.0 + 0.7.5.201505241946 + 1.6 + 1.6.6 + + 3.0.4 + UTF-8 + com.redhat.darcy darcy-web - 0.2.2-SNAPSHOT + 0.3.0 com.redhat.synq synq - 0.1.2-SNAPSHOT + 0.1.3 org.seleniumhq.selenium selenium-server - 2.45.0 + ${version.selenium} com.google.guiceberry guiceberry - 3.3.1 + ${version.guiceberry} com.google.inject guice - 4.0-beta5 + ${version.guice} com.opera operadriver - 1.5 + ${version.operadriver} + + + org.apache.commons + commons-exec + + org.mockito mockito-core - 2.0.26-beta + ${version.mockito} test junit junit - 4.11 + ${version.junit} test + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${version.maven-compiler-plugin} + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + ${version.maven-surefire-plugin} + + + org.apache.maven.plugins + maven-source-plugin + ${version.maven-source-plugin} + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-release-plugin + ${version.maven-release-plugin} + + true + false + release + deploy + + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${version.nexus-staging-maven-plugin} + true + + ossrh + https://oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${version.maven-javadoc-plugin} + + + attach-javadocs + + jar + + + + + + org.eluder.coveralls + coveralls-maven-plugin + ${version.coveralls-maven-plugin} + + + org.jacoco + jacoco-maven-plugin + ${version.jacoco-maven-plugin} + + + prepare-agent + + prepare-agent + + + + + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + ${version.maven-gpg-plugin} + + + sign-artifacts + verify + + sign + + + + + + + + + + + ${prerequisites.maven} + + + + scm:git:https://github.com/darcy-framework/darcy-webdriver.git + scm:git:git@github.com:darcy-framework/darcy-webdriver.git + https://github.com/darcy-framework/darcy-webdriver + HEAD + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + + + + GNU General Public License, Version 3 + https://www.gnu.org/licenses/gpl-3.0.txt + repo + + + + + + alechenninger + Alec Henninger + alechenninger@gmail.com + Red Hat + + architect + developer + + -5 + + diff --git a/src/main/java/com/redhat/darcy/webdriver/WebDriverBrowser.java b/src/main/java/com/redhat/darcy/webdriver/WebDriverBrowser.java index fb6bea2..3f2dc56 100644 --- a/src/main/java/com/redhat/darcy/webdriver/WebDriverBrowser.java +++ b/src/main/java/com/redhat/darcy/webdriver/WebDriverBrowser.java @@ -21,6 +21,7 @@ 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; @@ -41,10 +42,14 @@ 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.NoSuchSessionException; import org.openqa.selenium.NoSuchWindowException; -import org.openqa.selenium.remote.SessionNotFoundException; +import org.openqa.selenium.OutputType; +import java.io.IOException; +import java.io.OutputStream; import java.util.List; import java.util.Objects; import java.util.function.Supplier; @@ -172,6 +177,18 @@ public void closeAll() { 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); @@ -327,6 +344,16 @@ 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; @@ -338,7 +365,7 @@ public TargetedWebDriver getWrappedDriver() { private void attempt(Runnable action) { try { action.run(); - } catch (NoSuchFrameException | NoSuchWindowException | SessionNotFoundException e) { + } catch (NoSuchFrameException | NoSuchWindowException | NoSuchSessionException e) { throw new FindableNotPresentException(this, e); } } @@ -350,7 +377,7 @@ private void attempt(Runnable action) { private T attemptAndGet(Supplier action) { try { return action.get(); - } catch (NoSuchFrameException | NoSuchWindowException | SessionNotFoundException e) { + } catch (NoSuchFrameException | NoSuchWindowException | NoSuchSessionException e) { throw new FindableNotPresentException(this, e); } } diff --git a/src/main/java/com/redhat/darcy/webdriver/WebDriverBrowserFactory.java b/src/main/java/com/redhat/darcy/webdriver/WebDriverBrowserFactory.java index 55c3db8..70e7cde 100644 --- a/src/main/java/com/redhat/darcy/webdriver/WebDriverBrowserFactory.java +++ b/src/main/java/com/redhat/darcy/webdriver/WebDriverBrowserFactory.java @@ -55,7 +55,7 @@ protected static Browser makeBrowser(WebDriver driver, ElementConstructorMap ele CachingTargetLocator cachingLocator = new CachingTargetLocator(target, driver); WebDriverParentContext context = new TargetedWebDriverParentContext(target, cachingLocator, - elementMap); + driver::getWindowHandles, elementMap); return context.findById(Browser.class, currentWindowHandle); } diff --git a/src/main/java/com/redhat/darcy/webdriver/WebDriverParentContext.java b/src/main/java/com/redhat/darcy/webdriver/WebDriverParentContext.java index e6808f0..8b916d9 100644 --- a/src/main/java/com/redhat/darcy/webdriver/WebDriverParentContext.java +++ b/src/main/java/com/redhat/darcy/webdriver/WebDriverParentContext.java @@ -25,8 +25,9 @@ import com.redhat.darcy.ui.internal.FindsByTitle; import com.redhat.darcy.ui.internal.FindsByView; import com.redhat.darcy.web.api.Alert; +import com.redhat.darcy.web.internal.FindsByUrl; public interface WebDriverParentContext extends ParentContext, FindsById, FindsByName, FindsByView, - FindsByTitle { + FindsByTitle, FindsByUrl { Alert alert(); } diff --git a/src/main/java/com/redhat/darcy/webdriver/internal/DelegatingWebContext.java b/src/main/java/com/redhat/darcy/webdriver/internal/DelegatingWebContext.java index 359e53a..7af97b1 100644 --- a/src/main/java/com/redhat/darcy/webdriver/internal/DelegatingWebContext.java +++ b/src/main/java/com/redhat/darcy/webdriver/internal/DelegatingWebContext.java @@ -39,9 +39,12 @@ import com.redhat.darcy.web.internal.FindsByClassName; import com.redhat.darcy.web.internal.FindsByCss; import com.redhat.darcy.web.internal.FindsByHtmlTag; +import com.redhat.darcy.web.internal.FindsByUrl; import com.redhat.darcy.webdriver.WebDriverElementContext; import com.redhat.darcy.webdriver.WebDriverParentContext; +import org.hamcrest.Matcher; + import java.util.List; import java.util.Objects; @@ -382,6 +385,28 @@ public T findByTitle(Class type, String title) { } } + @Override + public List findAllByUrl(Class type, Matcher urlMatcher) { + try { + FindsByUrl context = (FindsByUrl) contextForType(type); + + return context.findAllByUrl(type, urlMatcher); + } catch (ClassCastException e) { + throw unsupportedLocatorForType("url matching, " + urlMatcher, type); + } + } + + @Override + public T findByUrl(Class type, Matcher urlMatcher) { + try { + FindsByUrl context = (FindsByUrl) contextForType(type); + + return context.findByUrl(type, urlMatcher); + } catch (ClassCastException e) { + throw unsupportedLocatorForType("url matching, " + urlMatcher, type); + } + } + /** * Returns the ElementContext or PraentContext depending on if the type of thing we're looking * for is an element or a context. diff --git a/src/main/java/com/redhat/darcy/webdriver/internal/ForwardingTargetedAlert.java b/src/main/java/com/redhat/darcy/webdriver/internal/ForwardingTargetedAlert.java index d56ad57..8f1deed 100644 --- a/src/main/java/com/redhat/darcy/webdriver/internal/ForwardingTargetedAlert.java +++ b/src/main/java/com/redhat/darcy/webdriver/internal/ForwardingTargetedAlert.java @@ -61,6 +61,11 @@ public void sendKeys(String keysToSend) { alert().sendKeys(keysToSend); } + @Override + public void setCredentials(Credentials credentials) { + alert().setCredentials(credentials); + } + @Override public void authenticateUsing(Credentials credentials) { alert().authenticateUsing(credentials); diff --git a/src/main/java/com/redhat/darcy/webdriver/internal/ForwardingTargetedWebDriver.java b/src/main/java/com/redhat/darcy/webdriver/internal/ForwardingTargetedWebDriver.java index 8c345eb..b3ed627 100644 --- a/src/main/java/com/redhat/darcy/webdriver/internal/ForwardingTargetedWebDriver.java +++ b/src/main/java/com/redhat/darcy/webdriver/internal/ForwardingTargetedWebDriver.java @@ -35,7 +35,6 @@ import org.openqa.selenium.internal.FindsByTagName; import org.openqa.selenium.internal.FindsByXPath; import org.openqa.selenium.internal.WrapsDriver; -import org.openqa.selenium.remote.SessionNotFoundException; import java.util.List; import java.util.Objects; @@ -44,7 +43,7 @@ public class ForwardingTargetedWebDriver implements TargetedWebDriver, FindsByClassName, FindsByCssSelector, FindsById, FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath, - TakesScreenshot, JavascriptExecutor, WrapsDriver { + JavascriptExecutor, WrapsDriver { private final TargetLocator locator; private final WebDriverTarget target; @@ -71,7 +70,7 @@ public boolean isPresent() { try { driver().getTitle(); return true; - } catch (NotFoundException | SessionNotFoundException e) { + } catch (NotFoundException e) { return false; } } diff --git a/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebDriver.java b/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebDriver.java index 942b7b1..978108a 100644 --- a/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebDriver.java +++ b/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebDriver.java @@ -21,6 +21,7 @@ import com.redhat.darcy.ui.api.elements.Findable; +import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; /** @@ -33,7 +34,7 @@ * Elements found by this driver should also be targeted. That is, elements are associated with a * driver and target and will ensure the driver is switched before interacting with the element. */ -public interface TargetedWebDriver extends WebDriver, Findable { +public interface TargetedWebDriver extends WebDriver, Findable, TakesScreenshot { WebDriverTarget getWebDriverTarget(); /** diff --git a/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebDriverParentContext.java b/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebDriverParentContext.java index 0401233..8f0f122 100644 --- a/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebDriverParentContext.java +++ b/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebDriverParentContext.java @@ -32,16 +32,18 @@ import com.redhat.darcy.webdriver.WebDriverBrowser; import com.redhat.darcy.webdriver.WebDriverParentContext; +import org.hamcrest.Matcher; import org.openqa.selenium.WebDriver.TargetLocator; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Set; import java.util.function.Supplier; /** - * {@link ParentContext} for {@link TargetedWebDriver}s that instantiates other + * {@link ParentContext} for {@link TargetedWebDriver}s that instantiates other * {@link com.redhat.darcy.webdriver.WebDriverBrowser}s with {@link TargetedWebDriver}s assigned to * them that point to the found driver. */ @@ -49,6 +51,12 @@ public class TargetedWebDriverParentContext implements WebDriverParentContext { private final WebDriverTarget myTarget; private final TargetLocator locator; private final ElementConstructorMap elementMap; + private final KnowsWindowHandles knowsWindowHandles; + + @FunctionalInterface + public interface KnowsWindowHandles { + Set getWindowHandles(); + } /** * @param myTarget Parent contexts must be targeted because frame targets depend on another, @@ -56,13 +64,16 @@ public class TargetedWebDriverParentContext implements WebDriverParentContext { * associated with, because this state is used when finding frames. * @param locator Means of finding other WebDrivers for new targets. Each new browser shares the * same locator. - * @param elementMap Each new browser must have an element constructor map so it may create - * element objects. Each new browser shares the same map. + * @param knowsWindowHandles Finds open windows' handles. Must be associated with the same + * driver as the {@code locator}. + * @param elementMap Each new browser must have an element conFunction or type which can provide the current set of window + * handles of the driver associated with the locator.structor map so it may create */ public TargetedWebDriverParentContext(WebDriverTarget myTarget, TargetLocator locator, - ElementConstructorMap elementMap) { + KnowsWindowHandles knowsWindowHandles, ElementConstructorMap elementMap) { this.myTarget = myTarget; this.locator = locator; + this.knowsWindowHandles = knowsWindowHandles; this.elementMap = elementMap; } @@ -120,7 +131,7 @@ public List findAllByView(Class type, View view) { + "available frames."); } - return (List) new LazyList(new FoundByViewSupplier(view)); + return (List) new LazyList<>(new FoundByViewSupplier(view)); } @SuppressWarnings("unchecked") @@ -150,7 +161,7 @@ public List findAllByTitle(Class type, String title) { + "available frames."); } - return (List) new LazyList(new FoundByTitleSupplier(title)); + return (List) new LazyList<>(new FoundByTitleSupplier(title)); } @SuppressWarnings("unchecked") @@ -168,6 +179,34 @@ public T findByTitle(Class type, String title) { return (T) newBrowser(WebDriverTargets.windowByTitle(title)); } + @Override + public List findAllByUrl(Class type, Matcher urlMatcher) { + if (!type.isAssignableFrom(WebDriverBrowser.class)) { + throw new DarcyException("Cannot find contexts of type: " + type); + } + + if (Frame.class.equals(type)) { + throw new DarcyException("Cannot find Frames by url. Unable to iterate through all " + + "available frames."); + } + + return (List) new LazyList<>(new FoundByUrlSupplier(urlMatcher)); + } + + @Override + public T findByUrl(Class type, Matcher urlMatcher) { + if (!type.isAssignableFrom(WebDriverBrowser.class)) { + throw new DarcyException("Cannot find contexts of type: " + type); + } + + if (Frame.class.equals(type)) { + throw new DarcyException("Cannot find Frames by url. Unable to iterate through all " + + "available frames."); + } + + return (T) newBrowser(WebDriverTargets.windowByUrl(urlMatcher)); + } + @Override public boolean equals(Object o) { if (this == o) { @@ -200,7 +239,7 @@ private WebDriverBrowser newBrowser(WebDriverTarget target) { TargetedWebDriver targetedDriver = new ForwardingTargetedWebDriver(locator, target); return new WebDriverBrowser(targetedDriver, - new TargetedWebDriverParentContext(target, locator, elementMap), + new TargetedWebDriverParentContext(target, locator, knowsWindowHandles, elementMap), new DefaultWebDriverElementContext(targetedDriver, elementMap)); } @@ -215,7 +254,7 @@ class FoundByViewSupplier implements Supplier> { public List get() { List found = new ArrayList<>(); - for (String windowHandle : locator.defaultContent().getWindowHandles()) { + for (String windowHandle : knowsWindowHandles.getWindowHandles()) { Browser forWindowHandle = findById(Browser.class, windowHandle); ElementContext priorContext = view.getContext(); @@ -245,7 +284,7 @@ class FoundByTitleSupplier implements Supplier> { public List get() { List found = new ArrayList<>(); - for (String windowHandle : locator.defaultContent().getWindowHandles()) { + for (String windowHandle : knowsWindowHandles.getWindowHandles()) { if (locator.window(windowHandle).getTitle().equals(title)) { found.add(findById(Browser.class, windowHandle)); } @@ -254,4 +293,25 @@ public List get() { return found; } } + + private class FoundByUrlSupplier implements Supplier> { + private final Matcher urlMatcher; + + public FoundByUrlSupplier(Matcher urlMatcher) { + this.urlMatcher = urlMatcher; + } + + @Override + public List get() { + List found = new ArrayList<>(); + + for (String windowHandle : knowsWindowHandles.getWindowHandles()) { + if (urlMatcher.matches(locator.window(windowHandle).getCurrentUrl())) { + found.add(findById(Browser.class, windowHandle)); + } + } + + return found; + } + } } diff --git a/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebElement.java b/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebElement.java index 341a08b..242b230 100644 --- a/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebElement.java +++ b/src/main/java/com/redhat/darcy/webdriver/internal/TargetedWebElement.java @@ -23,7 +23,10 @@ import org.openqa.selenium.By; import org.openqa.selenium.Dimension; +import org.openqa.selenium.OutputType; import org.openqa.selenium.Point; +import org.openqa.selenium.Rectangle; +import org.openqa.selenium.WebDriverException; import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.FindsByClassName; import org.openqa.selenium.internal.FindsByCssSelector; @@ -124,6 +127,11 @@ public Dimension getSize() { return element().getSize(); } + @Override + public Rectangle getRect() { + return element().getRect(); + } + @Override public String getCssValue(String propertyName) { return element().getCssValue(propertyName); @@ -209,6 +217,12 @@ public List findElementsByXPath(String using) { return targetedWebElements(((FindsByXPath) element()).findElementsByXPath(using)); } + + @Override + public X getScreenshotAs(OutputType outputType) throws WebDriverException { + return element().getScreenshotAs(outputType); + } + /** * @return The backing {@link org.openqa.selenium.WebElement}, with the driver switched to the * appropriate target. diff --git a/src/main/java/com/redhat/darcy/webdriver/internal/WebDriverTargets.java b/src/main/java/com/redhat/darcy/webdriver/internal/WebDriverTargets.java index 062d04f..208eb75 100644 --- a/src/main/java/com/redhat/darcy/webdriver/internal/WebDriverTargets.java +++ b/src/main/java/com/redhat/darcy/webdriver/internal/WebDriverTargets.java @@ -26,6 +26,7 @@ import com.redhat.darcy.util.Caching; import com.redhat.darcy.web.api.Browser; +import org.hamcrest.Matcher; import org.openqa.selenium.NoSuchWindowException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver.TargetLocator; @@ -65,6 +66,10 @@ public static WebDriverTarget windowByTitle(String title) { return new WindowTitleWebDriverTarget(title); } + public static WebDriverTarget windowByUrl(Matcher urlMatcher) { + return new WindowUrlWebDriverTarget(urlMatcher); + } + /** * Determines the parent target of the specified * {@link com.redhat.darcy.webdriver.internal.WebDriverTarget}. If the target has no parent @@ -348,8 +353,11 @@ public boolean equals(Object o) { @Override public String toString() { - return "ViewWebDriverTarget: {view: " + view + ", parentContext: " - + parentContext + "}"; + return "ViewWebDriverTarget{" + + "view=" + view + + ", parentContext=" + parentContext + + ", windowHandle='" + windowHandle + '\'' + + '}'; } private String findWindow(TargetLocator targetLocator) { @@ -416,6 +424,7 @@ public int hashCode() { public String toString() { return "WindowTitleWebDriverTarget{" + "title='" + title + '\'' + + ", windowHandle='" + windowHandle + '\'' + '}'; } @@ -429,4 +438,68 @@ private String findWindow(TargetLocator targetLocator) { throw new NoSuchWindowException("No window in driver found which has title: " + title); } } + + public static class WindowUrlWebDriverTarget implements WebDriverTarget, Caching { + private final Matcher urlMatcher; + + /** + * Stores window handle of window which has the title so subsequent lookups always refer to + * the same window. + */ + private String windowHandle; + + public WindowUrlWebDriverTarget(Matcher urlMatcher) { + this.urlMatcher = Objects.requireNonNull(urlMatcher, "urlMatcher"); + } + + @Override + public WebDriver switchTo(TargetLocator targetLocator) { + if (windowHandle == null) { + windowHandle = findWindow(targetLocator); + } + + return targetLocator.window(windowHandle); + } + + @Override + public void invalidateCache() { + windowHandle = null; + } + + private String findWindow(TargetLocator targetLocator) { + for (String windowHandle : targetLocator.defaultContent().getWindowHandles()) { + if (urlMatcher.matches(targetLocator.window(windowHandle).getCurrentUrl())) { + return windowHandle; + } + } + + throw new NoSuchWindowException("No window in driver found which has url matching: " + urlMatcher); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WindowUrlWebDriverTarget that = (WindowUrlWebDriverTarget) o; + return Objects.equals(urlMatcher, that.urlMatcher) && + Objects.equals(windowHandle, that.windowHandle); + } + + @Override + public int hashCode() { + return Objects.hash(urlMatcher, windowHandle); + } + + @Override + public String toString() { + return "WindowUrlWebDriverTarget{" + + "urlMatcher=" + urlMatcher + + ", windowHandle='" + windowHandle + '\'' + + '}'; + } + } } diff --git a/src/main/java/com/redhat/darcy/webdriver/locators/ByChained.java b/src/main/java/com/redhat/darcy/webdriver/locators/ByChained.java index d572543..81a884d 100644 --- a/src/main/java/com/redhat/darcy/webdriver/locators/ByChained.java +++ b/src/main/java/com/redhat/darcy/webdriver/locators/ByChained.java @@ -71,7 +71,7 @@ public List findElements(SearchContext context) { } } - return found.stream() + return found == null ? null : found.stream() .map(WebDriverElement::getWrappedElement) .collect(Collectors.toList()); } diff --git a/src/main/java/com/redhat/darcy/webdriver/locators/ByVisibleText.java b/src/main/java/com/redhat/darcy/webdriver/locators/ByVisibleText.java index 90656e0..f93c702 100644 --- a/src/main/java/com/redhat/darcy/webdriver/locators/ByVisibleText.java +++ b/src/main/java/com/redhat/darcy/webdriver/locators/ByVisibleText.java @@ -48,7 +48,7 @@ public ByVisibleText(String text) { @Override public List findElements(SearchContext context) { - List result = new ArrayList(); + List result = new ArrayList<>(); // First find any elements that *contain* this text. List elems = byPartialVisibleText.findElements(context); diff --git a/src/main/java/com/redhat/darcy/webdriver/locators/ByVisibleTextIgnoreCase.java b/src/main/java/com/redhat/darcy/webdriver/locators/ByVisibleTextIgnoreCase.java index fb4c55a..842dc4d 100644 --- a/src/main/java/com/redhat/darcy/webdriver/locators/ByVisibleTextIgnoreCase.java +++ b/src/main/java/com/redhat/darcy/webdriver/locators/ByVisibleTextIgnoreCase.java @@ -45,7 +45,7 @@ public ByVisibleTextIgnoreCase(String text) { @Override public List findElements(SearchContext context) { - List result = new ArrayList(); + List result = new ArrayList<>(); // First find any elements that *contain* this text. List elems = byPartialVisibleTextIgnoreCase.findElements(context); @@ -60,7 +60,7 @@ public List findElements(SearchContext context) { } } - if (result.size() == 0) { + if (result.isEmpty()) { throw new NoSuchElementException("Cannot locate an element using " + toString()); } diff --git a/src/test/java/com/redhat/darcy/webdriver/ChromeBrowserFactoryTest.java b/src/test/java/com/redhat/darcy/webdriver/ChromeBrowserFactoryTest.java index 0ebe6e4..679e816 100644 --- a/src/test/java/com/redhat/darcy/webdriver/ChromeBrowserFactoryTest.java +++ b/src/test/java/com/redhat/darcy/webdriver/ChromeBrowserFactoryTest.java @@ -26,25 +26,34 @@ import com.redhat.darcy.webdriver.internal.CachingTargetLocator; import com.redhat.darcy.webdriver.internal.ForwardingTargetedWebDriver; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.chrome.ChromeDriver; public class ChromeBrowserFactoryTest { + private WebDriverBrowser browser; + @Before public void checkForDriver() { assumeNotNull(System.getProperty("webdriver.chrome.driver")); } + @After + public void closeBrowser() { + if (browser != null) { + browser.close(); + } + } + @Test public void shouldBeInstanceOfUntargetedChromeDriver() { WebDriverBrowserFactory browserFactory = new ChromeBrowserFactory(); - WebDriverBrowser browser = (WebDriverBrowser) browserFactory.newBrowser(); + browser = (WebDriverBrowser) browserFactory.newBrowser(); ForwardingTargetedWebDriver webDriver = (ForwardingTargetedWebDriver) browser.getWrappedDriver(); CachingTargetLocator targetLocator = (CachingTargetLocator) webDriver.getTargetLocator(); assertThat(targetLocator.getUntargetedDriver(), instanceOf(ChromeDriver.class)); - browser.close(); } } diff --git a/src/test/java/com/redhat/darcy/webdriver/FirefoxBrowserFactoryTest.java b/src/test/java/com/redhat/darcy/webdriver/FirefoxBrowserFactoryTest.java index 1a33673..25c722e 100644 --- a/src/test/java/com/redhat/darcy/webdriver/FirefoxBrowserFactoryTest.java +++ b/src/test/java/com/redhat/darcy/webdriver/FirefoxBrowserFactoryTest.java @@ -21,26 +21,38 @@ import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertThat; +import static org.junit.Assume.assumeNotNull; import static org.junit.Assume.assumeTrue; import com.redhat.darcy.webdriver.internal.CachingTargetLocator; import com.redhat.darcy.webdriver.internal.ForwardingTargetedWebDriver; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.firefox.FirefoxDriver; public class FirefoxBrowserFactoryTest { + WebDriverBrowser browser; + @Before public void checkForDriver() { assumeTrue(System.getProperty("java.class.path").contains("firefox-driver")); + assumeNotNull(System.getProperty("webdriver.gecko.driver")); + } + + @After + public void closeBrowser() { + if (browser != null) { + browser.close(); + } } @Test public void shouldBeInstanceOfUntargetedFirefoxDriver() { WebDriverBrowserFactory browserFactory = new FirefoxBrowserFactory(); - WebDriverBrowser browser = (WebDriverBrowser) browserFactory.newBrowser(); + browser = (WebDriverBrowser) browserFactory.newBrowser(); ForwardingTargetedWebDriver webDriver = (ForwardingTargetedWebDriver) browser.getWrappedDriver(); CachingTargetLocator targetLocator = (CachingTargetLocator) webDriver.getTargetLocator(); diff --git a/src/test/java/com/redhat/darcy/webdriver/HtmlUnitBrowserFactoryTest.java b/src/test/java/com/redhat/darcy/webdriver/HtmlUnitBrowserFactoryTest.java index 5a2b370..0d7edf2 100644 --- a/src/test/java/com/redhat/darcy/webdriver/HtmlUnitBrowserFactoryTest.java +++ b/src/test/java/com/redhat/darcy/webdriver/HtmlUnitBrowserFactoryTest.java @@ -25,19 +25,27 @@ import com.redhat.darcy.webdriver.internal.CachingTargetLocator; import com.redhat.darcy.webdriver.internal.ForwardingTargetedWebDriver; +import org.junit.After; import org.junit.Test; import org.openqa.selenium.htmlunit.HtmlUnitDriver; public class HtmlUnitBrowserFactoryTest { + private WebDriverBrowser browser; + + @After + public void closeDriver() { + if (browser != null) { + browser.close(); + } + } @Test public void shouldBeInstanceOfUntargetedHtmlUnitDriver() { WebDriverBrowserFactory browserFactory = new HtmlUnitBrowserFactory(); - WebDriverBrowser browser = (WebDriverBrowser) browserFactory.newBrowser(); + browser = (WebDriverBrowser) browserFactory.newBrowser(); ForwardingTargetedWebDriver webDriver = (ForwardingTargetedWebDriver) browser.getWrappedDriver(); CachingTargetLocator targetLocator = (CachingTargetLocator) webDriver.getTargetLocator(); assertThat(targetLocator.getUntargetedDriver(), instanceOf(HtmlUnitDriver.class)); - browser.close(); } } diff --git a/src/test/java/com/redhat/darcy/webdriver/InternetExplorerBrowserFactoryTest.java b/src/test/java/com/redhat/darcy/webdriver/InternetExplorerBrowserFactoryTest.java index 0b01919..d8f76a3 100644 --- a/src/test/java/com/redhat/darcy/webdriver/InternetExplorerBrowserFactoryTest.java +++ b/src/test/java/com/redhat/darcy/webdriver/InternetExplorerBrowserFactoryTest.java @@ -26,25 +26,34 @@ import com.redhat.darcy.webdriver.internal.CachingTargetLocator; import com.redhat.darcy.webdriver.internal.ForwardingTargetedWebDriver; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.ie.InternetExplorerDriver; public class InternetExplorerBrowserFactoryTest { + private WebDriverBrowser browser; + @Before public void checkForDriver() { assumeNotNull(System.getProperty("webdriver.ie.driver")); } + @After + public void closeBrowser() { + if (browser != null) { + browser.close(); + } + } + @Test public void shouldBeInstanceOfUntargetedInternetExplorerDriver() { WebDriverBrowserFactory browserFactory = new InternetExplorerBrowserFactory(); - WebDriverBrowser browser = (WebDriverBrowser) browserFactory.newBrowser(); + browser = (WebDriverBrowser) browserFactory.newBrowser(); ForwardingTargetedWebDriver webDriver = (ForwardingTargetedWebDriver) browser.getWrappedDriver(); CachingTargetLocator targetLocator = (CachingTargetLocator) webDriver.getTargetLocator(); assertThat(targetLocator.getUntargetedDriver(), instanceOf(InternetExplorerDriver.class)); - browser.close(); } } diff --git a/src/test/java/com/redhat/darcy/webdriver/OperaBrowserFactoryTest.java b/src/test/java/com/redhat/darcy/webdriver/OperaBrowserFactoryTest.java index a4d7e20..5422d9e 100644 --- a/src/test/java/com/redhat/darcy/webdriver/OperaBrowserFactoryTest.java +++ b/src/test/java/com/redhat/darcy/webdriver/OperaBrowserFactoryTest.java @@ -28,24 +28,34 @@ import com.redhat.darcy.webdriver.internal.ForwardingTargetedWebDriver; import com.opera.core.systems.OperaDriver; +import org.junit.After; import org.junit.Before; import org.junit.Test; public class OperaBrowserFactoryTest { + private WebDriverBrowser browser; + @Before public void checkForDriver() { assumeTrue(System.getProperty("java.class.path").contains("operadriver")); assumeNotNull(System.getProperty("webdriver.opera.driver")); } + + @After + public void closeDriver() { + if (browser != null) { + browser.close(); + } + } + @Test public void shouldBeInstanceOfUntargetedOperaDriver() { WebDriverBrowserFactory browserFactory = new OperaBrowserFactory(); - WebDriverBrowser browser = (WebDriverBrowser) browserFactory.newBrowser(); + browser = (WebDriverBrowser) browserFactory.newBrowser(); ForwardingTargetedWebDriver webDriver = (ForwardingTargetedWebDriver) browser.getWrappedDriver(); CachingTargetLocator targetLocator = (CachingTargetLocator) webDriver.getTargetLocator(); assertThat(targetLocator.getUntargetedDriver(), instanceOf(OperaDriver.class)); - browser.close(); } } diff --git a/src/test/java/com/redhat/darcy/webdriver/SafariBrowserFactoryTest.java b/src/test/java/com/redhat/darcy/webdriver/SafariBrowserFactoryTest.java index d1155e4..e788a0c 100644 --- a/src/test/java/com/redhat/darcy/webdriver/SafariBrowserFactoryTest.java +++ b/src/test/java/com/redhat/darcy/webdriver/SafariBrowserFactoryTest.java @@ -26,25 +26,34 @@ import com.redhat.darcy.webdriver.internal.CachingTargetLocator; import com.redhat.darcy.webdriver.internal.ForwardingTargetedWebDriver; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.safari.SafariDriver; public class SafariBrowserFactoryTest { + private WebDriverBrowser browser; + @Before public void checkForDriver() { assumeNotNull(System.getProperty("webdriver.safari.driver")); } + @After + public void closeDriver() { + if (browser != null) { + browser.close(); + } + } + @Test public void shouldBeInstanceOfUntargetedSafariDriver() { WebDriverBrowserFactory browserFactory = new SafariBrowserFactory(); - WebDriverBrowser browser = (WebDriverBrowser) browserFactory.newBrowser(); + browser = (WebDriverBrowser) browserFactory.newBrowser(); ForwardingTargetedWebDriver webDriver = (ForwardingTargetedWebDriver) browser.getWrappedDriver(); CachingTargetLocator targetLocator = (CachingTargetLocator) webDriver.getTargetLocator(); assertThat(targetLocator.getUntargetedDriver(), instanceOf(SafariDriver.class)); - browser.close(); } } diff --git a/src/test/java/com/redhat/darcy/webdriver/TakeScreenshotTest.java b/src/test/java/com/redhat/darcy/webdriver/TakeScreenshotTest.java new file mode 100644 index 0000000..1b5157e --- /dev/null +++ b/src/test/java/com/redhat/darcy/webdriver/TakeScreenshotTest.java @@ -0,0 +1,110 @@ +package com.redhat.darcy.webdriver; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.redhat.darcy.ui.DarcyException; +import com.redhat.darcy.ui.FindableNotPresentException; +import com.redhat.darcy.web.api.Browser; +import com.redhat.darcy.webdriver.internal.TargetedWebDriver; +import com.redhat.darcy.webdriver.testing.doubles.StubWebDriverElementContext; +import com.redhat.darcy.webdriver.testing.doubles.StubWebDriverParentContext; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.InOrder; +import org.openqa.selenium.NoSuchWindowException; +import org.openqa.selenium.OutputType; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +@RunWith(JUnit4.class) +public class TakeScreenshotTest { + @Test + public void shouldTakeScreenshotAndWriteToOutputStream() throws IOException { + TargetedWebDriver mockedDriver = mock(TargetedWebDriver.class); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Browser browser = new WebDriverBrowser(mockedDriver, + new StubWebDriverParentContext(), + new StubWebDriverElementContext()); + + byte[] data = new byte[] { 1, 2, 3 }; + + when(mockedDriver.getScreenshotAs(OutputType.BYTES)) + .thenReturn(data); + + browser.takeScreenshot(baos); + + assertThat(baos.toByteArray(), equalTo(data)); + } + + @Test + public void shouldTakeScreenshotAndWriteToOutputStreamThenFlushAndCloseInOrder() throws IOException { + TargetedWebDriver mockedDriver = mock(TargetedWebDriver.class); + OutputStream outputStream = mock(OutputStream.class); + Browser browser = new WebDriverBrowser(mockedDriver, + new StubWebDriverParentContext(), + new StubWebDriverElementContext()); + + InOrder inOrder = inOrder(outputStream); + + browser.takeScreenshot(outputStream); + + inOrder.verify(outputStream).write(any(byte[].class)); + inOrder.verify(outputStream).flush(); + inOrder.verify(outputStream).close(); + } + + @SuppressWarnings("unchecked") + @Test + public void shouldThrowFindableNotPresentExceptionIfDriverIsNotPresent() throws IOException { + TargetedWebDriver driver = mock(TargetedWebDriver.class); + OutputStream outputStream = mock(OutputStream.class); + Browser browser = new WebDriverBrowser(driver, + new StubWebDriverParentContext(), + new StubWebDriverElementContext()); + + when(driver.getScreenshotAs(OutputType.BYTES)) + .thenThrow(NoSuchWindowException.class); + try { + browser.takeScreenshot(outputStream); + fail("Expected FindableNotPresentException to be thrown"); + } catch (Exception e) { + assertThat("Expected FindableNotPresentException to be thrown", + e.getClass(), equalTo(FindableNotPresentException.class)); + } + + verify(outputStream).close(); + } + + @Test + public void shouldThrowDarcyExceptionWhenAnIOExceptionOccurs() throws IOException { + TargetedWebDriver driver = mock(TargetedWebDriver.class); + Browser browser = new WebDriverBrowser(driver, + new StubWebDriverParentContext(), + new StubWebDriverElementContext()); + + OutputStream outputStream = mock(OutputStream.class); + doThrow(new IOException()).when(outputStream).close(); + + try { + browser.takeScreenshot(outputStream); + fail("Expected DarcyException to be thrown"); + } catch (Exception e) { + assertThat("Expected DarcyException to be thrown" , + e.getClass(), equalTo(DarcyException.class)); + } + + verify(outputStream).close(); + } +} diff --git a/src/test/java/com/redhat/darcy/webdriver/internal/TargetedWebDriverParentContextTest.java b/src/test/java/com/redhat/darcy/webdriver/internal/TargetedWebDriverParentContextTest.java index 7ec2efe..29c3239 100644 --- a/src/test/java/com/redhat/darcy/webdriver/internal/TargetedWebDriverParentContextTest.java +++ b/src/test/java/com/redhat/darcy/webdriver/internal/TargetedWebDriverParentContextTest.java @@ -22,8 +22,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.sameInstance; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -42,7 +42,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.openqa.selenium.internal.WrapsDriver; import java.util.Arrays; import java.util.HashSet; @@ -57,7 +56,7 @@ public class TargetedWebDriverParentContextTest { private TargetedWebDriverParentContext context = new TargetedWebDriverParentContext(contextTarget, mockTargetedLocator, - mock(ElementConstructorMap.class)); + mockTargetedDriver::getWindowHandles, mock(ElementConstructorMap.class)); @Before public void stubMocks() { @@ -178,6 +177,52 @@ public void shouldFindAllBrowsersByTitle() { WebDriverTargets.window("window2"))); } + @Test + public void shouldFindBrowsersByUrl() { + TargetedWebDriver fooWindow = mock(TargetedWebDriver.class); + TargetedWebDriver barWindow = mock(TargetedWebDriver.class); + + when(fooWindow.getCurrentUrl()).thenReturn("foo"); + when(barWindow.getCurrentUrl()).thenReturn("bar"); + + when(mockTargetedDriver.getWindowHandles()) + .thenReturn(new HashSet<>(Arrays.asList("fooWindow", "barWindow"))); + when(mockTargetedLocator.window("fooWindow")).thenReturn(fooWindow); + when(mockTargetedLocator.window("barWindow")).thenReturn(barWindow); + + Browser browser = context.findByUrl(Browser.class, equalTo("awesome window")); + + assertFalse(browser.isPresent()); + + when(fooWindow.getCurrentUrl()).thenReturn("awesome window"); + + assertTrue(browser.isPresent()); + } + + @Test + public void shouldFindAllBrowsersByUrl() { + TargetedWebDriver window1 = mock(TargetedWebDriver.class); + TargetedWebDriver window2 = mock(TargetedWebDriver.class); + + when(window1.getCurrentUrl()).thenReturn("shared title"); + when(window2.getCurrentUrl()).thenReturn("shared title"); + + when(mockTargetedDriver.getWindowHandles()) + .thenReturn(new HashSet<>(Arrays.asList("window1", "window2"))); + when(mockTargetedLocator.window("window1")).thenReturn(window1); + when(mockTargetedLocator.window("window2")).thenReturn(window2); + + List browsers = context.findAllByUrl(Browser.class, equalTo("shared title")); + + assertThat(browsers.stream() + .map(b -> (WebDriverBrowser) b) + .map(WebDriverBrowser::getWrappedDriver) + .map(TargetedWebDriver::getWebDriverTarget) + .collect(Collectors.toList()), + containsInAnyOrder(WebDriverTargets.window("window1"), + WebDriverTargets.window("window2"))); + } + @Test(expected = DarcyException.class) public void shouldNotCreateTargetedDriversForFramesByView() { context.findByView(Frame.class, new AlwaysLoadedView()); diff --git a/src/test/java/com/redhat/darcy/webdriver/internal/TargetedWebElementTest.java b/src/test/java/com/redhat/darcy/webdriver/internal/TargetedWebElementTest.java new file mode 100644 index 0000000..d5cad66 --- /dev/null +++ b/src/test/java/com/redhat/darcy/webdriver/internal/TargetedWebElementTest.java @@ -0,0 +1,27 @@ +package com.redhat.darcy.webdriver.internal; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.openqa.selenium.Rectangle; +import org.openqa.selenium.WebDriver; + +@RunWith(JUnit4.class) +public class TargetedWebElementTest { + + @Test + public void shouldCallGetRectOnUnderlyingWebElement() { + WebDriver.TargetLocator locator = mock(WebDriver.TargetLocator.class); + WebDriverTarget target = mock(WebDriverTarget.class); + TargetedWebElement element = mock(TargetedWebElement.class); + when(element.getRect()).thenReturn(mock(Rectangle.class)); + TargetedWebElement targetedWebElement = new TargetedWebElement(locator, target, element); + + targetedWebElement.getRect(); + verify(element).getRect(); + } +} diff --git a/src/test/java/com/redhat/darcy/webdriver/internal/WindowTitleWebDriverTargetTest.java b/src/test/java/com/redhat/darcy/webdriver/internal/WindowTitleWebDriverTargetTest.java index 40a5224..f6e3194 100644 --- a/src/test/java/com/redhat/darcy/webdriver/internal/WindowTitleWebDriverTargetTest.java +++ b/src/test/java/com/redhat/darcy/webdriver/internal/WindowTitleWebDriverTargetTest.java @@ -37,7 +37,6 @@ @RunWith(JUnit4.class) public class WindowTitleWebDriverTargetTest { - private final WebDriver driver = mock(WebDriver.class); private final WebDriver fooWindow = mock(WebDriver.class); private final WebDriver barWindow = mock(WebDriver.class); diff --git a/src/test/java/com/redhat/darcy/webdriver/internal/WindowUrlWebDriverTargetTest.java b/src/test/java/com/redhat/darcy/webdriver/internal/WindowUrlWebDriverTargetTest.java new file mode 100644 index 0000000..be4cdc3 --- /dev/null +++ b/src/test/java/com/redhat/darcy/webdriver/internal/WindowUrlWebDriverTargetTest.java @@ -0,0 +1,84 @@ +/* + 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.internal; + +import static java.util.Arrays.asList; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.openqa.selenium.NoSuchWindowException; +import org.openqa.selenium.WebDriver; + +import java.util.HashSet; + +@RunWith(JUnit4.class) +public class WindowUrlWebDriverTargetTest { + private final WebDriver driver = mock(WebDriver.class); + private final WebDriver fooWindow = mock(WebDriver.class); + private final WebDriver barWindow = mock(WebDriver.class); + private final WebDriver.TargetLocator locator = mock(WebDriver.TargetLocator.class); + + @Before + public void stubMocks() { + when(driver.getWindowHandles()).thenReturn(new HashSet<>(asList("fooWindow", "barWindow"))); + + when(fooWindow.getCurrentUrl()).thenReturn("foo"); + when(barWindow.getCurrentUrl()).thenReturn("bar"); + + when(locator.defaultContent()).thenReturn(driver); + when(locator.window("fooWindow")).thenReturn(fooWindow); + when(locator.window("barWindow")).thenReturn(barWindow); + } + + @Test + public void shouldTargetAWindowWhichMatchesTheUrlMatcher() { + WebDriverTarget target = WebDriverTargets.windowByUrl(equalTo("foo")); + WebDriver found = target.switchTo(locator); + + assertThat(found.getCurrentUrl(), is("foo")); + } + + @Test + public void shouldKeepFindingTheSameWindowEvenIfItsUrlLaterDoesNotMatch() { + WebDriverTarget target = WebDriverTargets.windowByUrl(equalTo("foo")); + + WebDriver found = target.switchTo(locator); + assertThat(found.getCurrentUrl(), is("foo")); + + when(fooWindow.getCurrentUrl()).thenReturn("no longer foo"); + + WebDriver foundAgain = target.switchTo(locator); + assertThat(foundAgain.getCurrentUrl(), is("no longer foo")); + } + + @Test(expected = NoSuchWindowException.class) + public void shouldThrowNoSuchWindowExceptionIfNoWindowsCanBeFoundMatchingTheUrlMatcher() { + WebDriverTarget target = WebDriverTargets.windowByUrl(equalTo("awesome window")); + + target.switchTo(locator); + } +} diff --git a/src/test/java/com/redhat/darcy/webdriver/testing/doubles/StubWebDriverParentContext.java b/src/test/java/com/redhat/darcy/webdriver/testing/doubles/StubWebDriverParentContext.java index d7d8d7d..4e9cb5c 100644 --- a/src/test/java/com/redhat/darcy/webdriver/testing/doubles/StubWebDriverParentContext.java +++ b/src/test/java/com/redhat/darcy/webdriver/testing/doubles/StubWebDriverParentContext.java @@ -23,6 +23,8 @@ import com.redhat.darcy.web.api.Alert; import com.redhat.darcy.webdriver.WebDriverParentContext; +import org.hamcrest.Matcher; + import java.util.List; public class StubWebDriverParentContext implements WebDriverParentContext { @@ -70,4 +72,14 @@ public List findAllByTitle(Class type, String title) { public T findByTitle(Class type, String title) { throw new UnsupportedOperationException("findByTitle"); } + + @Override + public List findAllByUrl(Class type, Matcher url) { + throw new UnsupportedOperationException("findAllByUrl"); + } + + @Override + public T findByUrl(Class type, Matcher url) { + throw new UnsupportedOperationException("findByUrl"); + } }