diff --git a/java/client/src/org/openqa/selenium/SearchContext.java b/java/client/src/org/openqa/selenium/SearchContext.java index 5aae99f458d9c..64cb8e61457d2 100644 --- a/java/client/src/org/openqa/selenium/SearchContext.java +++ b/java/client/src/org/openqa/selenium/SearchContext.java @@ -27,7 +27,7 @@ public interface SearchContext { * @return A list of all {@link WebElement}s, or an empty list if nothing matches * @see org.openqa.selenium.By */ - List findElements(By by); + List findElements(By by); /** @@ -37,5 +37,5 @@ public interface SearchContext { * @return The first matching element on the current context * @throws NoSuchElementException If no matching elements are found */ - WebElement findElement(By by); -} + T findElement(By by); +} \ No newline at end of file diff --git a/java/client/src/org/openqa/selenium/WebDriver.java b/java/client/src/org/openqa/selenium/WebDriver.java index 8df863dc0a32d..f7ae25472af8c 100644 --- a/java/client/src/org/openqa/selenium/WebDriver.java +++ b/java/client/src/org/openqa/selenium/WebDriver.java @@ -91,11 +91,19 @@ public interface WebDriver extends SearchContext { * found collection, or will return an empty list if the timeout is reached. * * @param by The locating mechanism to use + * * @return A list of all {@link WebElement}s, or an empty list if nothing matches + * + * @throws ClassCastException The WebDriver interface is generic. + * It allows an end user to develop a WebDriver implementation that can find&return + * a list of instances of the desired {@link WebElement} subclass. But it is strongly recommended + * to use WebElement as the type of a list parameter when there are used + * common WebDriver implementations of the Selenium project. + * * @see org.openqa.selenium.By * @see org.openqa.selenium.WebDriver.Timeouts */ - List findElements(By by); + List findElements(By by) throws ClassCastException; /** @@ -109,11 +117,19 @@ public interface WebDriver extends SearchContext { * * @param by The locating mechanism * @return The first matching element on the current page + * * @throws NoSuchElementException If no matching elements are found + * + * @throws ClassCastException The WebDriver interface is generic. + * It allows an end user to develop a WebDriver implementation that can find&return an + * instance of the desired {@link WebElement} subclass. But it is strongly recommended + * to use WebElement as the type of the returned element when there are used + * common WebDriver implementations of the Selenium project. + * * @see org.openqa.selenium.By * @see org.openqa.selenium.WebDriver.Timeouts */ - WebElement findElement(By by); + T findElement(By by) throws NoSuchElementException, ClassCastException; // Misc diff --git a/java/client/src/org/openqa/selenium/WebElement.java b/java/client/src/org/openqa/selenium/WebElement.java index aefd43a022547..7fea170fa09a8 100644 --- a/java/client/src/org/openqa/selenium/WebElement.java +++ b/java/client/src/org/openqa/selenium/WebElement.java @@ -147,10 +147,17 @@ public interface WebElement extends SearchContext, TakesScreenshot { * * @param by The locating mechanism to use * @return A list of all {@link WebElement}s, or an empty list if nothing matches. + * + * @throws ClassCastException The WebElement interface is generic. + * It allows an end user to develop a WebElement implementation that can find&return + * a list of instances of the desired WebElement subclass. But it is strongly recommended to use WebElement + * as the type of a list parameter when there are used common {@link WebDriver} implementations of + * the Selenium project. + * * @see org.openqa.selenium.By * @see org.openqa.selenium.WebDriver.Timeouts */ - List findElements(By by); + List findElements(By by); /** * Find the first {@link WebElement} using the given method. See the note in @@ -164,11 +171,19 @@ public interface WebElement extends SearchContext, TakesScreenshot { * * @param by The locating mechanism * @return The first matching element on the current context. + * * @throws NoSuchElementException If no matching elements are found + * + * @throws ClassCastException The WebElement interface is generic. + * It allows an end user to develop a WebElement implementation that can find&return an instance of the desired + * WebElement subclass. But it is strongly recommended to use WebElement + * as the type of the returned element when there are used common {@link WebDriver} implementations of + * the Selenium project. + * * @see org.openqa.selenium.By * @see org.openqa.selenium.WebDriver.Timeouts */ - WebElement findElement(By by); + T findElement(By by); /** * Is this element displayed or not? This method avoids the problem of having to parse an diff --git a/java/client/src/org/openqa/selenium/htmlunit/HtmlUnitDriver.java b/java/client/src/org/openqa/selenium/htmlunit/HtmlUnitDriver.java index b3ac2aef8fb3c..df90673541291 100644 --- a/java/client/src/org/openqa/selenium/htmlunit/HtmlUnitDriver.java +++ b/java/client/src/org/openqa/selenium/htmlunit/HtmlUnitDriver.java @@ -129,6 +129,7 @@ * which is a headless (GUI-less) browser simulator. *

The main supported browsers are Chrome, Firefox and Internet Explorer. */ +@SuppressWarnings({"unchecked"}) public class HtmlUnitDriver implements WebDriver, JavascriptExecutor, FindsById, FindsByLinkText, FindsByXPath, FindsByName, FindsByCssSelector, FindsByTagName, FindsByClassName, HasCapabilities, HasInputDevices { diff --git a/java/client/src/org/openqa/selenium/htmlunit/HtmlUnitWebElement.java b/java/client/src/org/openqa/selenium/htmlunit/HtmlUnitWebElement.java index 4fc40a5da6d20..a36c6226f464d 100644 --- a/java/client/src/org/openqa/selenium/htmlunit/HtmlUnitWebElement.java +++ b/java/client/src/org/openqa/selenium/htmlunit/HtmlUnitWebElement.java @@ -73,7 +73,7 @@ import com.google.common.base.Strings; import com.google.common.base.Throwables; - +@SuppressWarnings({"unchecked"}) public class HtmlUnitWebElement implements WrapsDriver, FindsById, FindsByLinkText, FindsByXPath, FindsByTagName, FindsByCssSelector, Locatable, WebElement { diff --git a/java/client/src/org/openqa/selenium/internal/FindsByClassName.java b/java/client/src/org/openqa/selenium/internal/FindsByClassName.java index c7f742f0d43f5..8f0b2851e315a 100644 --- a/java/client/src/org/openqa/selenium/internal/FindsByClassName.java +++ b/java/client/src/org/openqa/selenium/internal/FindsByClassName.java @@ -22,7 +22,7 @@ import java.util.List; public interface FindsByClassName { - WebElement findElementByClassName(String using); + T findElementByClassName(String using); - List findElementsByClassName(String using); + List findElementsByClassName(String using); } diff --git a/java/client/src/org/openqa/selenium/internal/FindsByCssSelector.java b/java/client/src/org/openqa/selenium/internal/FindsByCssSelector.java index 5f221c61dd819..9ef0b9a226871 100644 --- a/java/client/src/org/openqa/selenium/internal/FindsByCssSelector.java +++ b/java/client/src/org/openqa/selenium/internal/FindsByCssSelector.java @@ -22,7 +22,7 @@ import java.util.List; public interface FindsByCssSelector { - WebElement findElementByCssSelector(String using); + T findElementByCssSelector(String using); - List findElementsByCssSelector(String using); + List findElementsByCssSelector(String using); } diff --git a/java/client/src/org/openqa/selenium/internal/FindsById.java b/java/client/src/org/openqa/selenium/internal/FindsById.java index a62e079999aaf..a567e03e7f995 100644 --- a/java/client/src/org/openqa/selenium/internal/FindsById.java +++ b/java/client/src/org/openqa/selenium/internal/FindsById.java @@ -22,7 +22,7 @@ import java.util.List; public interface FindsById { - WebElement findElementById(String using); + T findElementById(String using); - List findElementsById(String using); + List findElementsById(String using); } diff --git a/java/client/src/org/openqa/selenium/internal/FindsByLinkText.java b/java/client/src/org/openqa/selenium/internal/FindsByLinkText.java index f79ecb46f8f30..9368a4d9ce17e 100644 --- a/java/client/src/org/openqa/selenium/internal/FindsByLinkText.java +++ b/java/client/src/org/openqa/selenium/internal/FindsByLinkText.java @@ -22,11 +22,11 @@ import java.util.List; public interface FindsByLinkText { - WebElement findElementByLinkText(String using); + T findElementByLinkText(String using); - List findElementsByLinkText(String using); + List findElementsByLinkText(String using); - WebElement findElementByPartialLinkText(String using); + T findElementByPartialLinkText(String using); - List findElementsByPartialLinkText(String using); + List findElementsByPartialLinkText(String using); } diff --git a/java/client/src/org/openqa/selenium/internal/FindsByName.java b/java/client/src/org/openqa/selenium/internal/FindsByName.java index f4c3f559ad34a..21ee86a5a1dcd 100644 --- a/java/client/src/org/openqa/selenium/internal/FindsByName.java +++ b/java/client/src/org/openqa/selenium/internal/FindsByName.java @@ -22,7 +22,7 @@ import java.util.List; public interface FindsByName { - WebElement findElementByName(String using); + T findElementByName(String using); - List findElementsByName(String using); + List findElementsByName(String using); } diff --git a/java/client/src/org/openqa/selenium/internal/FindsByTagName.java b/java/client/src/org/openqa/selenium/internal/FindsByTagName.java index 5c21fe3529bce..9720fe1e8d350 100644 --- a/java/client/src/org/openqa/selenium/internal/FindsByTagName.java +++ b/java/client/src/org/openqa/selenium/internal/FindsByTagName.java @@ -22,7 +22,7 @@ import java.util.List; public interface FindsByTagName { - WebElement findElementByTagName(String using); + T findElementByTagName(String using); - List findElementsByTagName(String using); + List findElementsByTagName(String using); } diff --git a/java/client/src/org/openqa/selenium/internal/FindsByXPath.java b/java/client/src/org/openqa/selenium/internal/FindsByXPath.java index 49c0d72bea636..9eb082429aa71 100644 --- a/java/client/src/org/openqa/selenium/internal/FindsByXPath.java +++ b/java/client/src/org/openqa/selenium/internal/FindsByXPath.java @@ -22,7 +22,7 @@ import java.util.List; public interface FindsByXPath { - WebElement findElementByXPath(String using); + T findElementByXPath(String using); - List findElementsByXPath(String using); + List findElementsByXPath(String using); } diff --git a/java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java b/java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java index 8af022427cece..0e43c845f0f4b 100644 --- a/java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java +++ b/java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java @@ -74,7 +74,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -@Augmentable +@Augmentable @SuppressWarnings({"unchecked"}) public class RemoteWebDriver implements WebDriver, JavascriptExecutor, FindsById, FindsByClassName, FindsByLinkText, FindsByName, FindsByCssSelector, FindsByTagName, FindsByXPath, @@ -232,7 +232,7 @@ protected void startSession(Capabilities desiredCapabilities) { startSession(desiredCapabilities, null); } - @SuppressWarnings({"unchecked"}) + protected void startSession(Capabilities desiredCapabilities, Capabilities requiredCapabilities) { @@ -369,7 +369,7 @@ protected void setFoundBy(SearchContext context, WebElement element, String by, } } - @SuppressWarnings("unchecked") + protected List findElements(String by, String using) { if (using == null) { throw new IllegalArgumentException("Cannot find elements when the selector is null."); @@ -520,7 +520,7 @@ public void quit() { } } - @SuppressWarnings({"unchecked"}) + public Set getWindowHandles() { Response response = execute(DriverCommand.GET_WINDOW_HANDLES); Object value = response.getValue(); @@ -741,7 +741,7 @@ public void deleteAllCookies() { execute(DriverCommand.DELETE_ALL_COOKIES); } - @SuppressWarnings({"unchecked"}) + public Set getCookies() { Object returned = execute(DriverCommand.GET_ALL_COOKIES).getValue(); @@ -795,7 +795,7 @@ public Window window() { protected class RemoteInputMethodManager implements WebDriver.ImeHandler { - @SuppressWarnings("unchecked") + public List getAvailableEngines() { Response response = execute(DriverCommand.IME_GET_AVAILABLE_ENGINES); return (List) response.getValue(); @@ -869,7 +869,7 @@ public void setPosition(Point targetPosition) { } } - @SuppressWarnings({"unchecked"}) + public Dimension getSize() { Response response = getW3CStandardComplianceLevel() == 0 ? execute(DriverCommand.GET_WINDOW_SIZE, ImmutableMap.of("windowHandle", "current")) @@ -883,7 +883,7 @@ public Dimension getSize() { return new Dimension(width, height); } - @SuppressWarnings({"unchecked"}) + Map rawPoint; public Point getPosition() { if (getW3CStandardComplianceLevel() == 0) { diff --git a/java/client/src/org/openqa/selenium/remote/RemoteWebElement.java b/java/client/src/org/openqa/selenium/remote/RemoteWebElement.java index 7778eba8b6c61..8423587a7c101 100644 --- a/java/client/src/org/openqa/selenium/remote/RemoteWebElement.java +++ b/java/client/src/org/openqa/selenium/remote/RemoteWebElement.java @@ -47,7 +47,7 @@ import java.io.IOException; import java.util.List; import java.util.Map; - +@SuppressWarnings({"unchecked"}) public class RemoteWebElement implements WebElement, FindsByLinkText, FindsById, FindsByName, FindsByTagName, FindsByClassName, FindsByCssSelector, FindsByXPath, WrapsDriver, Locatable, HasIdentity, @@ -206,7 +206,7 @@ protected WebElement findElement(String using, String value) { return element; } - @SuppressWarnings("unchecked") + protected List findElements(String using, String value) { Response response = execute(DriverCommand.FIND_CHILD_ELEMENTS, ImmutableMap.of("id", id, "using", using, "value", value)); @@ -371,7 +371,7 @@ public boolean isDisplayed() { } } - @SuppressWarnings({"unchecked"}) + public Point getLocation() { Response response = parent.getW3CStandardComplianceLevel() == 0 ? execute(DriverCommand.GET_ELEMENT_LOCATION, ImmutableMap.of("id", id)) @@ -382,7 +382,7 @@ public Point getLocation() { return new Point(x, y); } - @SuppressWarnings({"unchecked"}) + public Dimension getSize() { Response response = parent.getW3CStandardComplianceLevel() == 0 ? execute(DriverCommand.GET_ELEMENT_SIZE, ImmutableMap.of("id", id)) @@ -405,12 +405,12 @@ public Point inViewPort() { Response response = execute(DriverCommand.GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW, ImmutableMap.of("id", getId())); - @SuppressWarnings("unchecked") + Map mapped = (Map) response.getValue(); return new Point(mapped.get("x").intValue(), mapped.get("y").intValue()); } else { - @SuppressWarnings("unchecked") + Map mapped = (Map) parent.executeScript( "return arguments[0].getBoundingClientRect()", RemoteWebElement.this); diff --git a/java/client/src/org/openqa/selenium/support/events/EventFiringWebDriver.java b/java/client/src/org/openqa/selenium/support/events/EventFiringWebDriver.java index f46fa3e8f24d1..ac87d1f44d6a6 100644 --- a/java/client/src/org/openqa/selenium/support/events/EventFiringWebDriver.java +++ b/java/client/src/org/openqa/selenium/support/events/EventFiringWebDriver.java @@ -61,6 +61,7 @@ * A wrapper around an arbitrary {@link WebDriver} instance which supports registering of a * {@link WebDriverEventListener}, e.g. for logging purposes. */ +@SuppressWarnings({"unchecked"}) public class EventFiringWebDriver implements WebDriver, JavascriptExecutor, TakesScreenshot, WrapsDriver, HasInputDevices, HasTouchScreen { diff --git a/java/client/test/org/openqa/selenium/SearchContextTest.java b/java/client/test/org/openqa/selenium/SearchContextTest.java new file mode 100644 index 0000000000000..1dae8856ecb95 --- /dev/null +++ b/java/client/test/org/openqa/selenium/SearchContextTest.java @@ -0,0 +1,72 @@ +package org.openqa.selenium; + +import org.junit.Test; + +import java.util.List; + +// this class just tests we can compile the code +public class SearchContextTest { + + private final SubClassingSearchContext subClassingSearchContext = new SubClassingSearchContext(); + private final SameClassSearchContext sameClassSearchContext = new SameClassSearchContext() { + @Override + public List findElements(By by) { + return null; + } + + @Override + public WebElement findElement(By by) { + return null; + } + }; + + private interface TestWebElement extends WebElement { + + } + + private static class SubClassingSearchContext implements SearchContext { + + @Override + public List findElements(By by) { + return null; + } + + @Override + public TestWebElement findElement(By by) { + return null; + } + } + + private interface SameClassSearchContext extends SearchContext { + + } + + @Test + public void makeSureFindElementsIsBackwardsCompatible() throws Exception { + + @SuppressWarnings("unused") + List elements = sameClassSearchContext.findElements(null); + } + + @Test + public void makeSureFindElementIsBackwardsCompatible() throws Exception { + + @SuppressWarnings("unused") + WebElement element = sameClassSearchContext.findElement(null); + } + + @Test + public void makeSureFindElementsCanUseSuperClass() throws Exception { + @SuppressWarnings("unused") + List elements = subClassingSearchContext.findElements(null); + } + + @Test + public void makeSureFindElementCanUseSuperClass() throws Exception { + + @SuppressWarnings("unused") + WebElement element = subClassingSearchContext.findElement(null); + + + } +} diff --git a/java/client/test/org/openqa/selenium/StandardSeleniumTests.java b/java/client/test/org/openqa/selenium/StandardSeleniumTests.java index 93228b6393984..c309b6bcfb9f9 100644 --- a/java/client/test/org/openqa/selenium/StandardSeleniumTests.java +++ b/java/client/test/org/openqa/selenium/StandardSeleniumTests.java @@ -88,7 +88,7 @@ WindowSwitchingTest.class, ContextSwitchingTest.class, WindowTest.class, - + SearchContextTest.class, Html5Tests.class, InteractionTests.class })