diff --git a/google-style.xml b/google-style.xml index 13557abdd..dd40c8a90 100755 --- a/google-style.xml +++ b/google-style.xml @@ -42,7 +42,7 @@ - + @@ -181,9 +181,12 @@ - + + + + diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index 784bad5c6..2f3f626fb 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -261,7 +261,7 @@ public List findElementsByXPath(String using) { } @Override public List findElementsByAccessibilityId(String using) { - return (List) findElements("accessibility id", using); + return super.findElementsByAccessibilityId(using); } @Override protected Response execute(String command) { diff --git a/src/main/java/io/appium/java_client/DefaultGenericMobileDriver.java b/src/main/java/io/appium/java_client/DefaultGenericMobileDriver.java index de55a4282..19555f105 100644 --- a/src/main/java/io/appium/java_client/DefaultGenericMobileDriver.java +++ b/src/main/java/io/appium/java_client/DefaultGenericMobileDriver.java @@ -16,15 +16,6 @@ package io.appium.java_client; -import io.appium.java_client.generic.searchcontext.GenericFindsByClassName; -import io.appium.java_client.generic.searchcontext.GenericFindsByCssSelector; -import io.appium.java_client.generic.searchcontext.GenericFindsById; -import io.appium.java_client.generic.searchcontext.GenericFindsByLinkText; -import io.appium.java_client.generic.searchcontext.GenericFindsByName; -import io.appium.java_client.generic.searchcontext.GenericFindsByTagName; -import io.appium.java_client.generic.searchcontext.GenericFindsByXPath; -import io.appium.java_client.generic.searchcontext.GenericSearchContext; - import org.openqa.selenium.By; import org.openqa.selenium.Capabilities; import org.openqa.selenium.WebDriverException; @@ -39,9 +30,7 @@ @SuppressWarnings({"unchecked", "rawtypes"}) abstract class DefaultGenericMobileDriver extends RemoteWebDriver - implements GenericSearchContext, GenericFindsById, GenericFindsByXPath, - GenericFindsByLinkText, GenericFindsByTagName, GenericFindsByClassName, - GenericFindsByCssSelector, GenericFindsByName, MobileDriver { + implements MobileDriver { public DefaultGenericMobileDriver(CommandExecutor executor, Capabilities desiredCapabilities) { super(executor, desiredCapabilities); diff --git a/src/main/java/io/appium/java_client/DefaultGenericMobileElement.java b/src/main/java/io/appium/java_client/DefaultGenericMobileElement.java index 7aa74bc14..88884e405 100644 --- a/src/main/java/io/appium/java_client/DefaultGenericMobileElement.java +++ b/src/main/java/io/appium/java_client/DefaultGenericMobileElement.java @@ -16,16 +16,6 @@ package io.appium.java_client; -import io.appium.java_client.generic.searchcontext.GenericFindsByClassName; -import io.appium.java_client.generic.searchcontext.GenericFindsByCssSelector; -import io.appium.java_client.generic.searchcontext.GenericFindsById; -import io.appium.java_client.generic.searchcontext.GenericFindsByLinkText; -import io.appium.java_client.generic.searchcontext.GenericFindsByName; -import io.appium.java_client.generic.searchcontext.GenericFindsByTagName; -import io.appium.java_client.generic.searchcontext.GenericFindsByXPath; -import io.appium.java_client.generic.searchcontext.GenericSearchContext; - - import org.openqa.selenium.By; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.WebElement; @@ -37,10 +27,7 @@ @SuppressWarnings({"unchecked", "rawtypes"}) abstract class DefaultGenericMobileElement extends RemoteWebElement - implements GenericSearchContext, GenericFindsById, GenericFindsByXPath, - GenericFindsByLinkText, GenericFindsByTagName, GenericFindsByClassName, - GenericFindsByCssSelector, GenericFindsByName, FindsByAccessibilityId, - TouchableElement { + implements FindsByAccessibilityId, TouchableElement { @Override public Response execute(String driverCommand, Map parameters) { return super.execute(driverCommand, parameters); @@ -50,10 +37,18 @@ abstract class DefaultGenericMobileElement extends RemoteW return super.findElements(by); } + @Override public List findElements(String by, String using) { + return super.findElements(by, using); + } + @Override public T findElement(By by) { return (T) super.findElement(by); } + @Override public T findElement(String by, String using) { + return (T) super.findElement(by, using); + } + @Override public List findElementsById(String id) { return super.findElementsById(id); } diff --git a/src/main/java/io/appium/java_client/MobileDriver.java b/src/main/java/io/appium/java_client/MobileDriver.java index 0e13181f8..e6965aef9 100644 --- a/src/main/java/io/appium/java_client/MobileDriver.java +++ b/src/main/java/io/appium/java_client/MobileDriver.java @@ -16,17 +16,64 @@ package io.appium.java_client; +import org.openqa.selenium.By; import org.openqa.selenium.ContextAware; import org.openqa.selenium.Rotatable; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.html5.LocationContext; +import org.openqa.selenium.internal.FindsByClassName; +import org.openqa.selenium.internal.FindsByCssSelector; +import org.openqa.selenium.internal.FindsById; +import org.openqa.selenium.internal.FindsByLinkText; +import org.openqa.selenium.internal.FindsByName; +import org.openqa.selenium.internal.FindsByTagName; +import org.openqa.selenium.internal.FindsByXPath; import org.openqa.selenium.remote.Response; +import java.util.List; import java.util.Map; -public interface MobileDriver extends WebDriver, PerformsTouchActions, ContextAware, Rotatable, - FindsByAccessibilityId, LocationContext, DeviceActionShortcuts, TouchShortcuts, - InteractsWithFiles, InteractsWithApps, HasAppStrings { +public interface MobileDriver extends WebDriver, PerformsTouchActions, ContextAware, Rotatable, + FindsByAccessibilityId, LocationContext, DeviceActionShortcuts, TouchShortcuts, + InteractsWithFiles, InteractsWithApps, HasAppStrings, FindsByClassName, FindsByCssSelector, FindsById, + FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath { + Response execute(String driverCommand, Map parameters); + + List findElements(By by); + + T findElement(By by); + + T findElementByClassName(String className); + + List findElementsByClassName(String className); + + T findElementByCssSelector(String cssSelector); + + List findElementsByCssSelector(String cssSelector); + + T findElementById(String id); + + List findElementsById(String id); + + T findElementByLinkText(String linkText); + + List findElementsByLinkText(String linkText); + + T findElementByPartialLinkText(String partialLinkText); + + List findElementsByPartialLinkText(String partialLinkText); + + T findElementByName(String name); + + List findElementsByName(String name); + + T findElementByTagName(String tagName); + + List findElementsByTagName(String tagName); + + T findElementByXPath(String xPath); + + List findElementsByXPath(String xPath); } diff --git a/src/main/java/io/appium/java_client/MobileElement.java b/src/main/java/io/appium/java_client/MobileElement.java index 9b6020d98..ecb878bb1 100644 --- a/src/main/java/io/appium/java_client/MobileElement.java +++ b/src/main/java/io/appium/java_client/MobileElement.java @@ -19,10 +19,8 @@ import org.openqa.selenium.By; import org.openqa.selenium.Dimension; import org.openqa.selenium.Point; -import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.FileDetector; -import java.util.ArrayList; import java.util.List; @SuppressWarnings({"unchecked"}) @@ -69,6 +67,10 @@ public Point getCenter() { return super.findElements(by); } + @Override public List findElements(String by, String using) { + return super.findElements(by, using); + } + @Override public List findElementsById(String id) { return super.findElementsById(id); } @@ -102,11 +104,6 @@ public List findElementsByXPath(String using) { } @Override public List findElementsByAccessibilityId(String using) { - List result = new ArrayList(); - List found = findElements("accessibility id", using); - for (WebElement e : found) { - result.add((MobileElement) e); - } - return result; + return super.findElementsByAccessibilityId(using); } } diff --git a/src/main/java/io/appium/java_client/TouchableElement.java b/src/main/java/io/appium/java_client/TouchableElement.java index e5df6bfc9..757c99626 100644 --- a/src/main/java/io/appium/java_client/TouchableElement.java +++ b/src/main/java/io/appium/java_client/TouchableElement.java @@ -16,13 +16,61 @@ package io.appium.java_client; +import org.openqa.selenium.By; import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.FindsByClassName; +import org.openqa.selenium.internal.FindsByCssSelector; +import org.openqa.selenium.internal.FindsById; +import org.openqa.selenium.internal.FindsByLinkText; +import org.openqa.selenium.internal.FindsByName; +import org.openqa.selenium.internal.FindsByTagName; +import org.openqa.selenium.internal.FindsByXPath; + +import java.util.List; /** * It supposed that mobile elements could be tappable, swipeable, zoomable and so on. * This interface extends {@link WebElement} and describes this behavior. */ -public interface TouchableElement extends WebElement { +public interface TouchableElement extends WebElement, FindsByClassName, + FindsByCssSelector, FindsById, + FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath { + + List findElements(By by); + + T findElement(By by); + + T findElementByClassName(String className); + + List findElementsByClassName(String className); + + T findElementByCssSelector(String cssSelector); + + List findElementsByCssSelector(String cssSelector); + + T findElementById(String id); + + List findElementsById(String id); + + T findElementByLinkText(String linkText); + + List findElementsByLinkText(String linkText); + + T findElementByPartialLinkText(String partialLinkText); + + List findElementsByPartialLinkText(String partialLinkText); + + T findElementByName(String name); + + List findElementsByName(String name); + + T findElementByTagName(String tagName); + + List findElementsByTagName(String tagName); + + T findElementByXPath(String xPath); + + List findElementsByXPath(String xPath); /** * Convenience method for pinching the given element. diff --git a/src/main/java/io/appium/java_client/android/AndroidElement.java b/src/main/java/io/appium/java_client/android/AndroidElement.java index f21aa7eb8..8bb762993 100644 --- a/src/main/java/io/appium/java_client/android/AndroidElement.java +++ b/src/main/java/io/appium/java_client/android/AndroidElement.java @@ -23,9 +23,7 @@ import io.appium.java_client.MobileElement; import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.WebElement; -import java.util.ArrayList; import java.util.List; @@ -37,7 +35,7 @@ public class AndroidElement extends MobileElement */ @Override public MobileElement findElementByAndroidUIAutomator(String using) throws WebDriverException { - return (MobileElement) findElement("-android uiautomator", using); + return findElement("-android uiautomator", using); } /** @@ -45,12 +43,7 @@ public class AndroidElement extends MobileElement */ @Override public List findElementsByAndroidUIAutomator(String using) throws WebDriverException { - List result = new ArrayList(); - List found = findElements("-android uiautomator", using); - for (WebElement e : found) { - result.add((AndroidElement) e); - } - return result; + return findElements("-android uiautomator", using); } /** diff --git a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByClassName.java b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByClassName.java index c7a4485f3..e9dc6c202 100644 --- a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByClassName.java +++ b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByClassName.java @@ -20,6 +20,12 @@ import java.util.List; +@Deprecated +/** + * This interface became deprecated. Use + * {@link org.openqa.selenium.internal.FindsByClassName} + * instead. + */ public interface GenericFindsByClassName { T findElementByClassName(String className); diff --git a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByCssSelector.java b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByCssSelector.java index 5dcfa093b..200c20bd6 100644 --- a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByCssSelector.java +++ b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByCssSelector.java @@ -20,6 +20,12 @@ import java.util.List; +@Deprecated +/** + * This interface became deprecated. Use + * {@link org.openqa.selenium.internal.FindsByCssSelector} + * instead. + */ public interface GenericFindsByCssSelector { T findElementByCssSelector(String cssSelector); diff --git a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsById.java b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsById.java index 98ce156b8..5e6c7c870 100644 --- a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsById.java +++ b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsById.java @@ -20,6 +20,12 @@ import java.util.List; +@Deprecated +/** + * This interface became deprecated. Use + * {@link org.openqa.selenium.internal.FindsById} + * instead. + */ public interface GenericFindsById { T findElementById(String id); diff --git a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByLinkText.java b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByLinkText.java index b48585d43..353c44af5 100644 --- a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByLinkText.java +++ b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByLinkText.java @@ -20,6 +20,12 @@ import java.util.List; +@Deprecated +/** + * This interface became deprecated. Use + * {@link org.openqa.selenium.internal.FindsByLinkText} + * instead. + */ public interface GenericFindsByLinkText { T findElementByLinkText(String linkText); diff --git a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByName.java b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByName.java index ec1431009..5ea24a8ca 100644 --- a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByName.java +++ b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByName.java @@ -20,6 +20,12 @@ import java.util.List; +@Deprecated +/** + * This interface became deprecated. Use + * {@link org.openqa.selenium.internal.FindsByName} + * instead. + */ public interface GenericFindsByName { T findElementByName(String name); diff --git a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByTagName.java b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByTagName.java index 98a22c333..54be50396 100644 --- a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByTagName.java +++ b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByTagName.java @@ -20,6 +20,12 @@ import java.util.List; +@Deprecated +/** + * This interface became deprecated. Use + * {@link org.openqa.selenium.internal.FindsByTagName} + * instead. + */ public interface GenericFindsByTagName { T findElementByTagName(String tagName); diff --git a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByXPath.java b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByXPath.java index 1ba9f9897..105f68344 100644 --- a/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByXPath.java +++ b/src/main/java/io/appium/java_client/generic/searchcontext/GenericFindsByXPath.java @@ -20,6 +20,12 @@ import java.util.List; +@Deprecated +/** + * This interface became deprecated. Use + * {@link org.openqa.selenium.internal.FindsByXPath} + * instead. + */ public interface GenericFindsByXPath { T findElementByXPath(String xPath); diff --git a/src/main/java/io/appium/java_client/generic/searchcontext/GenericSearchContext.java b/src/main/java/io/appium/java_client/generic/searchcontext/GenericSearchContext.java index a7609df9e..db902062b 100644 --- a/src/main/java/io/appium/java_client/generic/searchcontext/GenericSearchContext.java +++ b/src/main/java/io/appium/java_client/generic/searchcontext/GenericSearchContext.java @@ -21,6 +21,12 @@ import java.util.List; +@Deprecated +/** + * This interface became deprecated. Use + * {@link org.openqa.selenium.SearchContext} + * instead. + */ public interface GenericSearchContext { List findElements(By by); diff --git a/src/main/java/io/appium/java_client/ios/IOSElement.java b/src/main/java/io/appium/java_client/ios/IOSElement.java index 23a287b60..2059a854a 100644 --- a/src/main/java/io/appium/java_client/ios/IOSElement.java +++ b/src/main/java/io/appium/java_client/ios/IOSElement.java @@ -21,11 +21,8 @@ import io.appium.java_client.FindsByIosUIAutomation; import io.appium.java_client.MobileCommand; import io.appium.java_client.MobileElement; -import io.appium.java_client.SwipeElementDirection; import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.WebElement; -import java.util.ArrayList; import java.util.List; public class IOSElement extends MobileElement @@ -36,7 +33,7 @@ public class IOSElement extends MobileElement */ @Override public MobileElement findElementByIosUIAutomation(String using) throws WebDriverException { - return (IOSElement) findElement("-ios uiautomation", using); + return findElement("-ios uiautomation", using); } /** @@ -45,12 +42,7 @@ public class IOSElement extends MobileElement */ @Override public List findElementsByIosUIAutomation(String using) throws WebDriverException { - List result = new ArrayList(); - List found = findElements("-ios uiautomation", using); - for (WebElement e : found) { - result.add((IOSElement) e); - } - return result; + return findElements("-ios uiautomation", using); } /** diff --git a/src/main/java/org/openqa/selenium/SearchContext.java b/src/main/java/org/openqa/selenium/SearchContext.java new file mode 100644 index 000000000..79501d6d8 --- /dev/null +++ b/src/main/java/org/openqa/selenium/SearchContext.java @@ -0,0 +1,41 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium; + +import java.util.List; + +public interface SearchContext { + /** + * Find all elements within the current context using the given mechanism. + * + * @param by The locating mechanism to use + * @return A list of all {@link WebElement}s, or an empty list if nothing matches + * @see org.openqa.selenium.By + */ + List findElements(By by); + + + /** + * Find the first {@link WebElement} using the given method. + * + * @param by The locating mechanism + * @return The first matching element on the current context + * @throws NoSuchElementException If no matching elements are found + */ + T findElement(By by); +} diff --git a/src/main/java/org/openqa/selenium/WebDriver.java b/src/main/java/org/openqa/selenium/WebDriver.java new file mode 100644 index 000000000..dde47d84b --- /dev/null +++ b/src/main/java/org/openqa/selenium/WebDriver.java @@ -0,0 +1,515 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium; + +import org.openqa.selenium.logging.Logs; +import org.openqa.selenium.logging.LoggingPreferences; + +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + + +/** + * The main interface to use for testing, which represents an idealised web browser. The methods in + * this class fall into three categories: + *
    + *
  • Control of the browser itself
  • + *
  • Selection of {@link WebElement}s
  • + *
  • Debugging aids
  • + *
+ *

+ * Key methods are {@link WebDriver#get(String)}, which is used to load a new web page, and the + * various methods similar to {@link WebDriver#findElement(By)}, which is used to find + * {@link WebElement}s. + *

+ * Currently, you will need to instantiate implementations of this class directly. It is hoped that + * you write your tests against this interface so that you may "swap in" a more fully featured + * browser when there is a requirement for one. + *

+ * Note that all methods that use XPath to locate elements will throw a {@link RuntimeException} + * should there be an error thrown by the underlying XPath engine. + */ +public interface WebDriver extends SearchContext { + // Navigation + + /** + * Load a new web page in the current browser window. This is done using an HTTP GET operation, + * and the method will block until the load is complete. This will follow redirects issued either + * by the server or as a meta-redirect from within the returned HTML. Should a meta-redirect + * "rest" for any duration of time, it is best to wait until this timeout is over, since should + * the underlying page change whilst your test is executing the results of future calls against + * this interface will be against the freshly loaded page. Synonym for + * {@link org.openqa.selenium.WebDriver.Navigation#to(String)}. + * + * @param url The URL to load. It is best to use a fully qualified URL + */ + void get(String url); + + /** + * Get a string representing the current URL that the browser is looking at. + * + * @return The URL of the page currently loaded in the browser + */ + String getCurrentUrl(); + + // General properties + + /** + * The title of the current page. + * + * @return The title of the current page, with leading and trailing whitespace stripped, or null + * if one is not already set + */ + String getTitle(); + + /** + * Find all elements within the current page using the given mechanism. + * This method is affected by the 'implicit wait' times in force at the time of execution. When + * implicitly waiting, this method will return as soon as there are more than 0 items in the + * 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 + * @see org.openqa.selenium.By + * @see org.openqa.selenium.WebDriver.Timeouts + */ + List findElements(By by); + + + /** + * Find the first {@link WebElement} using the given method. + * This method is affected by the 'implicit wait' times in force at the time of execution. + * The findElement(..) invocation will return a matching row, or try again repeatedly until + * the configured timeout is reached. + *

+ * findElement should not be used to look for non-present elements, use {@link #findElements(By)} + * and assert zero length response instead. + * + * @param by The locating mechanism + * @return The first matching element on the current page + * @throws NoSuchElementException If no matching elements are found + * @see org.openqa.selenium.By + * @see org.openqa.selenium.WebDriver.Timeouts + */ + T findElement(By by); + + // Misc + + /** + * Get the source of the last loaded page. If the page has been modified after loading (for + * example, by Javascript) there is no guarantee that the returned text is that of the modified + * page. Please consult the documentation of the particular driver being used to determine whether + * the returned text reflects the current state of the page or the text last sent by the web + * server. The page source returned is a representation of the underlying DOM: do not expect it to + * be formatted or escaped in the same way as the response sent from the web server. Think of it as + * an artist's impression. + * + * @return The source of the current page + */ + String getPageSource(); + + /** + * Close the current window, quitting the browser if it's the last window currently open. + */ + void close(); + + /** + * Quits this driver, closing every associated window. + */ + void quit(); + + /** + * Return a set of window handles which can be used to iterate over all open windows of this + * WebDriver instance by passing them to {@link #switchTo()}.{@link Options#window()} + * + * @return A set of window handles which can be used to iterate over all open windows. + */ + Set getWindowHandles(); + + /** + * Return an opaque handle to this window that uniquely identifies it within this driver instance. + * This can be used to switch to this window at a later date + * + * @return the current window handle + */ + String getWindowHandle(); + + /** + * Send future commands to a different frame or window. + * + * @return A TargetLocator which can be used to select a frame or window + * @see org.openqa.selenium.WebDriver.TargetLocator + */ + TargetLocator switchTo(); + + /** + * An abstraction allowing the driver to access the browser's history and to navigate to a given + * URL. + * + * @return A {@link org.openqa.selenium.WebDriver.Navigation} that allows the selection of what to + * do next + */ + Navigation navigate(); + + /** + * Gets the Option interface + * + * @return An option interface + * @see org.openqa.selenium.WebDriver.Options + */ + Options manage(); + + /** + * An interface for managing stuff you would do in a browser menu + */ + interface Options { + + /** + * Add a specific cookie. If the cookie's domain name is left blank, it is assumed that the + * cookie is meant for the domain of the current document. + * + * @param cookie The cookie to add. + */ + void addCookie(Cookie cookie); + + /** + * Delete the named cookie from the current domain. This is equivalent to setting the named + * cookie's expiry date to some time in the past. + * + * @param name The name of the cookie to delete + */ + void deleteCookieNamed(String name); + + /** + * Delete a cookie from the browser's "cookie jar". The domain of the cookie will be ignored. + * + * @param cookie nom nom nom + */ + void deleteCookie(Cookie cookie); + + /** + * Delete all the cookies for the current domain. + */ + void deleteAllCookies(); + + /** + * Get all the cookies for the current domain. This is the equivalent of calling + * "document.cookie" and parsing the result + * + * @return A Set of cookies for the current domain. + */ + Set getCookies(); + + /** + * Get a cookie with a given name. + * + * @param name the name of the cookie + * @return the cookie, or null if no cookie with the given name is present + */ + Cookie getCookieNamed(String name); + + /** + * @return the interface for managing driver timeouts. + */ + Timeouts timeouts(); + + /** + * @return the interface for controlling IME engines to generate complex-script input. + */ + ImeHandler ime(); + + /** + * @return the interface for managing the current window. + */ + Window window(); + + /** + * Gets the {@link Logs} interface used to fetch different types of logs. + *

+ *

To set the logging preferences {@link LoggingPreferences}. + * + * @return A Logs interface. + */ + @Beta + Logs logs(); + } + + /** + * An interface for managing timeout behavior for WebDriver instances. + */ + interface Timeouts { + + /** + * Specifies the amount of time the driver should wait when searching for an element if it is + * not immediately present. + *

+ * When searching for a single element, the driver should poll the page until the element has + * been found, or this timeout expires before throwing a {@link NoSuchElementException}. When + * searching for multiple elements, the driver should poll the page until at least one element + * has been found or this timeout has expired. + *

+ * Increasing the implicit wait timeout should be used judiciously as it will have an adverse + * effect on test run time, especially when used with slower location strategies like XPath. + * + * @param time The amount of time to wait. + * @param unit The unit of measure for {@code time}. + * @return A self reference. + */ + Timeouts implicitlyWait(long time, TimeUnit unit); + + /** + * Sets the amount of time to wait for an asynchronous script to finish execution before + * throwing an error. If the timeout is negative, then the script will be allowed to run + * indefinitely. + * + * @param time The timeout value. + * @param unit The unit of time. + * @return A self reference. + * @see JavascriptExecutor#executeAsyncScript(String, Object...) + */ + Timeouts setScriptTimeout(long time, TimeUnit unit); + + /** + * Sets the amount of time to wait for a page load to complete before throwing an error. + * If the timeout is negative, page loads can be indefinite. + * + * @param time The timeout value. + * @param unit The unit of time. + * @return A Timeouts interface. + */ + Timeouts pageLoadTimeout(long time, TimeUnit unit); + } + + /** + * Used to locate a given frame or window. + */ + interface TargetLocator { + /** + * Select a frame by its (zero-based) index. Selecting a frame by index is equivalent to the + * JS expression window.frames[index] where "window" is the DOM window represented by the + * current context. Once the frame has been selected, all subsequent calls on the WebDriver + * interface are made to that frame. + * + * @param index (zero-based) index + * @return This driver focused on the given frame + * @throws NoSuchFrameException If the frame cannot be found + */ + WebDriver frame(int index); + + /** + * Select a frame by its name or ID. Frames located by matching name attributes are always given + * precedence over those matched by ID. + * + * @param nameOrId the name of the frame window, the id of the <frame> or <iframe> + * element, or the (zero-based) index + * @return This driver focused on the given frame + * @throws NoSuchFrameException If the frame cannot be found + */ + WebDriver frame(String nameOrId); + + /** + * Select a frame using its previously located {@link WebElement}. + * + * @param frameElement The frame element to switch to. + * @return This driver focused on the given frame. + * @throws NoSuchFrameException If the given element is neither an IFRAME nor a FRAME element. + * @throws StaleElementReferenceException If the WebElement has gone stale. + * @see WebDriver#findElement(By) + */ + WebDriver frame(WebElement frameElement); + + /** + * Change focus to the parent context. If the current context is the top level browsing context, + * the context remains unchanged. + * + * @return This driver focused on the parent frame + */ + WebDriver parentFrame(); + + /** + * Switch the focus of future commands for this driver to the window with the given name/handle. + * + * @param nameOrHandle The name of the window or the handle as returned by + * {@link WebDriver#getWindowHandle()} + * @return This driver focused on the given window + * @throws NoSuchWindowException If the window cannot be found + */ + WebDriver window(String nameOrHandle); + + /** + * Selects either the first frame on the page, or the main document when a page contains + * iframes. + * + * @return This driver focused on the top window/first frame. + */ + WebDriver defaultContent(); + + /** + * Switches to the element that currently has focus within the document currently "switched to", + * or the body element if this cannot be detected. This matches the semantics of calling + * "document.activeElement" in Javascript. + * + * @return The WebElement with focus, or the body element if no element with focus can be + * detected. + */ + WebElement activeElement(); + + /** + * Switches to the currently active modal dialog for this particular driver instance. + * + * @return A handle to the dialog. + * @throws NoAlertPresentException If the dialog cannot be found + */ + Alert alert(); + } + + interface Navigation { + /** + * Move back a single "item" in the browser's history. + */ + void back(); + + /** + * Move a single "item" forward in the browser's history. Does nothing if we are on the latest + * page viewed. + */ + void forward(); + + + /** + * Load a new web page in the current browser window. This is done using an HTTP GET operation, + * and the method will block until the load is complete. This will follow redirects issued + * either by the server or as a meta-redirect from within the returned HTML. Should a + * meta-redirect "rest" for any duration of time, it is best to wait until this timeout is over, + * since should the underlying page change whilst your test is executing the results of future + * calls against this interface will be against the freshly loaded page. + * + * @param url The URL to load. It is best to use a fully qualified URL + */ + void to(String url); + + /** + * Overloaded version of {@link #to(String)} that makes it easy to pass in a URL. + * + * @param url URL + */ + void to(URL url); + + /** + * Refresh the current page + */ + void refresh(); + } + + /** + * An interface for managing input methods. + */ + interface ImeHandler { + /** + * All available engines on the machine. To use an engine, it has to be activated. + * + * @return list of available IME engines. + * @throws ImeNotAvailableException if the host does not support IME. + */ + List getAvailableEngines(); + + /** + * Get the name of the active IME engine. The name string is platform-specific. + * + * @return name of the active IME engine. + * @throws ImeNotAvailableException if the host does not support IME. + */ + String getActiveEngine(); + + /** + * Indicates whether IME input active at the moment (not if it's available). + * + * @return true if IME input is available and currently active, false otherwise. + * @throws ImeNotAvailableException if the host does not support IME. + */ + boolean isActivated(); + + /** + * De-activate IME input (turns off the currently activated engine). Note that getActiveEngine + * may still return the name of the engine but isActivated will return false. + * + * @throws ImeNotAvailableException if the host does not support IME. + */ + void deactivate(); + + /** + * Make an engines that is available (appears on the list returned by getAvailableEngines) + * active. After this call, the only loaded engine on the IME daemon will be this one and the + * input sent using sendKeys will be converted by the engine. Noteh that this is a + * platform-independent method of activating IME (the platform-specific way being using keyboard + * shortcuts). + * + * @param engine name of engine to activate. + * @throws ImeNotAvailableException if the host does not support IME. + * @throws ImeActivationFailedException if the engine is not available or if activation failed + * for other reasons. + */ + void activateEngine(String engine); + } + + @Beta + interface Window { + /** + * Set the size of the current window. This will change the outer window dimension, + * not just the view port, synonymous to window.resizeTo() in JS. + * + * @param targetSize The target size. + */ + void setSize(Dimension targetSize); + + /** + * Set the position of the current window. This is relative to the upper left corner of the + * screen, synonymous to window.moveTo() in JS. + * + * @param targetPosition The target position of the window. + */ + void setPosition(Point targetPosition); + + /** + * Get the size of the current window. This will return the outer window dimension, not just + * the view port. + * + * @return The current window size. + */ + Dimension getSize(); + + /** + * Get the position of the current window, relative to the upper left corner of the screen. + * + * @return The current window position. + */ + Point getPosition(); + + /** + * Maximizes the current window if it is not already maximized + */ + void maximize(); + + /** + * Fullscreen the current window if it is not already fullscreen + */ + void fullscreen(); + } +} diff --git a/src/main/java/org/openqa/selenium/WebElement.java b/src/main/java/org/openqa/selenium/WebElement.java new file mode 100644 index 000000000..76aae6a3b --- /dev/null +++ b/src/main/java/org/openqa/selenium/WebElement.java @@ -0,0 +1,219 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium; + +import java.util.List; + +/** + * Represents an HTML element. Generally, all interesting operations to do with interacting with a + * page will be performed through this interface. + *

+ * All method calls will do a freshness check to ensure that the element reference is still valid. + * This essentially determines whether or not the element is still attached to the DOM. If this test + * fails, then an {@link org.openqa.selenium.StaleElementReferenceException} is thrown, and all + * future calls to this instance will fail. + */ +public interface WebElement extends SearchContext, TakesScreenshot { + /** + * Click this element. If this causes a new page to load, you + * should discard all references to this element and any further + * operations performed on this element will throw a + * StaleElementReferenceException. + *

+ * Note that if click() is done by sending a native event (which is + * the default on most browsers/platforms) then the method will + * _not_ wait for the next page to load and the caller should verify + * that themselves. + *

+ *

+ * There are some preconditions for an element to be clicked. The + * element must be visible and it must have a height and width + * greater then 0. + * + * @throws StaleElementReferenceException If the element no + * longer exists as initially defined + */ + void click(); + + /** + * If this current element is a form, or an element within a form, then this will be submitted to + * the remote server. If this causes the current page to change, then this method will block until + * the new page is loaded. + * + * @throws NoSuchElementException If the given element is not within a form + */ + void submit(); + + /** + * Use this method to simulate typing into an element, which may set its value. + * + * @param keysToSend character sequence to send to the element + */ + void sendKeys(CharSequence... keysToSend); + + /** + * If this element is a text entry element, this will clear the value. Has no effect on other + * elements. Text entry elements are INPUT and TEXTAREA elements. + *

+ * Note that the events fired by this event may not be as you'd expect. In particular, we don't + * fire any keyboard or mouse events. If you want to ensure keyboard events are fired, consider + * using something like {@link #sendKeys(CharSequence...)} with the backspace key. To ensure + * you get a change event, consider following with a call to {@link #sendKeys(CharSequence...)} + * with the tab key. + */ + void clear(); + + /** + * Get the tag name of this element. Not the value of the name attribute: will return + * "input" for the element <input name="foo" />. + * + * @return The tag name of this element. + */ + String getTagName(); + + /** + * Get the value of a the given attribute of the element. Will return the current value, even if + * this has been modified after the page has been loaded. More exactly, this method will return + * the value of the given attribute, unless that attribute is not present, in which case the value + * of the property with the same name is returned (for example for the "value" property of a + * textarea element). If neither value is set, null is returned. The "style" attribute is + * converted as best can be to a text representation with a trailing semi-colon. The following are + * deemed to be "boolean" attributes, and will return either "true" or null: + *

+ * async, autofocus, autoplay, checked, compact, complete, controls, declare, defaultchecked, + * defaultselected, defer, disabled, draggable, ended, formnovalidate, hidden, indeterminate, + * iscontenteditable, ismap, itemscope, loop, multiple, muted, nohref, noresize, noshade, + * novalidate, nowrap, open, paused, pubdate, readonly, required, reversed, scoped, seamless, + * seeking, selected, spellcheck, truespeed, willvalidate + *

+ * Finally, the following commonly mis-capitalized attribute/property names are evaluated as + * expected: + *

+ *

    + *
  • "class" + *
  • "readonly" + *
+ * + * @param name The name of the attribute. + * @return The attribute/property's current value or null if the value is not set. + */ + String getAttribute(String name); + + /** + * Determine whether or not this element is selected or not. This operation only applies to input + * elements such as checkboxes, options in a select and radio buttons. + * + * @return True if the element is currently selected or checked, false otherwise. + */ + boolean isSelected(); + + /** + * Is the element currently enabled or not? This will generally return true for everything but + * disabled input elements. + * + * @return True if the element is enabled, false otherwise. + */ + boolean isEnabled(); + + /** + * Get the visible (i.e. not hidden by CSS) innerText of this element, including sub-elements, + * without any leading or trailing whitespace. + * + * @return The innerText of this element. + */ + String getText(); + + /** + * Find all elements within the current context using the given mechanism. When using xpath be + * aware that webdriver follows standard conventions: a search prefixed with "//" will search the + * entire document, not just the children of this current node. Use ".//" to limit your search to + * the children of this WebElement. + * This method is affected by the 'implicit wait' times in force at the time of execution. When + * implicitly waiting, this method will return as soon as there are more than 0 items in the + * 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. + * @see org.openqa.selenium.By + * @see org.openqa.selenium.WebDriver.Timeouts + */ + List findElements(By by); + + /** + * Find the first {@link WebElement} using the given method. See the note in + * {@link #findElements(By)} about finding via XPath. + * This method is affected by the 'implicit wait' times in force at the time of execution. + * The findElement(..) invocation will return a matching row, or try again repeatedly until + * the configured timeout is reached. + *

+ * findElement should not be used to look for non-present elements, use {@link #findElements(By)} + * and assert zero length response instead. + * + * @param by The locating mechanism + * @return The first matching element on the current context. + * @throws NoSuchElementException If no matching elements are found + * @see org.openqa.selenium.By + * @see org.openqa.selenium.WebDriver.Timeouts + */ + T findElement(By by); + + /** + * Is this element displayed or not? This method avoids the problem of having to parse an + * element's "style" attribute. + * + * @return Whether or not the element is displayed + */ + boolean isDisplayed(); + + /** + * Where on the page is the top left-hand corner of the rendered element? + * + * @return A point, containing the location of the top left-hand corner of the element + */ + Point getLocation(); + + /** + * What is the width and height of the rendered element? + * + * @return The size of the element on the page. + */ + Dimension getSize(); + + /** + * @return The location and size of the rendered element + */ + Rectangle getRect(); + + /** + * Get the value of a given CSS property. + * Color values should be returned as rgba strings, so, + * for example if the "background-color" property is set as "green" in the + * HTML source, the returned value will be "rgba(0, 255, 0, 1)". + *

+ * Note that shorthand CSS properties (e.g. background, font, border, border-top, margin, + * margin-top, padding, padding-top, list-style, outline, pause, cue) are not returned, + * in accordance with the + * DOM CSS2 specification + * - you should directly access the longhand properties (e.g. background-color) to access the + * desired values. + * + * @param propertyName the css property name of the element + * @return The current, computed value of the property. + */ + String getCssValue(String propertyName); +} diff --git a/src/main/java/org/openqa/selenium/internal/FindsByClassName.java b/src/main/java/org/openqa/selenium/internal/FindsByClassName.java new file mode 100644 index 000000000..cc28072ec --- /dev/null +++ b/src/main/java/org/openqa/selenium/internal/FindsByClassName.java @@ -0,0 +1,28 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium.internal; + +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByClassName { + T findElementByClassName(String using); + + List findElementsByClassName(String using); +} diff --git a/src/main/java/org/openqa/selenium/internal/FindsByCssSelector.java b/src/main/java/org/openqa/selenium/internal/FindsByCssSelector.java new file mode 100644 index 000000000..74074e534 --- /dev/null +++ b/src/main/java/org/openqa/selenium/internal/FindsByCssSelector.java @@ -0,0 +1,28 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium.internal; + +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByCssSelector { + T findElementByCssSelector(String using); + + List findElementsByCssSelector(String using); +} diff --git a/src/main/java/org/openqa/selenium/internal/FindsById.java b/src/main/java/org/openqa/selenium/internal/FindsById.java new file mode 100644 index 000000000..ee4fdd9d3 --- /dev/null +++ b/src/main/java/org/openqa/selenium/internal/FindsById.java @@ -0,0 +1,28 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium.internal; + +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsById { + T findElementById(String using); + + List findElementsById(String using); +} diff --git a/src/main/java/org/openqa/selenium/internal/FindsByLinkText.java b/src/main/java/org/openqa/selenium/internal/FindsByLinkText.java new file mode 100644 index 000000000..52c09f6a1 --- /dev/null +++ b/src/main/java/org/openqa/selenium/internal/FindsByLinkText.java @@ -0,0 +1,32 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium.internal; + +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByLinkText { + T findElementByLinkText(String using); + + List findElementsByLinkText(String using); + + T findElementByPartialLinkText(String using); + + List findElementsByPartialLinkText(String using); +} diff --git a/src/main/java/org/openqa/selenium/internal/FindsByName.java b/src/main/java/org/openqa/selenium/internal/FindsByName.java new file mode 100644 index 000000000..7d39ac1d8 --- /dev/null +++ b/src/main/java/org/openqa/selenium/internal/FindsByName.java @@ -0,0 +1,28 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium.internal; + +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByName { + T findElementByName(String using); + + List findElementsByName(String using); +} diff --git a/src/main/java/org/openqa/selenium/internal/FindsByTagName.java b/src/main/java/org/openqa/selenium/internal/FindsByTagName.java new file mode 100644 index 000000000..f5df666af --- /dev/null +++ b/src/main/java/org/openqa/selenium/internal/FindsByTagName.java @@ -0,0 +1,28 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium.internal; + +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByTagName { + T findElementByTagName(String using); + + List findElementsByTagName(String using); +} diff --git a/src/main/java/org/openqa/selenium/internal/FindsByXPath.java b/src/main/java/org/openqa/selenium/internal/FindsByXPath.java new file mode 100644 index 000000000..bea6007cb --- /dev/null +++ b/src/main/java/org/openqa/selenium/internal/FindsByXPath.java @@ -0,0 +1,28 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium.internal; + +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByXPath { + T findElementByXPath(String using); + + List findElementsByXPath(String using); +}