- * The public functions and classes of Helium are listed below. If you wish to
- * use them in your scripts, all that is required is the following import:
- *
- * {@code
- * import static com.heliumhq.API.*;}
- */
-public class API {
-
- public static WebDriver startFirefox() {
- return getAPIImpl().startFirefoxImpl();
- }
- public static WebDriver startFirefox(boolean headless) {
- return getAPIImpl().startFirefoxImpl(headless);
- }
- public static WebDriver startFirefox(String url) {
- return getAPIImpl().startFirefoxImpl(url);
- }
-
- /**
- * Starts an instance of Firefox. You can optionally open a URL and/or start
- * Firefox in headless mode. For instance:
- *
- * {@code
- * startFirefox();
- * startFirefox("google.com");
- * startFirefox(true);
- * startFirefox("google.com", true);}
- *
- * Helium does not automatically close the browser when Java shuts down. To
- * terminate the browser at the end of your script, use the following
- * command:
- *
- * {@code
- * killBrowser();}
- *
- * @param url The URL to open.
- * @return a Selenium {@link org.openqa.selenium.WebDriver} object
- * representing the newly opened browser.
- */
- public static WebDriver startFirefox(String url, boolean headless) {
- return getAPIImpl().startFirefoxImpl(url, headless);
- }
-
- public static WebDriver startChrome() {
- return getAPIImpl().startChromeImpl();
- }
- public static WebDriver startChrome(boolean headless) {
- return getAPIImpl().startChromeImpl(headless);
- }
- public static WebDriver startChrome(String url) {
- return getAPIImpl().startChromeImpl(url);
- }
-
- /**
- * Starts an instance of Google Chrome. You can optionally open a URL and/or
- * start Chrome in headless mode. For instance:
- *
- * {@code
- * startChrome();
- * startChrome("google.com");
- * startChrome(true);
- * startChrome("google.com", true);}
- *
- * When Java shuts down, Helium cleans up all resources used for controlling
- * the browser (such as the ChromeDriver process), but does not close the
- * browser itself. To terminate the browser at the end of your script, use
- * the following command:
- *
- * {@code
- * killBrowser();}
- *
- * @param url The URL to open.
- * @param headless Whether Chrome should be started in headless mode.
- * Defaults to false.
- * @return a Selenium {@link org.openqa.selenium.WebDriver} object
- * representing the newly opened browser.
- */
- public static WebDriver startChrome(String url, boolean headless) {
- return getAPIImpl().startChromeImpl(url, headless);
- }
-
- public static WebDriver startIE() {
- return getAPIImpl().startIEImpl();
- }
-
- /**
- * (Windows only) Starts an instance of Internet Explorer, optionally
- * opening the specified URL. For instance:
- *
- * {@code
- * startIE();
- * startIE("google.com");}
- *
- * When Java shuts down, Helium cleans up all resources used for controlling
- * the browser (such as the IEDriverServer process), but does not close the
- * browser itself. To terminate the browser at the end of your script, use
- * the following command:
- *
- * {@code
- * killBrowser();}
- *
- * @param url The URL to open.
- * @return a Selenium {@link org.openqa.selenium.WebDriver} object
- * representing the newly opened browser.
- */
- public static WebDriver startIE(String url) {
- return getAPIImpl().startIEImpl(url);
- }
-
- /**
- * Opens the specified URL in the current web browser window. For instance:
- *
- * {@code
- * goTo("google.com");}
- *
- * @param url The URL to open.
- */
- public static void goTo(String url) {
- getAPIImpl().goToImpl(url);
- }
-
- /**
- * Sets the Selenium {@link org.openqa.selenium.WebDriver} used to execute
- * Helium commands. See also {@link API#getDriver()}.
- *
- * @param driver The new WebDriver against which all future Helium commands
- * will be issued.
- */
- public static void setDriver(WebDriver driver) {
- getAPIImpl().setDriverImpl(driver);
- }
-
- /**
- * Returns the Selenium {@link org.openqa.selenium.WebDriver} currently used
- * by Helium to execute all commands. Each Helium command such as
- * click("Login"); is translated to a sequence of Selenium
- * commands that are issued to this driver.
- *
- * @return A {@link org.openqa.selenium.WebDriver} object.
- */
- public static WebDriver getDriver() {
- return getAPIImpl().getDriverImpl();
- }
-
- public static void write(String text) {
- getAPIImpl().writeImpl(text);
- }
-
- /**
- * Types the given text into the active window. If parameter 'into' is
- * given, writes the text into the text field or element identified by that
- * parameter. Common examples of 'write' are:
- *
- * {@code
- * write("Hello World!");
- * write("user12345", into("Username:"));
- * write("Michael", into(Alert("Please enter your name")));}
- *
- * As you can see in the above examples, the function
- * {@link API#into} is used to make the script more readable.
- *
- * @param text The text to be written.
- * @param into The element to write into.
- */
- public static void write(String text, String into) {
- getAPIImpl().writeImpl(text, into);
- }
- public static void write(String text, WebElement into) {
- getAPIImpl().writeImpl(text, into);
- }
- public static void write(String text, HTMLElement into) {
- getAPIImpl().writeImpl(text, into.getImpl());
- }
- public static void write(String text, Alert into) {
- getAPIImpl().writeImpl(text, into.getImpl());
- }
-
- /**
- * The purpose of the function 'into' is to make Helium scripts more
- * readable. It simply returns the parameter passed into it. It lets you
- * write:
- *
- * {@code
- * write("user12345", into("Username:"));}
- *
- * instead of the much less readable:
- *
- * {@code
- * write("user12345", "Username:");}
- *
- * @param element The element to return.
- * @return The element parameter.
- * @see com.heliumhq.API#to
- */
- public static String into(String element) {
- return element;
- }
- public static WebElement into(WebElement element) {
- return element;
- }
- public static HTMLElement into(HTMLElement element) {
- return element;
- }
- public static Alert into(Alert element) {
- return element;
- }
-
- /**
- * Presses the given key or key combination. To press a normal letter key
- * such as "a" simply call press for it:
- *
- * {@code
- * press("a");}
- *
- * You can also simulate the pressing of upper case characters that way::
- *
- * {@code
- * press("A");}
- *
- * The special keys you can press are those given by Selenium's enum
- * {@link org.openqa.selenium.Keys}. Helium makes all those keys available
- * through its namespace, so you can just use them without having to refer
- * to {@link org.openqa.selenium.Keys}. For instance, to press the Enter
- * key:
- *
- * {@code
- * press(ENTER);}
- *
- * To press several keys at the same time, concatenate them with
- * +. For example, to press Control + a, call:
- *
- * {@code
- * press(CONTROL + "a");}
- *
- * @param key The key or combination of keys to press.
- */
- public static void press(CharSequence key) {
- getAPIImpl().pressImpl(key);
- }
-
- public final static CharSequence NULL = Keys.NULL;
- public final static CharSequence CANCEL = Keys.CANCEL;
- public final static CharSequence HELP = Keys.HELP;
- public final static CharSequence BACK_SPACE = Keys.BACK_SPACE;
- public final static CharSequence TAB = Keys.TAB;
- public final static CharSequence CLEAR = Keys.CLEAR;
- public final static CharSequence RETURN = Keys.RETURN;
- public final static CharSequence ENTER = Keys.ENTER;
- public final static CharSequence SHIFT = Keys.SHIFT;
- public final static CharSequence LEFT_SHIFT = Keys.LEFT_SHIFT;
- public final static CharSequence CONTROL = Keys.CONTROL;
- public final static CharSequence LEFT_CONTROL = Keys.LEFT_CONTROL;
- public final static CharSequence ALT = Keys.ALT;
- public final static CharSequence LEFT_ALT = Keys.LEFT_ALT;
- public final static CharSequence PAUSE = Keys.PAUSE;
- public final static CharSequence ESCAPE = Keys.ESCAPE;
- public final static CharSequence SPACE = Keys.SPACE;
- public final static CharSequence PAGE_UP = Keys.PAGE_UP;
- public final static CharSequence PAGE_DOWN = Keys.PAGE_DOWN;
- public final static CharSequence END = Keys.END;
- public final static CharSequence HOME = Keys.HOME;
- public final static CharSequence LEFT = Keys.LEFT;
- public final static CharSequence ARROW_LEFT = Keys.ARROW_LEFT;
- public final static CharSequence UP = Keys.UP;
- public final static CharSequence ARROW_UP = Keys.ARROW_UP;
- public final static CharSequence RIGHT = Keys.RIGHT;
- public final static CharSequence ARROW_RIGHT = Keys.ARROW_RIGHT;
- public final static CharSequence DOWN = Keys.DOWN;
- public final static CharSequence ARROW_DOWN = Keys.ARROW_DOWN;
- public final static CharSequence INSERT = Keys.INSERT;
- public final static CharSequence DELETE = Keys.DELETE;
- public final static CharSequence SEMICOLON = Keys.SEMICOLON;
- public final static CharSequence EQUALS = Keys.EQUALS;
- public final static CharSequence NUMPAD0 = Keys.NUMPAD0;
- public final static CharSequence NUMPAD1 = Keys.NUMPAD1;
- public final static CharSequence NUMPAD2 = Keys.NUMPAD2;
- public final static CharSequence NUMPAD3 = Keys.NUMPAD3;
- public final static CharSequence NUMPAD4 = Keys.NUMPAD4;
- public final static CharSequence NUMPAD5 = Keys.NUMPAD5;
- public final static CharSequence NUMPAD6 = Keys.NUMPAD6;
- public final static CharSequence NUMPAD7 = Keys.NUMPAD7;
- public final static CharSequence NUMPAD8 = Keys.NUMPAD8;
- public final static CharSequence NUMPAD9 = Keys.NUMPAD9;
- public final static CharSequence MULTIPLY = Keys.MULTIPLY;
- public final static CharSequence ADD = Keys.ADD;
- public final static CharSequence SEPARATOR = Keys.SEPARATOR;
- public final static CharSequence SUBTRACT = Keys.SUBTRACT;
- public final static CharSequence DECIMAL = Keys.DECIMAL;
- public final static CharSequence DIVIDE = Keys.DIVIDE;
- public final static CharSequence F1 = Keys.F1;
- public final static CharSequence F2 = Keys.F2;
- public final static CharSequence F3 = Keys.F3;
- public final static CharSequence F4 = Keys.F4;
- public final static CharSequence F5 = Keys.F5;
- public final static CharSequence F6 = Keys.F6;
- public final static CharSequence F7 = Keys.F7;
- public final static CharSequence F8 = Keys.F8;
- public final static CharSequence F9 = Keys.F9;
- public final static CharSequence F10 = Keys.F10;
- public final static CharSequence F11 = Keys.F11;
- public final static CharSequence F12 = Keys.F12;
- public final static CharSequence META = Keys.META;
- public final static CharSequence COMMAND = Keys.COMMAND;
-
- /**
- * Clicks on the given element or point. Common examples are:
- *
- * {@code
- * click("Sign in");
- * click(Button("OK"));
- * click(Point(200, 300));
- * click(ComboBox("File type").getTopLeft().withOffset(50, 0));}
- *
- * @param element The element to click.
- */
- public static void click(String element) {
- getAPIImpl().clickImpl(element);
- }
- public static void click(WebElement element) {
- getAPIImpl().clickImpl(element);
- }
- public static void click(HTMLElement element) {
- getAPIImpl().clickImpl(element.getImpl());
- }
-
- /**
- * @param point The point to click.
- */
- public static void click(Point point) {
- getAPIImpl().clickImpl(point);
- }
-
- /**
- * Performs a double click on the given element or point. Common examples
- * are:
- *
- * {@code
- * doubleclick("Double click here");
- * doubleclick(Image("Directories"));
- * doubleclick(Point(200, 300));
- * click(ComboBox("File type").getTopLeft().withOffset(50, 0));}
- *
- * @param element The element to double click.
- */
- public static void doubleclick(String element) {
- getAPIImpl().doubleclickImpl(element);
- }
- public static void doubleclick(WebElement element) {
- getAPIImpl().doubleclickImpl(element);
- }
- public static void doubleclick(HTMLElement element) {
- getAPIImpl().doubleclickImpl(element.getImpl());
- }
-
- /**
- * @param point The point to double click.
- */
- public static void doubleclick(Point point) {
- getAPIImpl().doubleclickImpl(point);
- }
-
- /**
- * Drags the given element or point to the given location. For example:
- *
- * {@code
- * drag("Drag me!", to("Drop here."));}
- *
- * The dragging is performed by hovering the mouse cursor over
- * element, pressing and holding the left mouse button, moving
- * the mouse cursor over to, and then releasing the left mouse
- * button again.
- *
- * @param element The element or point to drag.
- * @param to The place to drop the dragged element.
- */
- public static void drag(String element, String to) {
- getAPIImpl().dragImpl(element, to);
- }
- public static void drag(String element, WebElement to) {
- getAPIImpl().dragImpl(element, to);
- }
- public static void drag(String element, HTMLElement to) {
- getAPIImpl().dragImpl(element, to.getImpl());
- }
- public static void drag(String element, Point to) {
- getAPIImpl().dragImpl(element, to);
- }
- public static void drag(WebElement element, String to) {
- getAPIImpl().dragImpl(element, to);
- }
- public static void drag(WebElement element, WebElement to) {
- getAPIImpl().dragImpl(element, to);
- }
- public static void drag(WebElement element, HTMLElement to) {
- getAPIImpl().dragImpl(element, to.getImpl());
- }
- public static void drag(WebElement element, Point to) {
- getAPIImpl().dragImpl(element, to);
- }
- public static void drag(HTMLElement element, String to) {
- getAPIImpl().dragImpl(element.getImpl(), to);
- }
- public static void drag(HTMLElement element, WebElement to) {
- getAPIImpl().dragImpl(element.getImpl(), to);
- }
- public static void drag(HTMLElement element, HTMLElement to) {
- getAPIImpl().dragImpl(element.getImpl(), to.getImpl());
- }
- public static void drag(HTMLElement element, Point to) {
- getAPIImpl().dragImpl(element.getImpl(), to);
- }
- public static void drag(Point element, String to) {
- getAPIImpl().dragImpl(element, to);
- }
- public static void drag(Point element, WebElement to) {
- getAPIImpl().dragImpl(element, to);
- }
- public static void drag(Point element, HTMLElement to) {
- getAPIImpl().dragImpl(element, to.getImpl());
- }
- public static void drag(Point element, Point to) {
- getAPIImpl().dragImpl(element, to);
- }
-
- /**
- * Lets you find all occurrences of the given GUI element predicate. For
- * instance, the following statement returns a list of all buttons with
- * label "Open":
- *
- * {@code
- * findAll(Button("Open"));}
- *
- * Other examples are:
- *
- * {@code
- * findAll(Window());
- * findAll(TextField("Address line 1"));}
- *
- * The function returns a list of elements of the same type as the passed-in
- * parameter. For instance, findAll(Button(...)); yields
- * an object of type List<Button>.
- *
- * @param predicate Any {@link com.heliumhq.API.GUIElement}.
- * @return A list of occurrences of the given predicate on the current page.
- */
- public static List findAll(G predicate) {
- List result = new ArrayList();
- for (Object impl : getAPIImpl().findAllImpl(predicate.getImpl()))
- try {
- Constructor constructor = (Constructor) predicate.
- getClass().getDeclaredConstructor(impl.getClass());
- constructor.setAccessible(true);
- result.add(constructor.newInstance(impl));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- return result;
- }
-
- public static void scrollDown() {
- getAPIImpl().scrollDownImpl();
- }
-
- /**
- * Scrolls down the page. The distance scrolled can be given by parameter
- * numPixels, and defaults to 100.
- *
- * @param numPixels The distance to scroll in pixels.
- */
- public static void scrollDown(int numPixels) {
- getAPIImpl().scrollDownImpl(numPixels);
- }
-
- public static void scrollUp() {
- getAPIImpl().scrollUpImpl();
- }
-
- /**
- * Scrolls up the page. The distance scrolled can be given by parameter
- * numPixels, and defaults to 100.
- *
- * @param numPixels The distance to scroll in pixels.
- */
- public static void scrollUp(int numPixels) {
- getAPIImpl().scrollUpImpl(numPixels);
- }
-
- public static void scrollRight() {
- getAPIImpl().scrollRightImpl();
- }
-
- /**
- * Scrolls the page to the right. The distance scrolled can be given by
- * parameter numPixels, and defaults to 100.
- *
- * @param numPixels The distance to scroll in pixels.
- */
- public static void scrollRight(int numPixels) {
- getAPIImpl().scrollRightImpl(numPixels);
- }
-
- public static void scrollLeft() {
- getAPIImpl().scrollLeftImpl();
- }
-
- /**
- * Scrolls the page to the left. The distance scrolled can be given by
- * parameter numPixels, and defaults to 100.
- *
- * @param numPixels The distance to scroll in pixels.
- */
- public static void scrollLeft(int numPixels) {
- getAPIImpl().scrollLeftImpl(numPixels);
- }
-
- /**
- * Hovers the mouse cursor over the given element or point. For example:
- *
- * {@code
- * hover("File size");
- * hover(Button("OK"));
- * hover(Link("Download"));
- * hover(Point(200, 300));
- * hover(ComboBox("File type").getTopLeft().withOffset(50, 0));}
- *
- * @param element The element to hover.
- */
- public static void hover(String element) {
- getAPIImpl().hoverImpl(element);
- }
- public static void hover(WebElement element) {
- getAPIImpl().hoverImpl(element);
- }
- public static void hover(HTMLElement element) {
- getAPIImpl().hoverImpl(element.getImpl());
- }
-
- /**
- * @param point The point to hover.
- */
- public static void hover(Point point) {
- getAPIImpl().hoverImpl(point);
- }
-
- /**
- * Performs a right click on the given element or point. For example:
- *
- * {@code
- * rightclick("Something");
- * rightclick(Point(200, 300));
- * rightclick(Image("captcha"));}
- *
- * @param element The element to right click.
- */
- public static void rightclick(String element) {
- getAPIImpl().rightclickImpl(element);
- }
- public static void rightclick(WebElement element) {
- getAPIImpl().rightclickImpl(element);
- }
- public static void rightclick(HTMLElement element) {
- getAPIImpl().rightclickImpl(element.getImpl());
- }
-
- /**
- * @param point The point to right click.
- */
- public static void rightclick(Point point) {
- getAPIImpl().rightclickImpl(point);
- }
-
- /**
- * Selects a value from a combo box. For example:
- *
- * {@code
- * select("Language", "English");
- * select(ComboBox("Language"), "English");}
- *
- * @param comboBox The combo box whose value should be changed.
- * @param value The visible value of the combo box to be selected.
- */
- public static void select(String comboBox, String value) {
- getAPIImpl().selectImpl(comboBox, value);
- }
- public static void select(ComboBox comboBox, String value) {
- getAPIImpl().selectImpl(comboBox.getImpl(), value);
- }
-
- /**
- * Simulates the dragging of a file from the computer over the browser
- * window and dropping it over the given element. This allows, for example,
- * to attach files to emails in Gmail:
- *
- * {@code
- * click("COMPOSE");
- * write("example@gmail.com", into("To"));
- * write("Email subject", into("Subject"));
- * dragFile("C:\\Documents\\notes.txt", to("Drop files here"));}
- *
- * As you can see in the above example, the function {@link API#to} is used
- * to make the script more readable.
- *
- * @param filePath The path of the file to be attached.
- * @param to The element to drop the dragged file on.
- */
- public static void dragFile(String filePath, String to) {
- getAPIImpl().dragFileImpl(filePath, to);
- }
- public static void dragFile(String filePath, WebElement to) {
- getAPIImpl().dragFileImpl(filePath, to);
- }
- public static void dragFile(String filePath, HTMLElement to) {
- getAPIImpl().dragFileImpl(filePath, to.getImpl());
- }
-
- /**
- * The purpose of the function 'to' is to make Helium scripts more
- * readable. It simply returns the parameter passed into it. It lets you
- * write:
- *
- * {@code
- * attachFile("c:/test.txt", to("Please select a file:"));}
- *
- * instead of the much less readable:
- *
- * {@code
- * attachFile("c:/test.txt", "Please select a file:");}
- *
- * Similarly, to can be used with {@link API#dragFile}:
- *
- * {@code
- * dragFile("C:\\Documents\\notes.txt", to("Drop files here"));}
- *
- * @param element The element to return.
- * @return The element parameter.
- * @see com.heliumhq.API#into
- */
- public static String to(String element) {
- return element;
- }
- public static WebElement to(WebElement element) {
- return element;
- }
- public static HTMLElement to(HTMLElement element) {
- return element;
- }
- public static Point to(Point element) {
- return element;
- }
-
- public static void attachFile(String filePath) {
- getAPIImpl().attachFileImpl(filePath);
- }
-
- /**
- * Allows attaching a file to a file input element or point. For instance:
- *
- * {@code
- * attachFile("c:/test.txt", to("Please select a file:"));}
- *
- * The file input element is identified by its label. If you omit the
- * to parameter, then Helium attaches the file to the first
- * file input element it finds on the page.
- *
- * As you can see in the above example, the function {@link API#to} is used
- * to make the script more readable.
- *
- * @param filePath The path of the file to be attached.
- * @param to The file input element to which to attach the file.
- */
- public static void attachFile(String filePath, String to) {
- getAPIImpl().attachFileImpl(filePath, to);
- }
- public static void attachFile(String filePath, WebElement to) {
- getAPIImpl().attachFileImpl(filePath, to);
- }
- public static void attachFile(String filePath, HTMLElement to) {
- getAPIImpl().attachFileImpl(filePath, to.getImpl());
- }
- public static void attachFile(String filePath, Point to) {
- getAPIImpl().attachFileImpl(filePath, to);
- }
-
- /**
- * Refreshes the current page. If an alert dialog is open, then Helium first
- * closes it.
- */
- public static void refresh() {
- getAPIImpl().refreshImpl();
- }
-
- public static void waitUntil(ExpectedCondition> condition) {
- getAPIImpl().waitUntilImpl(condition);
- }
- public static void waitUntil(
- ExpectedCondition> condition, long timeoutSecs
- ) {
- getAPIImpl().waitUntilImpl(condition, timeoutSecs);
- }
-
- /**
- * Waits until the given condition becomes true. This is most commonly used
- * to wait for an element to exist:
- *
- * {@code
- * waitUntil(Text("Finished!").exists);}
- *
- * You can wait for any boolean property exposed by Helium's GUI elements
- * this way. Here are some further examples:
- *
- * {@code
- * waitUntil(Button("Download").isEnabled);
- * waitUntil(Link("Proceed").exists);
- * waitUntil(TextField("Credit card number").isEditable);
- * ...}
- *
- * In general, waitUntil accepts any Selenium
- * {@link org.openqa.selenium.support.ui.ExpectedCondition}. For instance,
- * you can use {@link org.openqa.selenium.support.ui.ExpectedConditions#not(
- *org.openqa.selenium.support.ui.ExpectedCondition)}
- * to negate a condition:
- *
- * {@code
- * import static org.openqa.selenium.support.ui.ExpectedConditions.not;
- * ...
- * waitUntil(not(Text("Processing...").exists));}
- *
- * The parameter timeoutSecs controls how long Helium waits for
- * the condition to become true. If it does not become true within the given
- * number of seconds, then a {@link org.openqa.selenium.TimeoutException}
- * is thrown.
- *
- * intervalSecs specifies how long Helium waits in between
- * consecutive checks of the condition. The default of 0.5
- * makes Helium check every 500ms.
- *
- * It is recommended to use the functions {@link API#timeoutSecs(long)} and
- * {@link API#intervalSecs(double)} when specifying the time parameters for
- * improved readability. For example:
- *
- * {@code
- * waitUntil(Text("Done!").exists, timeoutSecs(15), intervalSecs(1));}
- *
- * @param condition The condition to wait for.
- * @param timeoutSecs The timeout after which Helium aborts the wait, in
- * seconds. Default: 10.
- * @param intervalSecs The number of seconds Helium waits between
- * consecutive checks of the given condition.
- * Default: 0.5 (500 ms).
- * @throws org.openqa.selenium.TimeoutException if the given condition isn't
- * fulfilled within timeoutSecs.
- */
- public static void waitUntil(
- ExpectedCondition> condition, long timeoutSecs,
- double intervalSecs
- ) {
- getAPIImpl().waitUntilImpl(condition, timeoutSecs, intervalSecs);
- }
-
- /**
- * This function is used to improve the readability of Helium scripts that
- * use {@link API#waitUntil}. It simply returns the parameter passed into
- * it. It lets you write:
- *
- * {@code
- * waitUntil(Text(...).exists, timeoutSecs(10));}
- *
- * instead of the less readable:
- *
- * {@code
- * waitUntil(Text(...).exists, 10);}
- *
- * @param timeoutSecs The timeout to be passed into waitUntil.
- * @return the timeoutSecs parameter passed when calling this function.
- */
- public static long timeoutSecs(long timeoutSecs) {
- return timeoutSecs;
- }
- /**
- * Similarly to {@link API#timeoutSecs(long)}, this function is used to
- * improve the readability of Helium scripts that use {@link API#waitUntil}.
- * It simply returns the parameter passed into it. It lets you write:
- *
- * {@code
- * waitUntil(Text(...).exists, timeoutSecs(10), intervalSecs(1));}
- *
- * instead of the less readable:
- *
- * {@code
- * waitUntil(Text(...).exists, timeoutSecs(10), 1);}
- *
- * @param intervalSecs The wait interval to be passed into waitUntil.
- * @return the intervalSecs parameter passed when calling this function.
- */
- public static double intervalSecs(double intervalSecs) {
- return intervalSecs;
- }
-
- /**
- * This class contains Helium's run-time configuration. To modify Helium's
- * behaviour, simply set the properties of this class. For instance:
- *
- * {@code
- * Config.setImplicitWaitSecs(0);}
- */
- public static class Config {
- private Config() {}
- private static double implicitWaitSecs = 10;
- /**
- * Suppose you have a script that executes the following command:
- *
- * {@code
- * click("Download");}
- *
- * If the "Download" element is not immediately available, then Helium
- * by default waits up to 10 seconds before throwing a
- * {@link org.openqa.selenium.NoSuchElementException}. This is useful in
- * situations where the page takes slightly longer to load, or a GUI
- * element only appears after a certain time (eg. after an AJAX
- * request).
- *
- * The function Config.setImplicitWaitSecs(...) lets you
- * configure the timeout before Helium throws a
- * {@link org.openqa.selenium.NoSuchElementException} when an element
- * cannot be found. For instance, to increase the timeout to 30 seconds,
- * you can call:
- *
- * {@code
- * Config.setImplicitWaitSecs(30);}
- *
- * To disable Helium's implicit waits entirely, you can call:
- *
- * {@code
- * Config.setImplicitWaitSecs(0);}
- *
- * Helium's implicit waits do not affect commands {@link API#findAll} or
- * {@link GUIElement#exists()}. Note also that calling
- * setImplicitWaitSecs(...) does not affect the underlying
- * Selenium driver (see {@link API#getDriver()}).
- *
- * For the best results, it is recommended to not use Selenium's
- * .implicitlyWait(...) in conjunction with Helium.
- *
- * @param value The new timeout, in seconds, after which Helium
- * throws
- * {@link org.openqa.selenium.NoSuchElementException}
- * when GUI elements cannot be found.
- */
- public static void setImplicitWaitSecs(double value) {
- implicitWaitSecs = value;
- }
- /**
- * Returns the number of seconds (as a double) Helium waits
- * before throwing a {@link org.openqa.selenium.NoSuchElementException}
- * when a GUI element cannot be found. Please see
- * {@link com.heliumhq.API.Config#setImplicitWaitSecs(double)} for a
- * more comprehensive description of this feature.
- */
- public static double getImplicitWaitSecs() {
- return implicitWaitSecs;
- }
- }
-
- /**
- * Abstract base class for all GUI elements identifiable by Helium:
- *
- *
- *
All {@link com.heliumhq.API.HTMLElement}s
- *
{@link API#Alert(java.lang.String)}
- *
{@link API#Window(java.lang.String)}
- *
- */
- public static abstract class GUIElement {
- private final GUIElementImpl impl;
- private GUIElement(GUIElementImpl impl) {
- this.impl = impl;
- }
- /**
- * Returns true if this GUI element exists,
- * false otherwise.
- */
- public boolean exists() {
- return impl.exists();
- }
- /**
- * An {@link org.openqa.selenium.support.ui.ExpectedCondition} that can
- * be used in conjunction with {@link com.heliumhq.API#waitUntil(
- * org.openqa.selenium.support.ui.ExpectedCondition)} to wait for this
- * GUI element to exist. For example, to wait until a certain text is
- * shown on the page, one can use:
- *
- * {@code
- * waitUntil(Text("Email sent").exists);}
- *
- * The same pattern can be used for Helium's other GUI elements:
- * waitUntil(Button(...).exists);,
- * waitUntil(CheckBox(...).exists);,
- * waitUntil(Window(...).exists); etc.
- */
- public final ExpectedCondition exists =
- new ExpectedCondition() {
- @Override
- public Boolean apply(WebDriver input) {
- return exists();
- }
- };
- @Override
- public String toString() {
- return impl.toString(getClass().getSimpleName());
- }
- GUIElementImpl getImpl() {
- return impl;
- }
- }
-
- /**
- * Abstract base class for HTML elements identifiable by Helium on a web
- * page:
- *
- */
- public static abstract class HTMLElement extends GUIElement {
- private HTMLElement(HTMLElementImpl impl) {
- super(impl);
- }
- /**
- * Returns an int giving the width of this HTML element, in
- * pixels.
- */
- public int getWidth() {
- return getImpl().getWidth();
- }
- /**
- * Returns an int giving the height of this HTML element,
- * in pixels.
- */
- public int getHeight() {
- return getImpl().getHeight();
- }
- /**
- * Returns an int giving the x-coordinate of the top-left
- * point of this UI element.
- */
- public int getX() {
- return getImpl().getX();
- }
- /**
- * Returns an int giving the y-coordinate of the top-left
- * point of this UI element.
- */
- public int getY() {
- return getImpl().getY();
- }
- /**
- * Returns the top left corner of this element, as a
- * {@link com.heliumhq.API.Point}. This point has exactly the
- * coordinates given by this element's .getX() and
- * .getY() properties. getTopLeft() is for
- * instance useful for clicking at an offset of an element:
- *
- * {@code
- * click(Button("OK").getTopLeft().withOffset(30, 15));}
- */
- public Point getTopLeft() {
- return getImpl().getTopLeft();
- }
- /**
- * Returns the Selenium {@link org.openqa.selenium.WebElement}
- * corresponding to this element.
- */
- public WebElement getWebElement() {
- return getImpl().getWebElement();
- }
- HTMLElementImpl getImpl() {
- return (HTMLElementImpl) super.getImpl();
- }
- }
-
- /**
- * Switches to the given browser window. For example:
- *
- * {@code
- * switchTo("Google");}
- *
- * This searches for a browser window whose title contains "Google", and
- * activates it.
- *
- * If there are multiple windows with the same title, then you can use
- * {@link API#findAll} to find all open windows, pick out the one you want
- * and pass that to switchTo. For example, the following
- * snippet switches to the first window in the list of open windows:
- *
- * {@code
- * switchTo(findAll(Window()).get(0));}
- *
- * @param windowTitle The title of the window to switch to.
- */
- public static void switchTo(String windowTitle) {
- getAPIImpl().switchToImpl(windowTitle);
- }
-
- /**
- * @param window The window to switch to.
- */
- public static void switchTo(Window window) {
- getAPIImpl().switchToImpl(window.getImpl());
- }
-
- /**
- * Closes the current browser with all associated windows and potentially
- * open dialogs. Dialogs opened as a response to the browser closing (eg.
- * "Are you sure you want to leave this page?") are also ignored and closed.
- *
- * This function is most commonly used to close the browser at the end of an
- * automation run:
- *
- * {@code
- * startChrome();
- * ...
- * // Close Chrome:
- * killBrowser();}
- */
- public static void killBrowser() {
- getAPIImpl().killBrowserImpl();
- }
-
- /**
- * Highlights the given element on the page by drawing a red rectangle
- * around it. This is useful for debugging purposes. For example:
- *
- * {@code
- * highlight("Helium");
- * highlight(Button("Sign in"));}
- *
- * @param element The element to highlight.
- */
- public static void highlight(String element) {
- getAPIImpl().highlightImpl(element);
- }
- public static void highlight(HTMLElement element) {
- getAPIImpl().highlightImpl(element.getImpl());
- }
- public static void highlight(WebElement element) {
- getAPIImpl().highlightImpl(element);
- }
-
- /**
- * A jQuery-style selector for identifying HTML elements by ID, name, CSS
- * class, CSS selector or XPath. For example: Say you have an element with
- * ID "myId" on a web page, such as <div id="myId" .../>.
- * Then you can identify this element using $ as follows:
- *
- * {@code
- * $("#myId")}
- *
- * The parameter which you pass to $(...) is interpreted by
- * Helium according to these rules:
- *
- *
- *
If it starts with an @, then it identifies elements
- * by HTML name. Eg. $("@btnName") identifies
- * an element with name="btnName".
- *
If it starts with //, then Helium interprets it as
- * an XPath.
- *
Otherwise, Helium interprets it as a CSS selector. This in
- * particular lets you write $("#myId") to identify an
- * element with id="myId", or $(".myClass")
- * to identify elements with class="myClass".
- *
- * @param selector The selector used to identify the HTML element(s).
- * @param searchRegion The search region to find the text in.
- * See the documentation of {@link API#below}.*
- */
- public static $ $(String selector, SearchRegion... searchRegion) {
- return new $(getAPIImpl().$Impl(selector, searchRegion));
- }
-
- public static class $ extends HTMLElement {
- private $($Impl impl) {
- super(impl);
- }
- }
-
- /**
- * Lets you identify any text or label on a web page. This is most useful
- * for checking whether a particular text exists:
- *
- * {@code
- * if (Text("Do you want to proceed?").exists())
- * click("Yes");}
- *
- * {@link com.heliumhq.API.Text} also makes it possible to read plain text
- * data from a web page. For example, suppose you have a table of people's
- * email addresses. Then you can read John's email addresses as follows:
- *
- * {@code
- * Text(below("Email"), toRightOf("John")).getValue()}
- *
- * Similarly to below and toRightOf, the keyword
- * parameters {@link API#above} and {@link API#toLeftOf} can be used to
- * search for texts above and to the left of other web elements.
- *
- * @param text The text to identify.
- * @param searchRegion The search region to find the text in.
- * See the documentation of {@link API#below}.
- */
- public static Text Text(String text, SearchRegion... searchRegion) {
- return new Text(getAPIImpl().TextImpl(text, searchRegion));
- }
- public static Text Text(SearchRegion... searchRegion) {
- return new Text(getAPIImpl().TextImpl(searchRegion));
- }
- public static class Text extends HTMLElement {
- private Text(TextImpl impl) {
- super(impl);
- }
- /**
- * Returns the current value of this Text object, as a
- * {@link java.lang.String}.
- */
- public String getValue() {
- return getImpl().getValue();
- }
- TextImpl getImpl() {
- return (TextImpl) super.getImpl();
- }
- }
-
- /**
- * Lets you identify a link on a web page. A typical usage of
- * Link is:
- *
- * {@code
- * click(Link("Sign in"));}
- *
- * You can also read a Link's properties. This is most
- * typically used to check for a link's existence before clicking on it:
- *
- * {@code
- * if (Link("Sign in").exists())
- * click(Link("Sign in"));}
- *
- * When there are multiple occurrences of a link on a page, you can
- * disambiguate between them using {@link API#below}, {@link API#toRightOf},
- * {@link API#above} and {@link API#toLeftOf}. For instance:
- *
- * {@code
- * click(Link("Block User", toRightOf("John Doe")));}
- *
- * @param text The link text or title.
- * @param searchRegion The search region to find the link in.
- * See the documentation of {@link API#below}.
- */
- public static Link Link(String text, SearchRegion... searchRegion) {
- return new Link(getAPIImpl().LinkImpl(text, searchRegion));
- }
- public static Link Link(SearchRegion... searchRegion) {
- return new Link(getAPIImpl().LinkImpl(searchRegion));
- }
- public static class Link extends HTMLElement {
- private Link(LinkImpl impl) {
- super(impl);
- }
- /**
- * Returns the URL of the page the link goes to, as a
- * {@link java.lang.String}. If there is no value, null is returned.
- */
- public String getHref() {
- return ((LinkImpl)getImpl()).getHref();
- }
- }
-
- /**
- * Lets you identify a list item (HTML <li> element) on a
- * web page. This is often useful for interacting with elements of a
- * navigation bar:
- *
- * {@code
- * click(ListItem("News Feed"));}
- *
- * In other cases such as an automated test, you might want to query the
- * properties of a ListItem. For example, the following snippet
- * checks whether a list item with text "List item 1" exists, and raises an
- * error if not:
- *
- * {@code
- * if (! ListItem("List item 1").exists())
- * throw new AssertionError("List item 1 does not exist");}
- *
- * When there are multiple occurrences of a list item on a page, you can
- * disambiguate between them using the functions {@link API#below},
- * {@link API#toRightOf}, {@link API#above} and {@link API#toLeftOf}.
- * For instance:
- * {@code
- * click(ListItem("List item 1", below("My first list:")));}
- *
- * @param text The text (label) of the list item.
- * @param searchRegion The search region to find the list item in.
- * See the documentation of {@link API#below}.
- */
- public static ListItem ListItem(String text, SearchRegion... searchRegion) {
- return new ListItem(getAPIImpl().ListItemImpl(text, searchRegion));
- }
- public static ListItem ListItem(SearchRegion... searchRegion) {
- return new ListItem(getAPIImpl().ListItemImpl(searchRegion));
- }
- public static class ListItem extends HTMLElement {
- private ListItem(ListItemImpl impl) {
- super(impl);
- }
- }
-
- /**
- * Lets you identify a button on a web page. A typical usage of
- * Button is:
- *
- * {@code
- * click(Button("Log In"));}
- *
- * Button also lets you read a button's properties. For
- * example, the following snippet clicks button "OK" only if it exists:
- *
- * {@code
- * if (Button("OK").exists())
- * click(Button("OK"));}
- *
- * When there are multiple occurrences of a button on a page, you can
- * disambiguate between them using the functions {@link API#below},
- * {@link API#toRightOf}, {@link API#above} and {@link API#toLeftOf}. For
- * instance:
- *
- * {@code
- * click(Button("Log In", below(TextField("Password"))));}
- *
- * @param text The button label.
- * @param searchRegion The search region to find the button in.
- * See the documentation of {@link API#below}.
- */
- public static Button Button(String text, SearchRegion... searchRegion) {
- return new Button(getAPIImpl().ButtonImpl(text, searchRegion));
- }
- public static Button Button(SearchRegion... searchRegion) {
- return new Button(getAPIImpl().ButtonImpl(searchRegion));
- }
- public static class Button extends HTMLElement {
- private Button(ButtonImpl impl) {
- super(impl);
- }
- /**
- * Returns true if this button can currently be interacted
- * with, false otherwise.
- */
- public boolean isEnabled() {
- return getImpl().isEnabled();
- }
- /**
- * An {@link org.openqa.selenium.support.ui.ExpectedCondition} that can
- * be used in conjunction with {@link com.heliumhq.API#waitUntil(
- * org.openqa.selenium.support.ui.ExpectedCondition)} to wait for this
- * Button to become enabled. For example:
- *
- * {@code
- * waitUntil(Button("Submit").isEnabled);}
- */
- public final ExpectedCondition isEnabled =
- new ExpectedCondition() {
- @Override
- public Boolean apply(WebDriver input) {
- return isEnabled();
- }
- };
- ButtonImpl getImpl() {
- return (ButtonImpl) super.getImpl();
- }
- }
-
- /**
- * Lets you identify an image (HTML <img> element) on a
- * web page. Typically, this is done via the image's alt text. For instance:
- *
- * {@code
- * click(Image("Helium Logo"));}
- *
- * You can also query an image's properties. For example, the following
- * snippet clicks on the image with alt text "Helium Logo" only if it
- * exists:
- *
- * {@code
- * if (Image("Helium Logo").exists())
- * click(Image("Helium Logo"));}
- *
- * When there are multiple occurrences of an image on a page, you can
- * disambiguate between them using the functions {@link API#below},
- * {@link API#toRightOf}, {@link API#above} and {@link API#toLeftOf}. For
- * instance:
- *
- * {@code
- * click(Image("Helium Logo", toLeftOf(ListItem("Download"))));}
- *
- * @param alt The image's alt text.
- * @param searchRegion The search region to find the image in.
- * See the documentation of {@link API#below}.
- */
- public static Image Image(String alt, SearchRegion... searchRegion) {
- return new Image(getAPIImpl().ImageImpl(alt, searchRegion));
- }
- public static Image Image(SearchRegion... searchRegion) {
- return new Image(getAPIImpl().ImageImpl(searchRegion));
- }
- public static class Image extends HTMLElement {
- private Image(ImageImpl impl) {
- super(impl);
- }
- }
-
- /**
- * Lets you identify a text field on a web page. This is most typically done
- * to read the value of a text field. For example:
- *
- * {@code
- * TextField("First name").getValue()}
- *
- * This returns the value of the "First name" text field. If it is empty,
- * the empty string "" is returned.
- *
- * When there are multiple occurrences of a text field on a page, you can
- * disambiguate between them using the functions {@link API#below},
- * {@link API#toRightOf}, {@link API#above} and {@link API#toLeftOf}. For
- * instance:
- *
- * {@code
- * TextField("Address line 1", below("Billing Address:")).getValue()}
- *
- * @param label The label (human-visible name) of the text field.
- * @param searchRegion The search region to find the text field in.
- * See the documentation of {@link API#below}.
- */
- public static TextField TextField(
- String label, SearchRegion... searchRegion
- ) {
- return new TextField(getAPIImpl().TextFieldImpl(label, searchRegion));
- }
- public static TextField TextField(SearchRegion... searchRegion) {
- return new TextField(getAPIImpl().TextFieldImpl(searchRegion));
- }
- public static class TextField extends HTMLElement {
- private TextField(TextFieldImpl impl) {
- super(impl);
- }
- /**
- * Returns the current value of this text field, as a
- * {@link java.lang.String}. If there is no value, "" is returned.
- */
- public String getValue() {
- return getImpl().getValue();
- }
- /**
- * Returns a boolean indicating whether this text field can
- * currently be interacted with.
- *
- * The difference between a text field being 'enabled' and 'editable' is
- * mostly visual: If a text field is not enabled, it is usually greyed
- * out, whereas if it is not editable it looks normal. See also
- * {@link TextField#isEditable()}.
- */
- public boolean isEnabled() {
- return getImpl().isEnabled();
- }
- /**
- * An {@link org.openqa.selenium.support.ui.ExpectedCondition} that can
- * be used in conjunction with {@link com.heliumhq.API#waitUntil(
- * org.openqa.selenium.support.ui.ExpectedCondition)} to wait for this
- * TextField to become enabled. For example:
- *
- * {@code
- * waitUntil(TextField("Subject").isEnabled);}
- */
- public final ExpectedCondition isEnabled =
- new ExpectedCondition() {
- @Override
- public Boolean apply(WebDriver input) {
- return isEnabled();
- }
- };
- /**
- * Returns true if the value of the text field can be
- * modified, false otherwise.
- *
- * The difference between a text field being 'enabled' and 'editable' is
- * mostly visual: If a text field is not enabled, it is usually greyed
- * out, whereas if it is not editable it looks normal. See also
- * {@link TextField#isEnabled()}.
- */
- public boolean isEditable() {
- return getImpl().isEditable();
- }
- /**
- * An {@link org.openqa.selenium.support.ui.ExpectedCondition} that can
- * be used in conjunction with {@link com.heliumhq.API#waitUntil(
- * org.openqa.selenium.support.ui.ExpectedCondition)} to wait for this
- * TextField to become editable. For example:
- *
- * {@code
- * waitUntil(TextField("Is active").isEditable);}
- */
- public final ExpectedCondition isEditable =
- new ExpectedCondition() {
- @Override
- public Boolean apply(WebDriver input) {
- return isEditable();
- }
- };
- TextFieldImpl getImpl() {
- return (TextFieldImpl) super.getImpl();
- }
- }
-
- /**
- * Lets you identify a combo box on a web page. This can for instance be
- * used to determine the current value of a combo box:
- * {@code
- * ComboBox("Language").getValue()}
- *
- * A ComboBox may be editable, which means that it is possible
- * to type in arbitrary values in addition to selecting from a predefined
- * drop-down list of values. The property
- * {@link com.heliumhq.API.ComboBox#isEditable()} can be used to
- * determine whether this is the case for a particular combo box instance.
- *
- * When there are multiple occurrences of a combo box on a page, you can
- * disambiguate between them using the functions {@link API#below},
- * {@link API#toRightOf}, {@link API#above} and {@link API#toLeftOf}. For
- * instance:
- *
- * {@code
- * select(ComboBox(toRightOf("John Doe"), below("Status")), "Active")}
- *
- * This sets the Status of John Doe to Active on the page.
- *
- * @param label The label (human-visible name) of the combo box.
- * @param searchRegion The search region to find the combo box in.
- * See the documentation of {@link API#below}.
- */
- public static ComboBox ComboBox(
- String label, SearchRegion... searchRegion
- ) {
- return new ComboBox(getAPIImpl().ComboBoxImpl(label, searchRegion));
- }
- public static ComboBox ComboBox(SearchRegion... searchRegion) {
- return new ComboBox(getAPIImpl().ComboBoxImpl(searchRegion));
- }
- public static class ComboBox extends HTMLElement {
- private ComboBox(ComboBoxImpl impl) {
- super(impl);
- }
- /**
- * Returns true if this combo box allows entering an
- * arbitrary text in addition to selecting predefined values from a
- * drop-down list. Otherwise, returns false.
- */
- public boolean isEditable() {
- return getImpl().isEditable();
- }
- /**
- * An {@link org.openqa.selenium.support.ui.ExpectedCondition} that can
- * be used in conjunction with {@link com.heliumhq.API#waitUntil(
- * org.openqa.selenium.support.ui.ExpectedCondition)} to wait for this
- * ComboBox to become editable. For example:
- *
- * {@code
- * waitUntil(ComboBox("Region").isEditable);}
- */
- public final ExpectedCondition isEditable =
- new ExpectedCondition() {
- @Override
- public Boolean apply(WebDriver input) {
- return isEditable();
- }
- };
- /**
- * Returns a List<String> of all possible options
- * available to choose from in the combo box.
- */
- public List getOptions() {
- return getImpl().getOptions();
- }
- /**
- * Returns the currently selected combo box value, as a
- * {@link java.lang.String}.
- */
- public String getValue() {
- return getImpl().getValue();
- }
- ComboBoxImpl getImpl() {
- return (ComboBoxImpl) super.getImpl();
- }
- }
-
- /**
- * Lets you identify a check box on a web page. To tick a currently
- * unselected check box, use:
- *
- * {@code
- * click(CheckBox("I agree"));}
- *
- * CheckBox also lets you read the properties of a check box.
- * For example,
- * the method {@link com.heliumhq.API.CheckBox#isChecked()} can be used to
- * only click a check box if it isn't already checked:
- *
- * {@code
- * if (! CheckBox("I agree").isChecked())
- * click(CheckBox("I agree"));}
- *
- * When there are multiple occurrences of a check box on a page, you can
- * disambiguate between them using the functions {@link API#below},
- * {@link API#toRightOf}, {@link API#above} and {@link API#toLeftOf}. For
- * instance:
- *
- * {@code
- * click(CheckBox("Stay signed in", below(Button("Sign in"))));}
- *
- * @param label The label (human-visible name) of the check box.
- * @param searchRegion The search region to find the check box in.
- * See the documentation of {@link API#below}.
- */
- public static CheckBox CheckBox(
- String label, SearchRegion... searchRegion
- ) {
- return new CheckBox(getAPIImpl().CheckBoxImpl(label, searchRegion));
- }
- public static CheckBox CheckBox(SearchRegion... searchRegion) {
- return new CheckBox(getAPIImpl().CheckBoxImpl(searchRegion));
- }
- public static class CheckBox extends HTMLElement {
- private CheckBox(CheckBoxImpl impl) {
- super(impl);
- }
- /**
- * Returns true if this check box can currently be
- * interacted with, false otherwise.
- */
- public boolean isEnabled() {
- return getImpl().isEnabled();
- }
- /**
- * An {@link org.openqa.selenium.support.ui.ExpectedCondition} that can
- * be used in conjunction with {@link com.heliumhq.API#waitUntil(
- * org.openqa.selenium.support.ui.ExpectedCondition)} to wait for this
- * CheckBox to become enabled. For example:
- *
- * {@code
- * waitUntil(CheckBox("I agree").isEnabled);}
- */
- public final ExpectedCondition isEnabled =
- new ExpectedCondition() {
- @Override
- public Boolean apply(WebDriver input) {
- return isEnabled();
- }
- };
- /**
- * Returns true if this check box is checked (selected).
- * false otherwise.
- */
- public boolean isChecked() {
- return getImpl().isChecked();
- }
- /**
- * An {@link org.openqa.selenium.support.ui.ExpectedCondition} that can
- * be used in conjunction with {@link com.heliumhq.API#waitUntil(
- * org.openqa.selenium.support.ui.ExpectedCondition)} to wait for this
- * CheckBox to become checked. For example:
- *
- * {@code
- * waitUntil(CheckBox("Is active").isChecked);}
- */
- public final ExpectedCondition isChecked =
- new ExpectedCondition() {
- @Override
- public Boolean apply(WebDriver input) {
- return isChecked();
- }
- };
- CheckBoxImpl getImpl() {
- return (CheckBoxImpl) super.getImpl();
- }
- }
-
- /**
- * Lets you identify a radio button on a web page. To select a currently
- * unselected radio button, use:
- *
- * {@code
- * click(RadioButton("Windows"))}
- *
- * RadioButton also lets you read the properties of a radio
- * button. For example, the method
- * {@link com.heliumhq.API.RadioButton#isSelected()} can be used to only
- * click a radio button if it isn't already selected:
- *
- * {@code
- * if (! RadioButton("Windows").is_selected())
- * click(RadioButton("Windows"));}
- *
- * When there are multiple occurrences of a radio button on a page, you can
- * disambiguate between them using the functions {@link API#below},
- * {@link API#toRightOf}, {@link API#above} and {@link API#toLeftOf}. For
- * instance:
- *
- * {@code
- * click(RadioButton("I accept", below("License Agreement")));}
- *
- * @param label The label (human-visible name) of the radio button.
- * @param searchRegion The search region to find the radio button in.
- * See the documentation of {@link API#below}.
- */
- public static RadioButton RadioButton(
- String label, SearchRegion... searchRegion
- ) {
- return new RadioButton(
- getAPIImpl().RadioButtonImpl(label, searchRegion)
- );
- }
- public static RadioButton RadioButton(SearchRegion... searchRegion) {
- return new RadioButton(getAPIImpl().RadioButtonImpl(searchRegion));
- }
- public static class RadioButton extends HTMLElement {
- private RadioButton(RadioButtonImpl impl) {
- super(impl);
- }
- /**
- * Returns true if this radio button is selected,
- * false otherwise.
- */
- public boolean isSelected() {
- return getImpl().isSelected();
- }
- /**
- * An {@link org.openqa.selenium.support.ui.ExpectedCondition} that can
- * be used in conjunction with {@link com.heliumhq.API#waitUntil(
- * org.openqa.selenium.support.ui.ExpectedCondition)} to wait for this
- * RadioButton to become checked. For example:
- *
- * {@code
- * waitUntil(RadioButton("Express shipping").isSelected);}
- */
- public final ExpectedCondition isSelected =
- new ExpectedCondition() {
- @Override
- public Boolean apply(WebDriver input) {
- return isSelected();
- }
- };
- RadioButtonImpl getImpl() {
- return (RadioButtonImpl) super.getImpl();
- }
- }
-
- /**
- * Lets you identify individual windows of the currently open browser
- * session.
- *
- * @param title The title of the window you wish to identify.
- */
- public static Window Window(String title) {
- return new Window(getAPIImpl().WindowImpl(title));
- }
- public static Window Window() {
- return new Window(getAPIImpl().WindowImpl());
- }
- public static class Window extends GUIElement {
- private Window(WindowImpl impl) {
- super(impl);
- }
- /**
- * Returns the title of this Window, as a {@link java.lang.String}.
- */
- public String getTitle() {
- return getImpl().getTitle();
- }
- /**
- * Returns the Selenium driver window handle assigned to this window (a
- * {@link java.lang.String}). Note that this window handle is simply an
- * abstract identifier and bears no relationship to the corresponding
- * operating system handle (HWND on Windows).
- */
- public String getHandle() {
- return getImpl().getHandle();
- }
- WindowImpl getImpl() {
- return (WindowImpl) super.getImpl();
- }
- }
-
-
- /**
- * Lets you identify and interact with JavaScript alert boxes.
- *
- * @param text The text displayed in the alert box you wish to identify.
- */
- public static Alert Alert(String text) {
- return new Alert(getAPIImpl().AlertImpl(text));
- }
- public static Alert Alert() {
- return new Alert(getAPIImpl().AlertImpl());
- }
- public static class Alert extends GUIElement {
- private Alert(AlertImpl impl) {
- super(impl);
- }
- /**
- * Returns the text displayed in this alert box, as a
- * {@link java.lang.String}.
- */
- public String getText() {
- return getImpl().getText();
- }
- /**
- * Accepts this alert. This typically corresponds to clicking the "OK"
- * button inside the alert. The typical way to use this method is:
- *
- * {@code
- * Alert().accept();}
- *
- * This accepts the currently open alert.
- */
- public void accept() {
- getImpl().accept();
- }
- /**
- * Dismisses this alert. This typically corresponds to clicking the
- * "Cancel" or "Close" button of the alert. The typical way to use this
- * method is:
- *
- * {@code
- * Alert().dismiss();}
- *
- * This dismisses the currently open alert.
- */
- public void dismiss() {
- getImpl().dismiss();
- }
- AlertImpl getImpl() {
- return (AlertImpl) super.getImpl();
- }
- }
-
- /**
- * A clickable point. To create a Point at on offset of an existing point,
- * use {@link com.heliumhq.API.Point#withOffset(int, int)}:
- *
- * {@code
- * Point point = Point(10, 25);
- * point.withOffset(15, 5); // Point(25, 30);}
- *
- * @param x The x coordinate of the point.
- * @param y The y coordinate of the point.
- */
- public static Point Point(int x, int y) {
- return new Point(x, y);
- }
- public static class Point {
- private int x, y;
- private Point(int x, int y) {
- this.x = x;
- this.y = y;
- }
- /**
- * Returns the x-coordinate of this point.
- */
- public int getX() {
- return x;
- }
- /**
- * Returns the y-coordinate of this point.
- */
- public int getY() {
- return y;
- }
- /**
- * Returns a new Point with coordinates relative to this Point's
- * coordinates.
- *
- * @param dx The distance of the new Point to this Point on the
- * horizontal axis.
- * @param dy The distance of the new Point to this Point on the
- * vertical axis.
- * @return a new Point with coordinates (x + dx, y + dy) if this Point
- * has coordinates (x, y).
- */
- public Point withOffset(int dx, int dy) {
- return new Point(x + dx, y + dy);
- }
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- Point point = (Point) o;
-
- if (x != point.x) return false;
- if (y != point.y) return false;
-
- return true;
- }
- @Override
- public int hashCode() {
- int result = x;
- result = 31 * result + y;
- return result;
- }
- }
-
- /**
- * This function is one of the four functions that can be used to perform
- * relative HTML element searches. For a description of this feature, please
- * consult {@link API#below}.
- *
- * @param text The text to the left of which a search should be
- * performed.
- */
- public static SearchRegion toLeftOf(String text) {
- return toLeftOf(Text(text));
- }
-
- /**
- * @param element The element to the left of which a search should be
- * performed.
- */
- public static SearchRegion toLeftOf(HTMLElement element) {
- return getAPIImpl().toLeftOf(element.getImpl());
- }
-
- /**
- * This function is one of the four functions that can be used to perform
- * relative HTML element searches. For a description of this feature, please
- * consult {@link API#below}.
- *
- * @param text The text to the right of which a search should be
- * performed.
- */
- public static SearchRegion toRightOf(String text) {
- return toRightOf(Text(text));
- }
-
- /**
- * @param element The element to the left of which a search should be
- * performed.
- */
- public static SearchRegion toRightOf(HTMLElement element) {
- return getAPIImpl().toRightOf(element.getImpl());
- }
-
- /**
- * This function is one of the four functions that can be used to perform
- * relative HTML element searches. For a description of this feature, please
- * consult {@link API#below}.
- *
- * @param text The text above which a search should be performed.
- */
- public static SearchRegion above(String text) {
- return above(Text(text));
- }
-
- /**
- * @param element The element above which a search should be performed.
- */
- public static SearchRegion above(HTMLElement element) {
- return getAPIImpl().above(element.getImpl());
- }
-
- /**
- * The function below and its sister functions
- * {@link API#toRightOf}, {@link API#above} and {@link API#toLeftOf} make it
- * possible to disambiguate multiple occurrences of a HTML element on a
- * page. Most typically, this occurs when working with tables. For example,
- * suppose you have a table of user accounts with buttons for blocking
- * them on a page. Then you can use the following snippet to disable the
- * user account of "John Doe":
- *
- * {@code
- * click(Button("Block account", toRightOf("John Doe"));}
- *
- * Relative GUI element searches like this can be nested and combined
- * arbitrarily with Helium's other functions. For example:
- *
- * {@code
- * click(CheckBox(below("Has read permissions"), toRightOf("Bob")));}
- *
- * This clicks on the check box below text "Has read permissions" and to the
- * right of text "Bob".
- *
- * @param text The text below which a search should be performed.
- */
- public static SearchRegion below(String text) {
- return below(Text(text));
- }
-
- /**
- * @param element The element below which a search should be performed.
- */
- public static SearchRegion below(HTMLElement element) {
- return getAPIImpl().below(element.getImpl());
- }
-
- private static APIImpl getAPIImpl() {
- return getApplicationContext().getAPIImpl();
- }
-
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/$Impl.java b/helium-java/src/main/java/com/heliumhq/api_impl/$Impl.java
deleted file mode 100644
index d962143..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/$Impl.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebElement;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class $Impl extends HTMLElementImpl {
-
- private final String selector;
-
- $Impl(
- WebDriverWrapper driver, String selector, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- this.selector = selector;
- }
-
- @Override
- protected Object[] getConstructorArgsBeforeSearchRegions() {
- return new Object[] {selector};
- }
-
- @Override
- protected List findAllInCurrFrame() {
- if (selector.startsWith("@"))
- return wrap(driver.findElements(By.name(selector.substring(1))));
- if (selector.startsWith("//"))
- return wrap(driver.findElements(By.xpath(selector)));
- return wrap(driver.findElements(By.cssSelector(selector)));
- }
-
- private List wrap(List elements) {
- List result = new ArrayList();
- for (WebElement element : elements)
- result.add(new WebElementWrapper(driver, element));
- return result;
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/APICommandImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/APICommandImpl.java
deleted file mode 100644
index d3245df..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/APICommandImpl.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import org.openqa.selenium.UnhandledAlertException;
-
-import java.util.HashSet;
-import java.util.Set;
-
-abstract class APICommandImpl implements Runnable {
-
- private final WebDriverWrapper driver;
-
- APICommandImpl(WebDriverWrapper driver) {
- this.driver = driver;
- }
-
- APICommandImpl handleUnexpectedAlert() {
- return new APICommandImpl(driver) {
- @Override
- public void run() {
- try {
- APICommandImpl.this.run();
- } catch (UnhandledAlertException e) {
- throwUnhandledAlertExceptionWithNiceMsg();
- }
- }
- private void throwUnhandledAlertExceptionWithNiceMsg() {
- throw new UnhandledAlertException(
- "This command is not supported when an alert is present. " +
- "To accept the alert (this usually corresponds to " +
- "clicking 'OK') use `Alert().accept()`. To dismiss the " +
- "alert (ie. 'cancel' it), use `Alert().dismiss()`. If " +
- "the alert contains a text field, you can use write(...) " +
- "to set its value. Eg.: `write('hi there!')`."
- );
-
- }
- };
- }
-
- APICommandImpl mightSpawnWindow() {
- return new APICommandImpl(driver) {
- @Override
- public void run() {
- if (driver.isIE() && new AlertImpl(driver).exists()) {
- // Accessing .window_handles in IE when an alert is present
- // raises an UnexpectedAlertPresentException. When
- // DesiredCapability 'unexpectedAlertBehaviour' is not
- // 'ignore' (the default is 'dismiss'), this leads to the
- // alert being closed. Since we don't want to
- // unintentionally close alert dialogs, we therefore do not
- // access .window_handles in IE when an alert is present.
- APICommandImpl.this.run();
- return;
- }
- Set windowHandlesBefore =
- driver.unwrap().getWindowHandles();
- APICommandImpl.this.run();
- // As above, don't access .window_handles in IE if an alert is
- // present:
- if (!(driver.isIE() && new AlertImpl(driver).exists())) {
- if (driver.isFirefox())
- // Unlike Chrome, Firefox does not wait for new windows
- // to open. Give it a little time to do so:
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {}
- Set newWindowHandles = new HashSet(
- driver.unwrap().getWindowHandles()
- );
- newWindowHandles.removeAll(windowHandlesBefore);
- if (!newWindowHandles.isEmpty())
- driver.switchTo().window(
- newWindowHandles.iterator().next()
- );
- }
- }
- };
- }
-
- void execute() {
- run();
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/APIImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/APIImpl.java
deleted file mode 100644
index 5fe239b..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/APIImpl.java
+++ /dev/null
@@ -1,1107 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.google.common.collect.ImmutableList;
-import com.heliumhq.environment.ResourceLocator;
-import com.heliumhq.errors.HeliumError;
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-import com.heliumhq.util.Tuple;
-import org.openqa.selenium.*;
-import org.openqa.selenium.chrome.ChromeDriver;
-import org.openqa.selenium.chrome.ChromeDriverService;
-import org.openqa.selenium.chrome.ChromeOptions;
-import org.openqa.selenium.firefox.FirefoxBinary;
-import org.openqa.selenium.firefox.FirefoxDriver;
-import org.openqa.selenium.firefox.FirefoxOptions;
-import org.openqa.selenium.firefox.GeckoDriverService;
-import org.openqa.selenium.ie.InternetExplorerDriver;
-import org.openqa.selenium.ie.InternetExplorerDriverService;
-import org.openqa.selenium.interactions.Actions;
-import org.openqa.selenium.remote.CapabilityType;
-import org.openqa.selenium.remote.DesiredCapabilities;
-import org.openqa.selenium.support.ui.ExpectedCondition;
-import org.openqa.selenium.support.ui.Select;
-import org.openqa.selenium.support.ui.WebDriverWait;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.heliumhq.API.Point;
-import static com.heliumhq.util.System.*;
-
-public class APIImpl {
-
- public static final String DRIVER_REQUIRED_MESSAGE =
- "This operation requires a browser window. Please call one of " +
- "the following functions first:\n" +
- " * startChrome()\n" +
- " * startFirefox()\n" +
- " * startIE()\n" +
- " * setDriver(...)";
-
- private final ResourceLocator resourceLocator;
- private WebDriverWrapper driver;
-
- public APIImpl(ResourceLocator resourceLocator) {
- this.resourceLocator = resourceLocator;
- }
-
- public WebDriver startFirefoxImpl() {
- return startFirefoxImpl(null);
- }
- public WebDriver startFirefoxImpl(String url) {
- return startFirefoxImpl(url, false);
- }
- public WebDriver startFirefoxImpl(boolean headless) {
- return startFirefoxImpl(null, headless);
- }
- public WebDriver startFirefoxImpl (String url, boolean headless) {
- FirefoxDriver firefox = startFirefoxDriver(headless);
- return start(firefox, url);
- }
- private FirefoxDriver startFirefoxDriver(boolean headless) {
- GeckoDriverService service = getGeckoDriverService();
- Runtime.getRuntime().addShutdownHook(
- new DriverServiceDestroyer(service)
- );
- FirefoxOptions options = new FirefoxOptions();
- if (headless) {
- FirefoxBinary binary = new FirefoxBinary();
- binary.addCommandLineOptions("--headless");
- options.setBinary(binary);
- }
- return new FirefoxDriver(service, options);
- }
- private GeckoDriverService getGeckoDriverService() {
- File driver = locateWebDriver("geckodriver");
- if (driver.exists()) {
- ensureDriverIsExecutable(driver);
- return new GeckoDriverService.Builder()
- .usingDriverExecutable(driver)
- .withLogFile(new File(isWindows() ? "nul" : "/dev/null"))
- .build();
- } else
- return GeckoDriverService.createDefaultService();
- }
-
- private void ensureDriverIsExecutable(File driver) {
- if (! driver.canExecute())
- if (! driver.setExecutable(true))
- throw new HeliumError(String.format(
- "The driver located at %s is not executable.",
- driver.getAbsolutePath()
- ));
- }
-
- public WebDriver startChromeImpl() {
- return startChromeImpl(null);
- }
- public WebDriver startChromeImpl(String url) {
- return startChromeImpl(url, false);
- }
- public WebDriver startChromeImpl(boolean headless) {
- return startChromeImpl(null, headless);
- }
- public WebDriver startChromeImpl(String url, boolean headless) {
- ChromeDriver chromeDriver = startChromeDriver(headless);
- return start(chromeDriver, url);
- }
-
- private ChromeDriver startChromeDriver(boolean headless) {
- ChromeOptions chromeOptions = getChromeOptions(headless);
- ChromeDriverService service = getChromeDriverService();
- Runtime.getRuntime().addShutdownHook(
- new DriverServiceDestroyer(service)
- );
- return new ChromeDriver(service, chromeOptions);
- }
-
- private ChromeOptions getChromeOptions(boolean headless) {
- ChromeOptions result = new ChromeOptions();
- if (headless)
- result.addArguments("--headless");
- return result;
- }
-
- private ChromeDriverService getChromeDriverService() {
- File driver = locateWebDriver("chromedriver");
- if (driver.exists()) {
- ensureDriverIsExecutable(driver);
- ChromeDriverService.Builder serviceBuilder =
- new ChromeDriverService.Builder();
- return serviceBuilder
- // Prevent verbose messages 'ChromeDriver started' on stderr:
- .withSilent(true)
- .usingAnyFreePort()
- .usingDriverExecutable(driver)
- .build();
- } else
- return ChromeDriverService.createDefaultService();
- }
-
- private File locateWebDriver(String driverName) {
- if (isWindows())
- driverName += ".exe";
- return new File(resourceLocator.locate("webdrivers", driverName));
- }
-
- public WebDriver startIEImpl() {
- return startIEImpl(null);
- }
- public WebDriver startIEImpl(String url) {
- File driverExe = locateWebDriver("IEDriverServer.exe");
- InternetExplorerDriverService.Builder serviceBuilder =
- new InternetExplorerDriverService.Builder()
- .usingAnyFreePort().
- // Prevent verbose messages 'IEDriver started', 'IEDriver
- // listening', 'IEDriver stopped' on stderr:
- withSilent(true);
- if (driverExe.exists())
- serviceBuilder = serviceBuilder.usingDriverExecutable(driverExe);
- InternetExplorerDriverService service = serviceBuilder.build();
- Runtime.getRuntime().addShutdownHook(
- new DriverServiceDestroyer(service)
- );
- InternetExplorerDriver ieBrowser;
- try {
- ieBrowser = new InternetExplorerDriver(service);
- } catch (WebDriverException e) {
- WebDriverException excToRaise = e;
- if (e.getMessage().contains(
- "Protected Mode settings are not the same for all zones."
- ))
- excToRaise = new WebDriverException(
- "Error launching IE: Protected Mode settings are not the " +
- "same for all zones. Please follow these steps: " +
- "http://heliumhq.com/docs/internet_explorer#protected_mode"
- );
- throw excToRaise;
- }
- return start(ieBrowser, url);
- }
-
- private WebDriver start(WebDriver browser, String url) {
- setDriverImpl(browser);
- if (url != null)
- goToImpl(url);
- return getDriverImpl();
- }
-
- public void goToImpl(final String url) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- driver.get((!url.contains("://") ? "http://" : "") + url);
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
-
- public void setDriverImpl(WebDriver driver) {
- this.driver = new WebDriverWrapper(driver);
- }
-
- public WebDriver getDriverImpl() {
- return driver == null ? null : driver.unwrap();
- }
-
- public void writeImpl(final String text) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- if (new AlertImpl(driver).exists())
- writeImpl(text, new AlertImpl(driver));
- else
- driver.switchTo().activeElement().sendKeys(text);
- }
- }).mightSpawnWindow().execute();
- }
- public void writeImpl(String text, String into) {
- writeImpl(text, new TextFieldImpl(requireDriver(), into));
- }
- public void writeImpl(String text, WebElement into) {
- writeImpl(text, new WebElementWrapper(driver, into));
- }
- private void writeImpl(final String text, final WebElementWrapper into) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- into.unwrap().clear();
- into.unwrap().sendKeys(text);
- driver.setLastManipulatedElement(into);
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void writeImpl(final String text, final HTMLElementImpl into) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- into.perform(new Action() {
- @Override
- void performOn(WebElementWrapper elementWrapper) {
- writeImpl(text, elementWrapper);
- }
- });
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void writeImpl(String text, AlertImpl into) {
- into.write(text);
- }
-
- public void pressImpl(final CharSequence key) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- driver.switchTo().activeElement().sendKeys(key);
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
-
- public final CharSequence NULL = Keys.NULL;
- public final CharSequence CANCEL = Keys.CANCEL;
- public final CharSequence HELP = Keys.HELP;
- public final CharSequence BACK_SPACE = Keys.BACK_SPACE;
- public final CharSequence TAB = Keys.TAB;
- public final CharSequence CLEAR = Keys.CLEAR;
- public final CharSequence RETURN = Keys.RETURN;
- public final CharSequence ENTER = Keys.ENTER;
- public final CharSequence SHIFT = Keys.SHIFT;
- public final CharSequence LEFT_SHIFT = Keys.LEFT_SHIFT;
- public final CharSequence CONTROL = Keys.CONTROL;
- public final CharSequence LEFT_CONTROL = Keys.LEFT_CONTROL;
- public final CharSequence ALT = Keys.ALT;
- public final CharSequence LEFT_ALT = Keys.LEFT_ALT;
- public final CharSequence PAUSE = Keys.PAUSE;
- public final CharSequence ESCAPE = Keys.ESCAPE;
- public final CharSequence SPACE = Keys.SPACE;
- public final CharSequence PAGE_UP = Keys.PAGE_UP;
- public final CharSequence PAGE_DOWN = Keys.PAGE_DOWN;
- public final CharSequence END = Keys.END;
- public final CharSequence HOME = Keys.HOME;
- public final CharSequence LEFT = Keys.LEFT;
- public final CharSequence ARROW_LEFT = Keys.ARROW_LEFT;
- public final CharSequence UP = Keys.UP;
- public final CharSequence ARROW_UP = Keys.ARROW_UP;
- public final CharSequence RIGHT = Keys.RIGHT;
- public final CharSequence ARROW_RIGHT = Keys.ARROW_RIGHT;
- public final CharSequence DOWN = Keys.DOWN;
- public final CharSequence ARROW_DOWN = Keys.ARROW_DOWN;
- public final CharSequence INSERT = Keys.INSERT;
- public final CharSequence DELETE = Keys.DELETE;
- public final CharSequence SEMICOLON = Keys.SEMICOLON;
- public final CharSequence EQUALS = Keys.EQUALS;
- public final CharSequence NUMPAD0 = Keys.NUMPAD0;
- public final CharSequence NUMPAD1 = Keys.NUMPAD1;
- public final CharSequence NUMPAD2 = Keys.NUMPAD2;
- public final CharSequence NUMPAD3 = Keys.NUMPAD3;
- public final CharSequence NUMPAD4 = Keys.NUMPAD4;
- public final CharSequence NUMPAD5 = Keys.NUMPAD5;
- public final CharSequence NUMPAD6 = Keys.NUMPAD6;
- public final CharSequence NUMPAD7 = Keys.NUMPAD7;
- public final CharSequence NUMPAD8 = Keys.NUMPAD8;
- public final CharSequence NUMPAD9 = Keys.NUMPAD9;
- public final CharSequence MULTIPLY = Keys.MULTIPLY;
- public final CharSequence ADD = Keys.ADD;
- public final CharSequence SEPARATOR = Keys.SEPARATOR;
- public final CharSequence SUBTRACT = Keys.SUBTRACT;
- public final CharSequence DECIMAL = Keys.DECIMAL;
- public final CharSequence DIVIDE = Keys.DIVIDE;
- public final CharSequence F1 = Keys.F1;
- public final CharSequence F2 = Keys.F2;
- public final CharSequence F3 = Keys.F3;
- public final CharSequence F4 = Keys.F4;
- public final CharSequence F5 = Keys.F5;
- public final CharSequence F6 = Keys.F6;
- public final CharSequence F7 = Keys.F7;
- public final CharSequence F8 = Keys.F8;
- public final CharSequence F9 = Keys.F9;
- public final CharSequence F10 = Keys.F10;
- public final CharSequence F11 = Keys.F11;
- public final CharSequence F12 = Keys.F12;
- public final CharSequence META = Keys.META;
- public final CharSequence COMMAND = Keys.COMMAND;
-
- public void clickImpl(String element) {
- clickImpl(toClickableText(element));
- }
- private ClickableText toClickableText(String element) {
- return new ClickableText(requireDriver(), element);
- }
- public void clickImpl(WebElement element) {
- clickImpl(new WebElementWrapper(driver, element));
- }
- private void clickImpl(final WebElementWrapper elementWrapper) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- elementWrapper.unwrap().click();
- driver.setLastManipulatedElement(elementWrapper);
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void clickImpl(final HTMLElementImpl element) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- element.perform(new Action() {
- @Override
- void performOn(WebElementWrapper element) {
- clickImpl(element);
- }
- });
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void clickImpl(final Point point) {
- handleOffset(point, new Action() {
- @Override
- void performOn(Actions actions) {
- actions.click();
- }
- });
- }
- private void handleOffset(final Point point, final Action action) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- Tuple eltAndOffset =
- pointToElementAndOffset(point);
- WebElementWrapper element = eltAndOffset.getFirst();
- Point offset = eltAndOffset.getSecond();
- Actions actions = driver.action().moveToElement(
- element.unwrap(), offset.getX(), offset.getY()
- );
- action.performOn(actions);
- actions.perform();
- driver.setLastManipulatedElement(element);
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- private Tuple pointToElementAndOffset(
- Point point
- ) {
- final WebDriverWrapper driver = requireDriver();
- WebElementWrapper element = new WebElementWrapper(
- driver,
- (WebElement) driver.executeScript(String.format(
- "return document.elementFromPoint(%s, %s);",
- point.getX(), point.getY()
- ))
- );
- Point offset = point.withOffset(
- -element.getLocation().getLeft(),
- -element.getLocation().getTop()
- );
- if (offset.equals(Point(0, 0)) && driver.isFirefox())
- // In some CSS settings (eg. inttest_point.html), the (0, 0) point
- // of buttons in Firefox is not clickable! The reason for this is
- // that Firefox styles buttons to not be perfect squares, but have
- // an indent in the corners. This workaround makes
- // click(btn.getTopLeft()) work even when this happens:
- offset = Point(1, 1);
- return new Tuple(element, offset);
- }
- private WebElementWrapper pointToElement(Point to) {
- return pointToElementAndOffset(to).getFirst();
- }
-
- public void doubleclickImpl(String element) {
- doubleclickImpl(toClickableText(element));
- }
- public void doubleclickImpl(WebElement element) {
- doubleclickImpl(new WebElementWrapper(driver, element));
- }
- private void doubleclickImpl(final WebElementWrapper elementWrapper) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- driver.action().doubleClick(elementWrapper.unwrap()).perform();
- driver.setLastManipulatedElement(elementWrapper);
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void doubleclickImpl(final HTMLElementImpl element) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- element.perform(new Action() {
- @Override
- void performOn(WebElementWrapper element) {
- doubleclickImpl(element);
- }
- });
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void doubleclickImpl(final Point point) {
- handleOffset(point, new Action() {
- @Override
- void performOn(Actions actions) {
- actions.doubleClick();
- }
- });
- }
-
- public void dragImpl(String element, String to) {
- dragImpl(toClickableText(element), toClickableText(to));
- }
- public void dragImpl(String element, WebElement to) {
- dragImpl(toClickableText(element), new WebElementWrapper(driver, to));
- }
- public void dragImpl(String element, HTMLElementImpl to) {
- dragImpl(toClickableText(element), to);
- }
- public void dragImpl(String element, Point to) {
- dragImpl(toClickableText(element), pointToElement(to));
- }
- public void dragImpl(WebElement element, String to) {
- dragImpl(new WebElementWrapper(driver, element), toClickableText(to));
- }
- public void dragImpl(WebElement element, WebElement to) {
- dragImpl(
- new WebElementWrapper(driver, element),
- new WebElementWrapper(driver, to)
- );
- }
- private void dragImpl(WebElementWrapper element, WebElementWrapper to) {
- DragHelper dragHelper = new DragHelper(this);
- dragHelper.begin();
- try {
- dragHelper.startDragging(element);
- driver.setLastManipulatedElement(element);
- dragHelper.dropOnTarget(to);
- driver.setLastManipulatedElement(to);
- } finally {
- dragHelper.end();
- }
- }
- private void dragImpl(WebElementWrapper element, HTMLElementImpl to) {
- final DragHelper dragHelper = new DragHelper(this);
- dragHelper.begin();
- try {
- dragHelper.startDragging(element);
- driver.setLastManipulatedElement(element);
- to.perform(
- new Action() {
- @Override
- void performOn(WebElementWrapper target) {
- dragHelper.dropOnTarget(target);
- driver.setLastManipulatedElement(target);
- }
- }
- );
- } finally {
- dragHelper.end();
- }
- }
- private void dragImpl(HTMLElementImpl element, WebElementWrapper to) {
- final DragHelper dragHelper = new DragHelper(this);
- dragHelper.begin();
- try {
- element.perform(
- new Action() {
- @Override
- void performOn(WebElementWrapper elementToDrag) {
- dragHelper.startDragging(elementToDrag);
- driver.setLastManipulatedElement(elementToDrag);
- }
- }
- );
- dragHelper.dropOnTarget(to);
- driver.setLastManipulatedElement(to);
- } finally {
- dragHelper.end();
- }
- }
- public void dragImpl(HTMLElementImpl element, HTMLElementImpl to) {
- final DragHelper dragHelper = new DragHelper(this);
- dragHelper.begin();
- try {
- element.perform(
- new Action() {
- @Override
- void performOn(WebElementWrapper elementToDrag) {
- dragHelper.startDragging(elementToDrag);
- driver.setLastManipulatedElement(elementToDrag);
- }
- }
- );
- to.perform(
- new Action() {
- @Override
- void performOn(WebElementWrapper target) {
- dragHelper.dropOnTarget(target);
- driver.setLastManipulatedElement(target);
- }
- }
- );
- } finally {
- dragHelper.end();
- }
- }
- public void dragImpl(WebElement element, HTMLElementImpl to) {
- dragImpl(new WebElementWrapper(driver, element), to);
- }
- public void dragImpl(WebElement element, Point to) {
- dragImpl(new WebElementWrapper(driver, element), pointToElement(to));
- }
- public void dragImpl(HTMLElementImpl element, String to) {
- dragImpl(element, toClickableText(to));
- }
- public void dragImpl(HTMLElementImpl element, WebElement to) {
- dragImpl(element, new WebElementWrapper(driver, to));
- }
- public void dragImpl(HTMLElementImpl element, Point to) {
- dragImpl(element, pointToElement(to));
- }
- public void dragImpl(Point element, String to) {
- dragImpl(pointToElement(element), toClickableText(to));
- }
- public void dragImpl(Point element, WebElement to) {
- dragImpl(pointToElement(element), new WebElementWrapper(driver, to));
- }
- public void dragImpl(Point element, HTMLElementImpl to) {
- dragImpl(pointToElement(element), to);
- }
- public void dragImpl(Point element, Point to) {
- dragImpl(pointToElement(element), pointToElement(to));
- }
- private void pressMouseOn(String element) {
- pressMouseOn(toClickableText(element));
- }
- private void pressMouseOn(WebElement element) {
- pressMouseOn(new WebElementWrapper(driver, element));
- }
- void pressMouseOn(final WebElementWrapper elementWrapper) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- driver.action().clickAndHold(elementWrapper.unwrap()).perform();
- driver.setLastManipulatedElement(elementWrapper);
- }
- }).handleUnexpectedAlert().execute();
- }
- private void pressMouseOn(final HTMLElementImpl element) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- element.perform(new Action() {
- @Override
- void performOn(WebElementWrapper elementWrapper) {
- pressMouseOn(elementWrapper);
- }
- });
- }
- }).handleUnexpectedAlert().execute();
- }
- private void pressMouseOn(Point point) {
- handleOffset(point, new Action() {
- @Override
- void performOn(Actions actions) {
- actions.clickAndHold();
- }
- });
- }
- private void releaseMouseOver(String element) {
- releaseMouseOver(toClickableText(element));
- }
- private void releaseMouseOver(WebElement element) {
- releaseMouseOver(new WebElementWrapper(driver, element));
- }
- void releaseMouseOver(final WebElementWrapper elementWrapper) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- driver.action().moveToElement(elementWrapper.unwrap())
- .release().perform();
- driver.setLastManipulatedElement(elementWrapper);
- }
- }).handleUnexpectedAlert().execute();
- }
- private void releaseMouseOver(final HTMLElementImpl element) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- element.perform(new Action() {
- @Override
- void performOn(WebElementWrapper elementWrapper) {
- releaseMouseOver(elementWrapper);
- }
- });
- }
- }).handleUnexpectedAlert().execute();
- }
- private void releaseMouseOver(Point point) {
- handleOffset(point, new Action() {
- @Override
- void performOn(Actions actions) {
- actions.release();
- }
- });
- }
-
- public > List> findAllImpl(
- final G predicateImpl
- ) {
- final WebDriverWrapper driver = requireDriver();
- final List> result =
- new ArrayList>();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- for (GUIElementImpl boundGuiElementImpl :
- predicateImpl.findAll())
- result.add(boundGuiElementImpl);
- }
- }).handleUnexpectedAlert().execute();
- return result;
- }
-
- public void scrollDownImpl() {
- scrollDownImpl(100);
- }
- public void scrollDownImpl(int numPixels) {
- scrollBy(0, numPixels);
- }
-
- public void scrollUpImpl() {
- scrollUpImpl(100);
- }
- public void scrollUpImpl(int numPixels) {
- scrollBy(0, -numPixels);
- }
-
- public void scrollRightImpl() {
- scrollRightImpl(100);
- }
- public void scrollRightImpl(int numPixels) {
- scrollBy(numPixels, 0);
- }
-
- public void scrollLeftImpl() {
- scrollLeftImpl(100);
- }
- public void scrollLeftImpl(int numPixels) {
- scrollBy(-numPixels, 0);
- }
-
- private void scrollBy(final int dxPixels, final int dyPixels) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- driver.executeScript(
- "window.scrollBy(arguments[0], arguments[1]);",
- dxPixels, dyPixels
- );
- }
- }).handleUnexpectedAlert().execute();
- }
-
- public void hoverImpl(String element) {
- hoverImpl(toClickableText(element));
- }
- public void hoverImpl(WebElement element) {
- hoverImpl(new WebElementWrapper(driver, element));
- }
- private void hoverImpl(final WebElementWrapper element) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- driver.action().moveToElement(element.unwrap()).perform();
- driver.setLastManipulatedElement(element);
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void hoverImpl(final HTMLElementImpl element) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- element.perform(new Action() {
- @Override
- void performOn(WebElementWrapper elementWrapper) {
- hoverImpl(elementWrapper);
- }
- });
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void hoverImpl(Point point) {
- handleOffset(point, new Action() {
- @Override
- void performOn(Actions actions) {
- // Nothing to do here. At this point, the mouse will have
- // already been hovered over the correct position.
- }
- });
- }
-
- public void rightclickImpl(String element) {
- rightclickImpl(toClickableText(element));
- }
- public void rightclickImpl(WebElement element) {
- rightclickImpl(new WebElementWrapper(driver, element));
- }
- private void rightclickImpl(final WebElementWrapper wrapper) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- driver.action().contextClick(wrapper.unwrap()).perform();
- driver.setLastManipulatedElement(wrapper);
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void rightclickImpl(final HTMLElementImpl element) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- element.perform(new Action() {
- @Override
- void performOn(WebElementWrapper elementWrapper) {
- rightclickImpl(elementWrapper);
- }
- });
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void rightclickImpl(Point point) {
- handleOffset(point, new Action() {
- @Override
- void performOn(Actions actions) {
- actions.contextClick();
- }
- });
- }
-
- public void selectImpl(String comboBox, String value) {
- this.selectImpl(ComboBoxImpl(comboBox), value);
- }
- public void selectImpl(ComboBoxImpl comboBox, String value) {
- new Select(comboBox.getWebElement()).selectByVisibleText(value);
- }
-
- public void dragFileImpl(String filePath, String to) {
- dragFileImpl(filePath, toClickableText(to));
- }
- public void dragFileImpl(String filePath, WebElement to) {
- dragFileImpl(filePath, new WebElementWrapper(driver, to));
- }
- private void dragFileImpl(
- final String filePath, final WebElementWrapper to
- ) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- DragAndDropFile dragAndDrop =
- new DragAndDropFile(driver, filePath);
- dragAndDrop.begin();
- try {
- // Some web apps (Gmail in particular) only register for the
- // 'drop' event when user has dragged the file over the
- // document. We therefore simulate this dragging over the
- // document first:
- dragAndDrop.dragOverDocument();
- dragAndDrop.dropOn(to);
- driver.setLastManipulatedElement(to);
- } finally {
- dragAndDrop.end();
- }
- }
- }).handleUnexpectedAlert().execute();
- }
- public void dragFileImpl(final String filePath, final HTMLElementImpl to) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- final DragAndDropFile dragAndDrop =
- new DragAndDropFile(driver, filePath);
- dragAndDrop.begin();
- try {
- // Some web apps (Gmail in particular) only register for the
- // 'drop' event when user has dragged the file over the
- // document. We therefore simulate this dragging over the
- // document first:
- dragAndDrop.dragOverDocument();
- to.perform(new Action() {
- @Override
- void performOn(WebElementWrapper element) {
- dragAndDrop.dropOn(element);
- driver.setLastManipulatedElement(element);
- }
- });
- } finally {
- dragAndDrop.end();
- }
- }
- }).handleUnexpectedAlert().execute();
- }
-
- public void attachFileImpl(String filePath) {
- attachFileImpl(filePath, new FileInput(requireDriver()));
- }
- public void attachFileImpl(String filePath, String to) {
- attachFileImpl(filePath, new FileInput(requireDriver(), to));
- }
- public void attachFileImpl(String filePath, WebElement to) {
- attachFileImpl(filePath, new WebElementWrapper(driver, to));
- }
- private void attachFileImpl(
- final String filePath, final WebElementWrapper to
- ) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- to.unwrap().sendKeys(filePath);
- driver.setLastManipulatedElement(to);
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void attachFileImpl(
- final String filePath, final HTMLElementImpl to
- ) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- to.perform(new Action() {
- @Override
- void performOn(WebElementWrapper element) {
- attachFileImpl(filePath, element);
- }
- });
- }
- }).handleUnexpectedAlert().mightSpawnWindow().execute();
- }
- public void attachFileImpl(final String filePath, Point to) {
- attachFileImpl(filePath, pointToElement(to));
- }
-
- public void refreshImpl() {
- final WebDriverWrapper driver = requireDriver();
- if (new AlertImpl(driver).exists())
- refreshWithAlert();
- else
- refreshNoAlert();
- }
- private void refreshNoAlert() {
- requireDriver().unwrap().navigate().refresh();
- }
- private void refreshWithAlert() {
- new AlertImpl(requireDriver()).accept();
- refreshNoAlert();
- }
-
- public void waitUntilImpl(ExpectedCondition> condition) {
- waitUntilImpl(condition, 10);
- }
- public void waitUntilImpl(
- ExpectedCondition> condition, long timeoutSecs
- ) {
- waitUntilImpl(condition, timeoutSecs, 0.5);
- }
- public void waitUntilImpl(
- ExpectedCondition> condition, long timeoutSecs,
- double intervalSecs
- ) {
- final WebDriverWrapper driver = requireDriver();
- long intervalMillis = (long) Math.ceil(intervalSecs / 1000);
- WebDriverWait wait =
- new WebDriverWait(driver.unwrap(), timeoutSecs, intervalMillis);
- wait.until(condition);
- }
-
- public void switchToImpl(String windowTitle) {
- switchToImpl(new WindowImpl(requireDriver(), windowTitle));
- }
- public void switchToImpl(final WindowImpl window) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- driver.switchTo().window(window.getHandle());
- }
- }).handleUnexpectedAlert().execute();
- }
-
- public void killBrowserImpl() {
- requireDriver().unwrap().quit();
- driver = null;
- }
-
- public void highlightImpl(String element) {
- highlightImpl(new TextImpl(requireDriver(), element));
- }
- public void highlightImpl(HTMLElementImpl element) {
- highlightImpl(element.getFirstOccurrence());
- }
- private void highlightImpl(WebElementWrapper elementWrapper) {
- highlightImpl(elementWrapper.unwrap());
- }
- public void highlightImpl(final WebElement element) {
- final WebDriverWrapper driver = requireDriver();
- (new APICommandImpl(driver) {
- @Override
- public void run() {
- String previousStyle = element.getAttribute("style");
- driver.executeScript(
- "arguments[0].setAttribute(" +
- "'style', 'border: 2px solid red; font-weight: bold;'" +
- ");", element
- );
- driver.executeScript(
- "var target = arguments[0];" +
- "var previousStyle = arguments[1];" +
- "setTimeout(" +
- "function() {" +
- "target.setAttribute('style', previousStyle);" +
- "}, 2000" +
- ");", element, previousStyle
- );
- }
- }).handleUnexpectedAlert().execute();
- }
-
- public $Impl $Impl(String selector, SearchRegion... searchRegions) {
- return new $Impl(requireDriver(), selector, searchRegions);
- }
-
- public TextImpl TextImpl(SearchRegion... searchRegions) {
- return new TextImpl(requireDriver(), searchRegions);
- }
- public TextImpl TextImpl(
- String text, SearchRegion... searchRegions
- ) {
- return new TextImpl(requireDriver(), text, searchRegions);
- }
-
- public LinkImpl LinkImpl(SearchRegion... searchRegions) {
- return new LinkImpl(requireDriver(), searchRegions);
- }
- public LinkImpl LinkImpl(
- String text, SearchRegion... searchRegions
- ) {
- return new LinkImpl(requireDriver(), text, searchRegions);
- }
-
- public ListItemImpl ListItemImpl(SearchRegion... searchRegions) {
- return new ListItemImpl(requireDriver(), searchRegions);
- }
- public ListItemImpl ListItemImpl(
- String text, SearchRegion... searchRegions
- ) {
- return new ListItemImpl(requireDriver(), text, searchRegions);
- }
-
- public ButtonImpl ButtonImpl(SearchRegion... searchRegions) {
- return new ButtonImpl(requireDriver(), searchRegions);
- }
- public ButtonImpl ButtonImpl(
- String text, SearchRegion... searchRegions
- ) {
- return new ButtonImpl(requireDriver(), text, searchRegions);
- }
-
- public ImageImpl ImageImpl(SearchRegion... searchRegions) {
- return new ImageImpl(requireDriver(), searchRegions);
- }
- public ImageImpl ImageImpl(
- String alt, SearchRegion... searchRegions
- ) {
- return new ImageImpl(requireDriver(), alt, searchRegions);
- }
-
- public TextFieldImpl TextFieldImpl(SearchRegion... searchRegions) {
- return new TextFieldImpl(requireDriver(), searchRegions);
- }
- public TextFieldImpl TextFieldImpl(
- String label, SearchRegion... searchRegions
- ) {
- return new TextFieldImpl(requireDriver(), label, searchRegions);
- }
-
- public ComboBoxImpl ComboBoxImpl(SearchRegion... searchRegions) {
- return new ComboBoxImpl(requireDriver(), searchRegions);
- }
- public ComboBoxImpl ComboBoxImpl(
- String label, SearchRegion... searchRegions
- ) {
- return new ComboBoxImpl(requireDriver(), label, searchRegions);
- }
-
- public CheckBoxImpl CheckBoxImpl(SearchRegion... searchRegions) {
- return new CheckBoxImpl(requireDriver(), searchRegions);
- }
- public CheckBoxImpl CheckBoxImpl(
- String label, SearchRegion... searchRegions
- ) {
- return new CheckBoxImpl(requireDriver(), label, searchRegions);
- }
-
- public RadioButtonImpl RadioButtonImpl(
- SearchRegion... searchRegions
- ) {
- return new RadioButtonImpl(requireDriver(), searchRegions);
- }
- public RadioButtonImpl RadioButtonImpl(
- String label, SearchRegion... searchRegions
- ) {
- return new RadioButtonImpl(requireDriver(), label, searchRegions);
- }
-
- public WindowImpl WindowImpl() {
- return new WindowImpl(requireDriver());
- }
- public WindowImpl WindowImpl(String title) {
- return new WindowImpl(requireDriver(), title);
- }
-
- public AlertImpl AlertImpl() {
- return new AlertImpl(requireDriver());
- }
-
- public AlertImpl AlertImpl(String text) {
- return new AlertImpl(requireDriver(), text);
- }
-
- public SearchRegion toLeftOf(HTMLElementImpl element) {
- return new SearchRegion(SearchDirection.TO_LEFT_OF, element);
- }
- public SearchRegion toRightOf(HTMLElementImpl element) {
- return new SearchRegion(SearchDirection.TO_RIGHT_OF, element);
- }
- public SearchRegion above(HTMLElementImpl element) {
- return new SearchRegion(SearchDirection.ABOVE, element);
- }
- public SearchRegion below(HTMLElementImpl element) {
- return new SearchRegion(SearchDirection.BELOW, element);
- }
-
- WebDriverWrapper requireDriver() {
- if (driver == null)
- throw new RuntimeException(DRIVER_REQUIRED_MESSAGE);
- return driver;
- }
-
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/Action.java b/helium-java/src/main/java/com/heliumhq/api_impl/Action.java
deleted file mode 100644
index 7ab3fc8..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/Action.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.heliumhq.api_impl;
-
-abstract class Action {
- abstract void performOn(T element);
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/AlertImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/AlertImpl.java
deleted file mode 100644
index 7ef85f9..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/AlertImpl.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import org.openqa.selenium.NoAlertPresentException;
-import org.openqa.selenium.WebDriverException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class AlertImpl extends GUIElementImpl {
-
- private final String searchText;
-
- public AlertImpl(WebDriverWrapper driver) {
- this(driver, null);
- }
-
- public AlertImpl(WebDriverWrapper driver, String searchText) {
- super(driver);
- this.searchText = searchText;
- }
-
- @Override
- protected Iterable findAllOccurrences() {
- List result =
- new ArrayList();
- try {
- org.openqa.selenium.Alert alert = driver.switchTo().alert();
- String text = alert.getText();
- if (searchText == null ||
- (text != null && text.startsWith(searchText)))
- result.add(alert);
- } catch (NoAlertPresentException e) {
- // alert hasn't been added to result so no need to do anything here.
- }
- return result;
- }
-
- public String getText() {
- return getFirstOccurrence().getText();
- }
-
- public void accept() {
- org.openqa.selenium.Alert firstOccurrence = getFirstOccurrence();
- try {
- firstOccurrence.accept();
- } catch (WebDriverException e) {
- // Attempt to work around Selenium issue 3544:
- // https://code.google.com/p/selenium/issues/detail?id=3544
- String msg = e.getMessage();
- if (msg != null && msg.matches(
- "a\\.document\\.getElementsByTagName\\([^\\)]*\\)\\[0\\] " +
- "is undefined")) {
- try {
- Thread.sleep(250);
- } catch (InterruptedException e2) {}
- firstOccurrence.accept();
- } else {
- throw e;
- }
- }
- }
-
- public void dismiss() {
- getFirstOccurrence().dismiss();
- }
-
- @Override
- protected Object[] getConstructorArgs() {
- String text = isBound() ? getText() : searchText;
- return new Object[] {text};
- }
-
- void write(String text) {
- getFirstOccurrence().sendKeys(text);
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/ButtonImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/ButtonImpl.java
deleted file mode 100644
index 0f3b77e..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/ButtonImpl.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-import static com.heliumhq.util.XPath.predicate;
-import static com.heliumhq.util.XPath.predicateOr;
-import static com.heliumhq.util.StringUtils.isEmpty;
-
-public class ButtonImpl extends HTMLElementContainingText {
-
- public ButtonImpl(WebDriverWrapper driver, SearchRegion... searchRegions) {
- super(driver, searchRegions);
- }
-
- public ButtonImpl(
- WebDriverWrapper driver, String text, SearchRegion... searchRegions
- ) {
- super(driver, text, searchRegions);
- }
-
- protected String getXPathNodeSelector() {
- return "button";
- }
-
- public boolean isEnabled() {
- String ariaDisabled =
- getFirstOccurrence().getAttribute("aria-disabled");
- return super.isEnabled() && (
- isEmpty(ariaDisabled) || ariaDisabled.equalsIgnoreCase("false")
- );
- }
-
- @Override
- protected String getXPath() {
- String hasAriaLabel = matches.xpath("@aria-label", searchText);
- String hasText = matches.xpath(".", searchText);
- String hasTextOrAriaLabel = predicateOr(hasAriaLabel, hasText);
- return super.getXPath() + " | " + getInputButtonXPath() + " | " +
- "//*[@role='button']" + hasTextOrAriaLabel + " | " +
- "//button" + predicate(hasAriaLabel);
- }
-
- String getInputButtonXPath() {
- String hasText;
- if (!isEmpty(searchText)) {
- String hasValue = matches.xpath("@value", searchText);
- String hasLabel = matches.xpath("@label", searchText);
- String hasAriaLabel = matches.xpath("@aria-label", searchText);
- String hasTitle = matches.xpath("@title", searchText);
- hasText = predicateOr(hasValue, hasLabel, hasAriaLabel, hasTitle);
- } else
- hasText = "";
- return "//input[@type='submit' or @type='button']" + hasText;
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/CheckBoxImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/CheckBoxImpl.java
deleted file mode 100644
index 9d166dd..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/CheckBoxImpl.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-public class CheckBoxImpl extends LabelledElement {
-
- public CheckBoxImpl(
- WebDriverWrapper driver, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- }
-
- public CheckBoxImpl(
- WebDriverWrapper driver, String label, SearchRegion... searchRegions
- ) {
- super(driver, label, searchRegions);
- }
-
- public boolean isEnabled() {
- return super.isEnabled();
- }
-
- public boolean isChecked() {
- return getFirstOccurrence().getAttribute("checked") != null;
- }
-
- @Override
- protected String getXPath() {
- return "//input[@type='checkbox']";
- }
-
- @Override
- protected SearchDirection getPrimarySearchDirection() {
- return SearchDirection.TO_LEFT_OF;
- }
-
- @Override
- protected SearchDirection getSecondarySearchDirection() {
- return SearchDirection.TO_RIGHT_OF;
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/ClickableText.java b/helium-java/src/main/java/com/heliumhq/api_impl/ClickableText.java
deleted file mode 100644
index 543c2c9..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/ClickableText.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-class ClickableText extends CompositeElement {
-
- private final String searchText;
-
- ClickableText(WebDriverWrapper driver) {
- this(driver, null);
- }
-
- ClickableText(WebDriverWrapper driver, String searchText) {
- super(driver);
- this.searchText = searchText;
- }
-
- @Override
- protected HTMLElementImpl[] getElements() {
- return new HTMLElementImpl[] {
- new ButtonImpl(driver, searchText),
- new TextImpl(driver, searchText)
- };
- }
-
- @Override
- protected Object[] getConstructorArgsBeforeSearchRegions() {
- return new Object[] {searchText};
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/ComboBoxIdentifiedByDisplayedValue.java b/helium-java/src/main/java/com/heliumhq/api_impl/ComboBoxIdentifiedByDisplayedValue.java
deleted file mode 100644
index 43a36c6..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/ComboBoxIdentifiedByDisplayedValue.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.ui.Select;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ComboBoxIdentifiedByDisplayedValue
- extends HTMLElementContainingText {
-
- public ComboBoxIdentifiedByDisplayedValue(
- WebDriverWrapper driver, String text, SearchRegion... searchRegions
- ) {
- super(driver, text, searchRegions);
- }
-
- @Override
- protected String getXPathNodeSelector() {
- return "option";
- }
-
- @Override
- protected String getXPath() {
- return super.getXPath() + "/ancestor::select[1]";
- }
-
- @Override
- protected List findAllInCurrFrame() {
- List allCbsWithAMatchingValue =
- super.findAllInCurrFrame();
- List result = new ArrayList();
- for (WebElementWrapper cb : allCbsWithAMatchingValue) {
- Select select = new Select(cb.unwrap());
- for (WebElement selectedOption : select.getAllSelectedOptions())
- if (matches.text(selectedOption.getText(), searchText)) {
- result.add(cb);
- break;
- }
- }
- return result;
- }
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/ComboBoxIdentifiedByLabel.java b/helium-java/src/main/java/com/heliumhq/api_impl/ComboBoxIdentifiedByLabel.java
deleted file mode 100644
index 59a26a5..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/ComboBoxIdentifiedByLabel.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-public class ComboBoxIdentifiedByLabel extends LabelledElement {
-
- ComboBoxIdentifiedByLabel(
- WebDriverWrapper driver, String label, SearchRegion... searchRegions
- ) {
- super(driver, label, searchRegions);
- }
-
- @Override
- protected String getXPath() {
- return "//select | //input[@list]";
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/ComboBoxImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/ComboBoxImpl.java
deleted file mode 100644
index 4d23ae0..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/ComboBoxImpl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.ui.Select;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ComboBoxImpl extends CompositeElement {
-
- private final String label;
-
- public ComboBoxImpl(
- WebDriverWrapper driver, SearchRegion... searchRegions
- ) {
- this(driver, null, searchRegions);
- }
-
- public ComboBoxImpl(
- WebDriverWrapper driver, String label, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- this.label = label;
- }
-
- @Override
- protected HTMLElementImpl[] getElements() {
- return new HTMLElementImpl[] {
- new ComboBoxIdentifiedByDisplayedValue(
- driver, label, searchRegions
- ),
- new ComboBoxIdentifiedByLabel(driver, label, searchRegions)
- };
- }
-
- public boolean isEditable() {
- return ! "select".equals(getFirstOccurrence().getTagName());
- }
-
- public String getValue() {
- WebElement selectedOption = getSelectDriver().getFirstSelectedOption();
- if (selectedOption != null) {
- return selectedOption.getText();
- }
- return null;
- }
-
- public List getOptions() {
- List result = new ArrayList();
- for (WebElement option : getSelectDriver().getOptions())
- result.add(option.getText());
- return result;
- }
-
- @Override
- protected Object[] getConstructorArgsBeforeSearchRegions() {
- return new Object[] {label};
- }
-
- private Select getSelectDriver() {
- return new Select(getWebElement());
- }
-
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/CompositeElement.java b/helium-java/src/main/java/com/heliumhq/api_impl/CompositeElement.java
deleted file mode 100644
index edb8aa7..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/CompositeElement.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-import com.heliumhq.util.Generator;
-
-import java.util.*;
-
-import static java.util.Arrays.asList;
-
-abstract class CompositeElement extends HTMLElementImpl {
-
- private GUIElementImpl firstElement;
-
- CompositeElement(WebDriverWrapper driver, SearchRegion... searchRegions) {
- super(driver, searchRegions);
- }
-
- protected GUIElementImpl getFirstElement() {
- if (firstElement == null) {
- bindToFirstOccurrence();
- // findAllInCurrFrame() below now sets firstElement.
- }
- return firstElement;
- }
-
- protected abstract HTMLElementImpl[] getElements();
-
- @Override
- protected Iterable findAllInCurrFrame() {
- return new Generator() {
-
- List alreadyYielded;
- Iterator elements;
- HTMLElementImpl element;
- Iterator boundGuiEltImpls;
-
- @Override
- protected WebElementWrapper generateNext() {
- if (alreadyYielded == null)
- alreadyYielded = new ArrayList();
- if (elements == null)
- elements = asList(getElements()).iterator();
- while (true) {
- if (element == null)
- element = elements.next();
- if (boundGuiEltImpls == null)
- boundGuiEltImpls =
- element.findAllInCurrFrame().iterator();
- while (boundGuiEltImpls.hasNext()) {
- WebElementWrapper boundGuiEltImpl =
- boundGuiEltImpls.next();
- if (firstElement == null)
- firstElement = element;
- if (!alreadyYielded.contains(boundGuiEltImpl)) {
- alreadyYielded.add(boundGuiEltImpl);
- return boundGuiEltImpl;
- }
- }
- element = null;
- boundGuiEltImpls = null;
- }
- }
-
- };
- }
-
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/DragAndDropFile.java b/helium-java/src/main/java/com/heliumhq/api_impl/DragAndDropFile.java
deleted file mode 100644
index 192259c..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/DragAndDropFile.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-import com.heliumhq.util.Tuple;
-import org.openqa.selenium.WebElement;
-
-class DragAndDropFile {
-
- private final WebDriverWrapper driver;
- private final String filePath;
- private WebElement fileInputElement;
- private JavaScriptInterval dragoverEvent;
-
- DragAndDropFile(WebDriverWrapper driver, String filePath) {
- this.driver = driver;
- this.filePath = filePath;
- }
-
- void begin() {
- createFileInputElement();
- try {
- fileInputElement.sendKeys(filePath);
- } catch (RuntimeException e) {
- end();
- throw e;
- }
- }
-
- private void createFileInputElement() {
- // The input needs to be visible to Selenium to allow sending keys to it
- // in Firefox and IE.
- // According to http://stackoverflow.com/questions/6101461/
- // Selenium criteria whether an element is visible or not are the
- // following:
- // - visibility != hidden
- // - display != none (is also checked against every parent element)
- // - opacity != 0
- // - height and width are both > 0
- // - for an input, the attribute type != hidden
- // So let's make sure its all good!
- fileInputElement = (WebElement) driver.executeScript(
- "var input = document.createElement('input');" +
- "input.type = 'file';" +
- "input.style.display = 'block';" +
- "input.style.opacity = '1';" +
- "input.style.visibility = 'visible';" +
- "input.style.height = '1px';" +
- "input.style.width = '1px';" +
- "if (document.body.childElementCount > 0) { " +
- " document.body.insertBefore(input, document.body.childNodes[0]);"+
- "} else { " +
- " document.body.appendChild(input);" +
- "}" +
- "return input;"
- );
- }
-
- void dragOverDocument() {
- // According to the HTML5 spec, we need to dispatch the dragenter event
- // once, and then the dragover event continuously, every 350+-200ms:
- // http://www.w3.org/html/wg/drafts/html/master/editing.html#current-
- // drag-operation
- // Especially IE implements this spec very tightly, and considers the
- // dragging to be over if no dragover event occurs for more than ~1sec.
- // We thus need to ensure that we keep dispatching the dragover event.
-
- // This line used to read `dispatchEvent(..., "document");`. However,
- // this doesn't work when adding a photo to a tweet on Twitter.
- // Dispatching the event to document.body fixes this, and also works for
- // Gmail:
- dispatchEvent("dragenter", "document.body");
- dragoverEvent = prepareContinuousEvent("dragover", "document", 300);
- dragoverEvent.start();
- }
-
- private void dispatchEvent(String eventName, String to) {
- Tuple scriptArgs =
- prepareDispatchEvent(eventName, to);
- driver.executeScript(scriptArgs.getFirst(), scriptArgs.getSecond());
- }
- private void dispatchEvent(String eventName, WebElementWrapper to) {
- Tuple scriptArgs =
- prepareDispatchEvent(eventName, to);
- driver.executeScript(scriptArgs.getFirst(), scriptArgs.getSecond());
- }
-
- private JavaScriptInterval prepareContinuousEvent(
- String eventName, String to, long intervalMsecs
- ) {
- Tuple scriptArgs =
- prepareDispatchEvent(eventName, to);
- return new JavaScriptInterval(
- driver, scriptArgs.getFirst(), scriptArgs.getSecond(),
- intervalMsecs
- );
- }
-
- private Tuple prepareDispatchEvent(
- String eventName, String to
- ) {
- String script = DISPATCH_EVENT_SCRIPT.replace("arguments[2]", to);
- return new Tuple(
- script, new Object[] {fileInputElement, eventName}
- );
- }
-
- private final String DISPATCH_EVENT_SCRIPT =
- "var files = arguments[0].files;" +
- "var items = [];" +
- "var types = [];" +
- "for (var i = 0; i < files.length; i++) {" +
- " items[i] = {kind: 'file', type: files[i].type};" +
- " types[i] = 'Files';" +
- "}" +
- "var event = document.createEvent('CustomEvent');" +
- "event.initCustomEvent(arguments[1], true, true, 0);" +
- "event.dataTransfer = {" +
- " files: files," +
- " items: items," +
- " types: types" +
- "};" +
- "arguments[2].dispatchEvent(event);";
-
- private Tuple prepareDispatchEvent(
- String eventName, WebElementWrapper to
- ) {
- return new Tuple(
- DISPATCH_EVENT_SCRIPT,
- new Object[] {fileInputElement, eventName, to.unwrap()}
- );
- }
-
- void dropOn(WebElementWrapper element) {
- dragoverEvent.stop();
- dispatchEvent("drop", element);
- }
-
- void end() {
- if (fileInputElement != null)
- driver.executeScript(
- "arguments[0].parentNode.removeChild(arguments[0]);",
- fileInputElement
- );
- fileInputElement = null;
- }
-
- private class JavaScriptInterval {
-
- private WebDriverWrapper driver;
- private String script;
- private Object[] args;
- private long intervalMsecs;
- private long intervalId;
-
- private JavaScriptInterval(
- WebDriverWrapper driver, String script, Object[] args,
- long intervalMsecs
- ) {
- this.driver = driver;
- this.script = script;
- this.args = args;
- this.intervalMsecs = intervalMsecs;
- }
-
- private void start() {
- String setintervalScript = String.format(
- "var originalArguments = arguments;" +
- "return setInterval(function() {" +
- " arguments = originalArguments;" +
- " %s" +
- "}, %d);", script, intervalMsecs
- );
- intervalId = (Long) driver.executeScript(setintervalScript, args);
- }
-
- private void stop() {
- driver.executeScript("clearInterval(arguments[0]);", intervalId);
- intervalId = 0L;
- }
-
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/DragHelper.java b/helium-java/src/main/java/com/heliumhq/api_impl/DragHelper.java
deleted file mode 100644
index 69fc488..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/DragHelper.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-
-class DragHelper {
-
- private final APIImpl apiImpl;
- private boolean isHtml5Drag;
-
- DragHelper(APIImpl apiImpl) {
- this.apiImpl = apiImpl;
- this.isHtml5Drag = false;
- }
-
- void begin() {
- executeScript(
- "window.helium = {};" +
- "window.helium.dragHelper = {" +
- " createEvent: function(type) {" +
- " var event = document.createEvent('CustomEvent');" +
- " event.initCustomEvent(type, true, true, null);" +
- " event.dataTransfer = {" +
- " data: {}," +
- " setData: function(type, val) {" +
- " this.data[type] = val;" +
- " }," +
- " getData: function(type) {" +
- " return this.data[type];" +
- " }" +
- " };" +
- " return event;" +
- " }" +
- "};"
- );
- }
-
- void startDragging(WebElementWrapper element) {
- if (attemptHtml5Drag(element))
- isHtml5Drag = true;
- else
- apiImpl.pressMouseOn(element);
- }
-
- void dropOnTarget(WebElementWrapper target) {
- if (isHtml5Drag)
- completeHtml5Drag(target);
- else
- apiImpl.releaseMouseOver(target);
- }
-
- void end() {
- executeScript("delete window.helium;");
- }
-
- private boolean attemptHtml5Drag(WebElementWrapper elementToDrag) {
- return (Boolean) executeScript(
- "var source = arguments[0];" +
- "function getDraggableParent(element) {" +
- " var previousParent = null;" +
- " while (element != null && element != previousParent) {" +
- " previousParent = element;" +
- " if ('draggable' in element) {" +
- " var draggable = element.draggable;" +
- " if (draggable === true)" +
- " return element;" +
- " if (typeof draggable == 'string' " +
- " || draggable instanceof String)" +
- " if (draggable.toLowerCase() == 'true')" +
- " return element;" +
- " }" +
- " element = element.parentNode;" +
- " }" +
- " return null;" +
- "}" +
- "var draggableParent = getDraggableParent(source);" +
- "if (draggableParent == null)" +
- " return false;" +
- "window.helium.dragHelper.draggedElement = draggableParent;" +
- "var dragStart = " +
- "window.helium.dragHelper.createEvent('dragstart');" +
- "source.dispatchEvent(dragStart);" +
- "window.helium.dragHelper.dataTransfer = dragStart.dataTransfer;" +
- "return true;",
- elementToDrag.unwrap()
- );
- }
-
- private void completeHtml5Drag(WebElementWrapper on) {
- executeScript(
- "var target = arguments[0];" +
- "var drop = window.helium.dragHelper.createEvent('drop');" +
- "drop.dataTransfer = window.helium.dragHelper.dataTransfer;" +
- "target.dispatchEvent(drop);" +
- "var dragEnd = window.helium.dragHelper.createEvent('dragend');" +
- "dragEnd.dataTransfer = window.helium.dragHelper.dataTransfer;" +
- "window.helium.dragHelper.draggedElement.dispatchEvent(dragEnd);",
- on.unwrap()
- );
- }
-
- private Object executeScript(String script, Object... args) {
- return apiImpl.requireDriver().executeScript(script, args);
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/DriverServiceDestroyer.java b/helium-java/src/main/java/com/heliumhq/api_impl/DriverServiceDestroyer.java
deleted file mode 100644
index 16e75fa..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/DriverServiceDestroyer.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.heliumhq.api_impl;
-
-import org.openqa.selenium.os.CommandLine;
-import org.openqa.selenium.remote.service.DriverService;
-
-import java.lang.reflect.Field;
-import java.util.concurrent.locks.ReentrantLock;
-
-class DriverServiceDestroyer extends Thread {
-
- private final DriverService driverService;
-
- DriverServiceDestroyer(DriverService driverService) {
- this.driverService = driverService;
- }
-
- public void run() {
- try {
- ReentrantLock lock = (ReentrantLock) getField("lock");
- try {
- lock.lock();
- CommandLine process = (CommandLine) getField("process");
- if (process == null)
- return;
- process.destroy();
- setField("process", null);
- } finally {
- lock.unlock();
- }
- } catch (Exception e) {
- throw new RuntimeException(
- "Unable to shutdown " + driverService + ".", e
- );
- }
- }
-
- private Object getField(String fieldName) throws
- NoSuchFieldException, IllegalAccessException {
- return getFieldDefinition(fieldName).get(driverService);
- }
- private Field getFieldDefinition(String fieldName) throws
- NoSuchFieldException {
- Field field = DriverService.class.getDeclaredField(fieldName);
- field.setAccessible(true);
- return field;
- }
- private void setField(String fieldName, Object value) throws
- IllegalAccessException, NoSuchFieldException {
- getFieldDefinition(fieldName).set(driverService, value);
- }
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/FileInput.java b/helium-java/src/main/java/com/heliumhq/api_impl/FileInput.java
deleted file mode 100644
index ab5dc4e..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/FileInput.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-class FileInput extends LabelledElement {
-
- FileInput(WebDriverWrapper driver, SearchRegion... searchRegions) {
- super(driver, searchRegions);
- }
-
- FileInput(
- WebDriverWrapper driver, String label, SearchRegion... searchRegions
- ) {
- super(driver, label, searchRegions);
- }
-
- @Override
- protected String getXPath() {
- return "//input[@type='file']";
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/FreeText.java b/helium-java/src/main/java/com/heliumhq/api_impl/FreeText.java
deleted file mode 100644
index a17964d..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/FreeText.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-public class FreeText extends HTMLElementContainingText {
- public FreeText(
- WebDriverWrapper driver, String text, SearchRegion... searchRegions
- ) {
- super(driver, text, searchRegions);
- }
-
- @Override
- protected String getXPathNodeSelector() {
- return "text()";
- }
-
- @Override
- protected String getXPath() {
- return super.getXPath() + "/..";
- }
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/GUIElementImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/GUIElementImpl.java
deleted file mode 100644
index e68f926..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/GUIElementImpl.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import com.heliumhq.util.Generator;
-import org.openqa.selenium.ElementNotVisibleException;
-import org.openqa.selenium.NoSuchElementException;
-import org.openqa.selenium.WebDriverException;
-import org.openqa.selenium.interactions.MoveTargetOutOfBoundsException;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import static com.heliumhq.API.Config;
-import static com.heliumhq.util.StringUtils.escape;
-import static com.heliumhq.util.StringUtils.join;
-import static java.lang.System.currentTimeMillis;
-import static java.util.Arrays.asList;
-
-public abstract class GUIElementImpl implements Cloneable {
-
- protected final WebDriverWrapper driver;
- private T boundOccurrence;
-
- protected GUIElementImpl(WebDriverWrapper driver) {
- this.driver = driver;
- }
-
- public boolean exists() {
- return findAll().iterator().hasNext();
- }
-
- public Iterable> findAll() {
- if (isBound())
- return asList(this);
- final Iterator allOccurrences = findAllOccurrences().iterator();
- return new Generator>() {
- @Override
- protected GUIElementImpl generateNext() {
- return boundToOccurrence(allOccurrences.next());
- }
- };
- }
-
- @Override
- public String toString() {
- return toString(getClass().getSimpleName());
- }
-
- public String toString(String className) {
- return String.format(
- "%s(%s)", className, reprConstuctorArgs()
- );
- }
-
- protected String reprConstuctorArgs() {
- Object[] constructorArgs = getConstructorArgs();
- List constructorArgsReprs = new ArrayList();
- for (Object arg : constructorArgs) {
- if (arg instanceof String)
- constructorArgsReprs.add(escape((String) arg));
- else if (arg != null)
- constructorArgsReprs.add(arg.toString());
- }
- return join(", ", constructorArgsReprs);
- }
-
- protected abstract Object[] getConstructorArgs();
-
- protected boolean isBound() {
- return boundOccurrence != null;
- }
-
- protected abstract Iterable findAllOccurrences();
-
- GUIElementImpl boundToOccurrence(T occurrence) {
- GUIElementImpl result;
- try {
- result = (GUIElementImpl) clone();
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException(e);
- }
- result.boundOccurrence = occurrence;
- return result;
- }
-
- protected T getFirstOccurrence() {
- if (! isBound())
- bindToFirstOccurrence();
- return boundOccurrence;
- }
-
- protected void bindToFirstOccurrence() {
- perform(new NoOpAction());
- // performNoWait(...) below now sets boundOccurrence.
- }
-
- T perform(Action action) {
- long endTime = currentTimeMillis() +
- (long) (Config.getImplicitWaitSecs() * 1000);
- // Try to perform `action` at least once:
- T result = performNoWait(action);
- while (result == null && currentTimeMillis() < endTime)
- result = performNoWait(action);
- if (result != null)
- return result;
- throw new NoSuchElementException("Cannot find element " + this + ".");
- }
-
- private T performNoWait(Action action) {
- for (GUIElementImpl boundGUIElementImpl : findAll()) {
- T occurrence = boundGUIElementImpl.getFirstOccurrence();
- try {
- action.performOn(occurrence);
- } catch (RuntimeException e) {
- if (shouldIgnoreException(e))
- continue;
- else
- throw e;
- }
- boundOccurrence = occurrence;
- return occurrence;
- }
- return null;
- }
-
- private boolean shouldIgnoreException(RuntimeException e) {
- if (e instanceof ElementNotVisibleException)
- return true;
- if (e instanceof MoveTargetOutOfBoundsException)
- return true;
- if (e instanceof WebDriverException) {
- String msg = e.getMessage();
- if (msg != null && msg.contains("Element is not clickable at point")
- && msg.contains("Other element would receive the click")
- )
- return true;
- }
- return false;
- }
-
- private class NoOpAction extends Action {
- @Override
- public void performOn(T element) {}
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/HTMLElementContainingText.java b/helium-java/src/main/java/com/heliumhq/api_impl/HTMLElementContainingText.java
deleted file mode 100644
index 62516b3..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/HTMLElementContainingText.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-import static com.heliumhq.util.XPath.predicate;
-
-abstract class HTMLElementContainingText extends HTMLElementIdentifiedByXPath {
-
- protected final String searchText;
-
- public HTMLElementContainingText(
- WebDriverWrapper driver, SearchRegion... searchRegions
- ) {
- this(driver, null, searchRegions);
- }
-
- public HTMLElementContainingText(
- WebDriverWrapper driver, String text, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- this.searchText = text;
- }
-
- @Override
- protected String getXPath() {
- String xpathBase = "//" + getXPathNodeSelector() +
- predicate(matches.xpath(".", searchText));
- return String.format(
- "%s[not(self::script)][not(.%s)]", xpathBase, xpathBase
- );
- }
-
- protected String getXPathNodeSelector() {
- return "*";
- }
-
- @Override
- protected Object[] getConstructorArgsBeforeSearchRegions() {
- return new Object[] {searchText};
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/HTMLElementIdentifiedByXPath.java b/helium-java/src/main/java/com/heliumhq/api_impl/HTMLElementIdentifiedByXPath.java
deleted file mode 100644
index 5b185d8..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/HTMLElementIdentifiedByXPath.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-import org.openqa.selenium.By;
-import org.openqa.selenium.StaleElementReferenceException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-abstract class HTMLElementIdentifiedByXPath extends HTMLElementImpl {
-
- HTMLElementIdentifiedByXPath(
- WebDriverWrapper driver, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- }
-
- @Override
- protected List findAllInCurrFrame() {
- String xpath = getXPath();
- List result = new ArrayList();
- for (org.openqa.selenium.WebElement element :
- driver.findElements(By.xpath(xpath)))
- result.add(new WebElementWrapper(driver, element));
- return sortSearchResult(result);
- }
-
- private List sortSearchResult(
- List result
- ) {
- List> resultScores =
- new ArrayList>();
- for (WebElementWrapper element : result) {
- try {
- double score = getSortIndex(element);
- resultScores.add(
- new ResultScore(element, score)
- );
- } catch (StaleElementReferenceException e) {
- // Simply ignore the element.
- }
- }
- return ResultScore.getSortedResults(resultScores);
- }
-
- protected abstract String getXPath();
-
- protected double getSortIndex(WebElementWrapper webElement) {
- return driver.getDistanceToLastManipulated(webElement) + 1;
- }
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/HTMLElementImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/HTMLElementImpl.java
deleted file mode 100644
index e4808d7..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/HTMLElementImpl.java
+++ /dev/null
@@ -1,193 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.FrameIterator;
-import com.heliumhq.selenium_wrappers.FramesChangedWhileIterating;
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-import com.heliumhq.util.Generator;
-import org.openqa.selenium.NoSuchWindowException;
-import org.openqa.selenium.WebElement;
-
-import java.util.*;
-
-import static com.google.common.collect.ObjectArrays.concat;
-import static com.heliumhq.API.Point;
-import static com.heliumhq.util.HtmlUtils.getEasilyReadableSnippet;
-
-public abstract class HTMLElementImpl extends
- GUIElementImpl {
-
- protected final SearchRegion[] searchRegions;
- protected final MatchType matches;
-
- HTMLElementImpl(
- WebDriverWrapper driver, SearchRegion... searchRegions
- ) {
- super(driver);
- this.searchRegions = searchRegions;
- matches = MatchType.PREFIX_IGNORE_CASE;
- }
-
- public int getWidth() {
- return getFirstOccurrence().getLocation().getWidth();
- }
-
- public int getHeight() {
- return getFirstOccurrence().getLocation().getHeight();
- }
-
- public int getX() {
- return getFirstOccurrence().getLocation().getLeft();
- }
-
- public int getY() {
- return getFirstOccurrence().getLocation().getTop();
- }
-
- public Point getTopLeft() {
- return Point(getX(), getY());
- }
-
- public WebElement getWebElement() {
- return getFirstOccurrence().unwrap();
- }
-
- @Override
- protected Object[] getConstructorArgs() {
- Object[] normalConstrArgs = getConstructorArgsBeforeSearchRegions();
- return concat(normalConstrArgs, searchRegions, Object.class);
- }
-
- protected abstract Object[] getConstructorArgsBeforeSearchRegions();
-
- @Override
- public String toString(String className) {
- if (isBound()) {
- String elementHtml = getWebElement().getAttribute("outerHTML");
- return getEasilyReadableSnippet(elementHtml);
- } else
- return super.toString(className);
- }
-
- @Override
- protected Iterable findAllOccurrences() {
- return new Generator() {
-
- private boolean firstCall = true;
- private Iterator frameIndices;
- private int[] frameIndex;
- List searchRegions;
- Iterator occurrences;
-
- @Override
- protected WebElementWrapper generateNext() {
- if (firstCall) {
- firstCall = false;
- handleClosedWindow();
- driver.switchTo().defaultContent();
- }
- if (frameIndices == null)
- frameIndices = new FrameIterator(driver).iterator();
- while (true) {
- if (frameIndex == null)
- try {
- frameIndex = frameIndices.next();
- } catch (FramesChangedWhileIterating e) {
- // Abort this search:
- throw new NoSuchElementException();
- }
- if (searchRegions == null)
- searchRegions = getSearchRegionsInCurrFrame();
- if (occurrences == null)
- occurrences = findAllInCurrFrame().iterator();
- while (occurrences.hasNext()) {
- WebElementWrapper occ = occurrences.next();
- if (shouldYield(occ, searchRegions)) {
- occ.setFrameIndex(frameIndex);
- return occ;
- }
- }
- frameIndex = null;
- searchRegions = null;
- occurrences = null;
- }
- }
-
- private void handleClosedWindow() {
- boolean windowHasBeenClosed;
- Set windowHandles = driver.getWindowHandles();
- try {
- windowHasBeenClosed =
- ! windowHandles.contains(driver.getWindowHandle());
- } catch (NoSuchWindowException e) {
- windowHasBeenClosed = true;
- }
- if (windowHasBeenClosed)
- driver.switchTo().window(windowHandles.iterator().next());
- }
-
- };
- }
-
- private List getSearchRegionsInCurrFrame() {
- List result =
- new ArrayList();
- for (SearchRegion searchRegion : searchRegions)
- result.addAll(searchRegion.getOccurrencesInCurrFrame());
- return result;
- }
-
- private boolean shouldYield(
- WebElementWrapper occurrence,
- List searchRegions
- ) {
- return occurrence.isDisplayed() &&
- isInAnySearchRegion(occurrence, searchRegions);
- }
-
- private boolean isInAnySearchRegion(
- WebElementWrapper element, List searchRegions
- ) {
- // group by SearchDirection
- Map> directionToRegion
- = new HashMap>();
- for (SearchRegion.Occurrence searchRegion : searchRegions) {
- SearchDirection direction = searchRegion.getSearchDirection();
- if (!directionToRegion.containsKey(direction)) {
- directionToRegion.put(
- direction,
- new ArrayList()
- );
- }
- directionToRegion.get(direction).add(searchRegion);
- }
-
- for (SearchDirection direction : SearchDirection.values()) {
- if (directionToRegion.containsKey(direction)) {
- boolean found = false;
- for (SearchRegion.Occurrence searchRegion :
- directionToRegion.get(direction)) {
- if (searchRegion.contains(element)) {
- found = true;
- break;
- }
- }
- if (!found) {
- return false;
- }
- }
- }
-
- return true;
- }
-
- protected abstract Iterable findAllInCurrFrame();
-
- /**
- * Useful for subclasses.
- */
- protected boolean isEnabled() {
- return getFirstOccurrence().getAttribute("disabled") == null;
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/ImageImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/ImageImpl.java
deleted file mode 100644
index 40e7a46..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/ImageImpl.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-import static com.heliumhq.util.XPath.predicate;
-
-public class ImageImpl extends HTMLElementIdentifiedByXPath {
-
- private final String alt;
-
- public ImageImpl(WebDriverWrapper driver, SearchRegion... searchRegions) {
- this(driver, null, searchRegions);
- }
-
- public ImageImpl(
- WebDriverWrapper driver, String alt, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- this.alt = alt;
- }
-
- @Override
- protected Object[] getConstructorArgsBeforeSearchRegions() {
- return new Object[] {alt};
- }
-
- @Override
- protected String getXPath() {
- return "//img" + predicate(matches.xpath("@alt", alt));
- }
-
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/LabelledElement.java b/helium-java/src/main/java/com/heliumhq/api_impl/LabelledElement.java
deleted file mode 100644
index 692840b..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/LabelledElement.java
+++ /dev/null
@@ -1,243 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-import com.heliumhq.util.Tuple;
-import com.heliumhq.util.geom.Rectangle;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebElement;
-
-import java.util.*;
-
-import static com.heliumhq.util.Collections.inverse;
-import static com.heliumhq.util.XPath.predicate;
-import static com.heliumhq.util.StringUtils.isEmpty;
-
-abstract class LabelledElement extends HTMLElementImpl {
-
- private final static double SECONDARY_SEARCH_DIMENSION_PENALTY_FACTOR = 1.5;
-
- private final String label;
-
- LabelledElement(WebDriverWrapper driver, SearchRegion... searchRegions) {
- this(driver, null, searchRegions);
- }
-
- LabelledElement(
- WebDriverWrapper driver, String label, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- this.label = label;
- }
-
- @Override
- protected Object[] getConstructorArgsBeforeSearchRegions() {
- return new Object[] {label};
- }
-
- @Override
- protected List findAllInCurrFrame() {
- List result;
- if (isEmpty(label))
- result = findElts();
- else {
- List labels =
- new TextImpl(driver, label, false).findAllInCurrFrame();
- if (! labels.isEmpty())
- result = filterEltsBelongingToLabels(findElts(), labels);
- else
- result = findEltsByFreeText();
- }
- Collections.sort(result, new Comparator() {
- @Override
- public int compare(WebElementWrapper e1, WebElementWrapper e2) {
- double s1 = driver.getDistanceToLastManipulated(e1);
- double s2 = driver.getDistanceToLastManipulated(e2);
- return (int) Math.round(s1 - s2);
- }
- });
- return result;
- }
-
- private List findElts() {
- return findElts(null);
- }
-
- private List findElts(String xpath) {
- if (xpath == null)
- xpath = getXPath();
- List result = new ArrayList();
- for (WebElement element : driver.findElements(By.xpath(xpath)))
- result.add(new WebElementWrapper(driver, element));
- return result;
- }
-
- private List findEltsByFreeText() {
- List eltTypes = new ArrayList();
- for (String xpath : getXPath().split(("\\|")))
- eltTypes.add(xpath.trim().replaceAll("^/+", ""));
- String labels = "//text()" + predicate(matches.xpath(".", label));
- StringBuilder xpath = new StringBuilder();
- boolean isFirst = true;
- for (String eltType : eltTypes) {
- if (! isFirst)
- xpath.append(" | ");
- xpath.append(labels);
- String axis;
- if (eltType.contains("checkbox") || eltType.contains("radio")) {
- axis = "preceding-sibling";
- } else {
- axis = "following";
- }
- xpath.append(String.format("/%s::", axis));
- xpath.append(eltType);
- xpath.append("[1]");
- isFirst = false;
- }
- return findElts(xpath.toString());
- }
-
- protected abstract String getXPath();
-
- protected SearchDirection getPrimarySearchDirection() {
- return SearchDirection.TO_RIGHT_OF;
- }
-
- protected SearchDirection getSecondarySearchDirection() {
- return SearchDirection.BELOW;
- }
-
- private List filterEltsBelongingToLabels(
- List allElts, List labels
- ) {
- List result = new ArrayList();
- for (Tuple tpl :
- getLabelsWithExplicitElts(allElts, labels)) {
- WebElementWrapper label = tpl.getFirst();
- WebElementWrapper elt = tpl.getSecond();
- result.add(elt);
- labels.remove(label);
- allElts.remove(elt);
- }
- Map> labelsToElts =
- getRelatedElts(allElts, labels);
- labelsToElts = ensureAtMostOneLabelPerElt(labelsToElts);
- retainClosest(labelsToElts);
- for (Set eltsForLabel : labelsToElts.values()) {
- assert eltsForLabel.size() <= 1;
- if (eltsForLabel.size() > 0)
- result.add(eltsForLabel.iterator().next());
- }
- return result;
- }
-
- private List>
- getLabelsWithExplicitElts(
- List allElts, List labels
- ) {
- List> result =
- new ArrayList>();
- for (WebElementWrapper label : labels)
- if ("label".equals(label.getTagName())) {
- String labelTarget = label.getAttribute("for");
- if (!isEmpty(labelTarget))
- for (WebElementWrapper elt : allElts) {
- String eltId = elt.getAttribute("id");
- if (labelTarget.equalsIgnoreCase(eltId))
- result.add(
- new Tuple<
- WebElementWrapper, WebElementWrapper
- >(label, elt)
- );
- }
- }
- return result;
- }
-
- private Map>
- getRelatedElts(
- List allElts, List labels
- ) {
- Map> result =
- new HashMap>();
- for (WebElementWrapper label : labels)
- for (WebElementWrapper elt : allElts)
- if (areRelated(elt, label)) {
- if (!result.containsKey(label))
- result.put(label, new HashSet());
- result.get(label).add(elt);
- }
- return result;
- }
-
- private boolean areRelated(
- WebElementWrapper elt, WebElementWrapper label
- ) {
- Rectangle eltLoc = elt.getLocation();
- Rectangle labelLoc = label.getLocation();
- if (eltLoc.intersects(labelLoc))
- return true;
- SearchDirection primSearchDir = getPrimarySearchDirection();
- SearchDirection secSearchDir = getSecondarySearchDirection();
- return labelLoc.getDistanceTo(eltLoc) <= 150 && (
- primSearchDir.isInDirection(eltLoc, labelLoc) ||
- secSearchDir.isInDirection(eltLoc, labelLoc)
- );
- }
-
- private Map>
- ensureAtMostOneLabelPerElt(
- Map> labelsToElts
- ) {
- Map> eltsToLabels =
- inverse(labelsToElts);
- retainClosest(eltsToLabels);
- return inverse(eltsToLabels);
- }
-
- private void retainClosest(
- Map> pivotsToElts
- ) {
- for (WebElementWrapper pivot : pivotsToElts.keySet()) {
- Set elts = pivotsToElts.get(pivot);
- if (! elts.isEmpty())
- pivotsToElts.put(
- pivot,
- new HashSet(
- Arrays.asList(findClosest(pivot, elts))
- )
- );
- }
- }
-
- private WebElementWrapper findClosest(
- WebElementWrapper toPivot, Set amongElts
- ) {
- Iterator remainingElts = amongElts.iterator();
- WebElementWrapper result = remainingElts.next();
- double resultDistance = computeDistance(result, toPivot);
- while (remainingElts.hasNext()) {
- WebElementWrapper element = remainingElts.next();
- double elementDistance = computeDistance(element, toPivot);
- if (elementDistance < resultDistance) {
- result = element;
- resultDistance = elementDistance;
- }
- }
- return result;
- }
-
- private double computeDistance(
- WebElementWrapper elt1, WebElementWrapper elt2
- ) {
- Rectangle loc1 = elt1.getLocation();
- Rectangle loc2 = elt2.getLocation();
- double factor;
- if (getSecondarySearchDirection().isInDirection(loc1, loc2))
- factor = SECONDARY_SEARCH_DIMENSION_PENALTY_FACTOR;
- else
- factor = 1;
- return factor * loc1.getDistanceTo(loc2);
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/LinkImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/LinkImpl.java
deleted file mode 100644
index e7e37bf..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/LinkImpl.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static com.heliumhq.util.XPath.predicate;
-
-public class LinkImpl extends HTMLElementContainingText {
-
- public LinkImpl(WebDriverWrapper driver, SearchRegion... searchRegions) {
- super(driver, searchRegions);
- }
-
- public LinkImpl(
- WebDriverWrapper driver, String text, SearchRegion... searchRegions
- ) {
- super(driver, text, searchRegions);
- }
-
- public String getHref() {
- return this.getWebElement().getAttribute("href");
- }
-
- @Override
- protected String getXPathNodeSelector() {
- return "a";
- }
-
- @Override
- protected String getXPath() {
- return super.getXPath() + " | " + "//a" +
- predicate(matches.xpath("@title", searchText)) + " | " +
- "//*[@role='link']" + predicate(matches.xpath(".", searchText));
- }
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/ListItemImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/ListItemImpl.java
deleted file mode 100644
index 5b596d5..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/ListItemImpl.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-public class ListItemImpl extends HTMLElementContainingText {
-
- public ListItemImpl(
- WebDriverWrapper driver, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- }
-
- public ListItemImpl(
- WebDriverWrapper driver, String text, SearchRegion... searchRegions
- ) {
- super(driver, text, searchRegions);
- }
-
- @Override
- protected String getXPathNodeSelector() {
- return "li";
- }
-
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/MatchType.java b/helium-java/src/main/java/com/heliumhq/api_impl/MatchType.java
deleted file mode 100644
index 371d2b7..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/MatchType.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.heliumhq.api_impl;
-
-import static com.heliumhq.util.XPath.lower;
-import static com.heliumhq.util.XPath.replaceNbsp;
-import static com.heliumhq.util.StringUtils.isEmpty;
-import static com.heliumhq.util.StringUtils.join;
-
-enum MatchType {
- PREFIX_IGNORE_CASE() {
- @Override
- public String xpath(String value, String text) {
- if (isEmpty(text))
- return "";
- // Asterisks '*' are sometimes used to mark required fields. Eg.:
- //
- // The starts-with filter below would be too strict to include such
- // matches. To get around this, we ignore asterisks unless the
- // searched text itself contains one.
- String stripAsterisks;
- if (text.contains("*")) {
- stripAsterisks = value;
- } else {
- stripAsterisks = String.format("translate(%s, '*', '')", value);
- }
- // if text contains apostrophes (single quotes) then they need to be
- // treated with care
- if (text.contains("'")) {
- text = String.format(
- "concat('%s')", join("',\"'\",'", text.split("'"))
- );
- } else {
- text = String.format("'%s'", text);
- }
-
- return String.format(
- "starts-with(normalize-space(%s), %s)",
- lower(replaceNbsp(stripAsterisks)), text.toLowerCase()
- );
- }
- @Override
- public boolean text(String value, String text) {
- if (isEmpty(text))
- return true;
- return value.toLowerCase().trim().startsWith(text.toLowerCase());
- }
- };
- public abstract String xpath(String value, String text);
- public abstract boolean text(String value, String text);
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/RadioButtonImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/RadioButtonImpl.java
deleted file mode 100644
index 04defad..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/RadioButtonImpl.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-public class RadioButtonImpl extends LabelledElement {
-
- public RadioButtonImpl(
- WebDriverWrapper driver, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- }
-
- public RadioButtonImpl(
- WebDriverWrapper driver, String label, SearchRegion... searchRegions
- ) {
- super(driver, label, searchRegions);
- }
-
- public boolean isSelected() {
- return getFirstOccurrence().getAttribute("checked") != null;
- }
-
- @Override
- protected String getXPath() {
- return "//input[@type='radio']";
- }
-
- @Override
- protected SearchDirection getPrimarySearchDirection() {
- return SearchDirection.TO_LEFT_OF;
- }
-
- @Override
- protected SearchDirection getSecondarySearchDirection() {
- return SearchDirection.TO_RIGHT_OF;
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/ResultScore.java b/helium-java/src/main/java/com/heliumhq/api_impl/ResultScore.java
deleted file mode 100644
index 0a50fd9..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/ResultScore.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.heliumhq.api_impl;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-class ResultScore implements Comparable> {
- public static List getSortedResults(
- Collection> resultScores
- ) {
- List> sortedResultScores =
- new ArrayList>();
- sortedResultScores.addAll(resultScores);
- Collections.sort(sortedResultScores);
- List result = new ArrayList();
- for (ResultScore resultScore : sortedResultScores)
- result.add(resultScore.result);
- return result;
- }
- final T result;
- double score;
- ResultScore(T result) {
- this(result, 0);
- }
- ResultScore(T result, double score) {
- this.result = result;
- this.score = score;
- }
- @Override
- public int compareTo(ResultScore other) {
- return (int) Math.round(score - other.score);
- }
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/SearchDirection.java b/helium-java/src/main/java/com/heliumhq/api_impl/SearchDirection.java
deleted file mode 100644
index 5b165b2..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/SearchDirection.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.util.geom.Rectangle;
-
-public enum SearchDirection {
-
- TO_LEFT_OF {
- @Override
- public boolean isInDirection(Rectangle r1, Rectangle r2) {
- return r1.isToLeftOf(r2);
- }
- },
- TO_RIGHT_OF {
- @Override
- public boolean isInDirection(Rectangle r1, Rectangle r2) {
- return r1.isToRightOf(r2);
- }
- },
- ABOVE {
- @Override
- public boolean isInDirection(Rectangle r1, Rectangle r2) {
- return r1.isAbove(r2);
- }
- },
- BELOW {
- @Override
- public boolean isInDirection(Rectangle r1, Rectangle r2) {
- return r1.isBelow(r2);
- }
- };
-
- public abstract boolean isInDirection(Rectangle r1, Rectangle r2);
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/SearchRegion.java b/helium-java/src/main/java/com/heliumhq/api_impl/SearchRegion.java
deleted file mode 100644
index 628fb3a..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/SearchRegion.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebElementWrapper;
-import com.heliumhq.util.geom.Rectangle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class SearchRegion {
-
- private final SearchDirection searchDirection;
- private final HTMLElementImpl pivotElement;
-
- public SearchRegion(
- SearchDirection searchDirection, HTMLElementImpl element
- ) {
- this.searchDirection = searchDirection;
- this.pivotElement = element;
- }
-
- List getOccurrencesInCurrFrame() {
- List result = new ArrayList();
- for (WebElementWrapper occurrence : pivotElement.findAllInCurrFrame())
- result.add(
- new Occurrence(searchDirection, occurrence.getLocation())
- );
- return result;
- }
-
- class Occurrence {
- private final SearchDirection searchDirection;
- private final Rectangle location;
- private Occurrence(
- SearchDirection searchDirection, Rectangle location
- ) {
- this.searchDirection = searchDirection;
- this.location = location;
- }
- boolean contains(WebElementWrapper element) {
- return searchDirection.isInDirection(
- element.getLocation(), location
- );
- }
- public SearchDirection getSearchDirection() {
- return this.searchDirection;
- }
- }
-
- public String toString() {
- String pivotElementRepr;
- if (pivotElement instanceof TextImpl)
- // Strip surrounding 'Text('...')':
- pivotElementRepr = pivotElement.reprConstuctorArgs();
- else
- pivotElementRepr = pivotElement.toString();
- return String.format(
- "%s(%s)", makeCamelCase(searchDirection.name()), pivotElementRepr
- );
- }
-
- // "ABOVE" -> "above", "TO_LEFT_OF" -> "toLeftOf", etc.
- private String makeCamelCase(String enumName) {
- String[] components = enumName.split("_");
- StringBuilder result = new StringBuilder(components[0].toLowerCase());
- for (int i = 1; i < components.length; i++) {
- String component = components[i];
- result.append(component.charAt(0));
- result.append(component.toLowerCase().substring(1));
- }
- return result.toString();
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/TextFieldImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/TextFieldImpl.java
deleted file mode 100644
index cb82d33..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/TextFieldImpl.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-import static com.heliumhq.util.XPath.lower;
-import static com.heliumhq.util.XPath.predicate;
-
-public class TextFieldImpl extends CompositeElement {
-
- private final String label;
-
- public TextFieldImpl(
- WebDriverWrapper driver, SearchRegion... searchRegions
- ) {
- this(driver, null, searchRegions);
- }
-
- public TextFieldImpl(
- WebDriverWrapper driver, String label, SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- this.label = label;
- }
-
- @Override
- protected Object[] getConstructorArgsBeforeSearchRegions() {
- return new Object[] {label};
- }
-
- public String getValue() {
- return ((TextFieldType) getFirstElement()).getValue();
- }
-
- public boolean isEnabled() {
- return ((TextFieldType) getFirstElement()).isEnabled();
- }
-
- public boolean isEditable() {
- return ((TextFieldType) getFirstElement()).isEditable();
- }
-
- @Override
- protected HTMLElementImpl[] getElements() {
- return new HTMLElementImpl[] {
- new StandardTextFieldWithPlaceHolder(
- driver, label, searchRegions
- ),
- new StandardTextFieldWithLabel(driver, label, searchRegions),
- new AriaTextFieldWithLabel(driver, label, searchRegions)
- };
- }
-
- private interface TextFieldType {
- String getValue();
- boolean isEnabled();
- boolean isEditable();
- }
-
- private class StandardTextFieldWithLabel extends LabelledElement
- implements TextFieldType {
-
- StandardTextFieldWithLabel(
- WebDriverWrapper driver, String label,
- SearchRegion... searchRegions
- ) {
- super(driver, label, searchRegions);
- }
-
- @Override
- public String getValue() {
- String result = getFirstOccurrence().getAttribute("value");
- if (result == null)
- return "";
- return result;
- }
-
- @Override
- public boolean isEnabled() {
- return super.isEnabled();
- }
-
- @Override
- public boolean isEditable() {
- return getFirstOccurrence().getAttribute("readOnly") == null;
- }
-
- @Override
- protected String getXPath() {
- return String.format(
- "//input[%s='text' or %s='email' or %s='password'" +
- " or %s='number' or %s='tel' or string-length(@type)=0]",
- lower("@type"), lower("@type"), lower("@type"), lower("@type"),
- lower("@type")
- ) + " | //textarea | //*[@contenteditable='true']";
- }
- }
-
- private class AriaTextFieldWithLabel extends LabelledElement
- implements TextFieldType {
-
- AriaTextFieldWithLabel(
- WebDriverWrapper driver, String label,
- SearchRegion... searchRegions
- ) {
- super(driver, label, searchRegions);
- }
-
- @Override
- public String getValue() {
- return getFirstOccurrence().getText();
- }
-
- @Override
- public boolean isEnabled() {
- return super.isEnabled();
- }
-
- @Override
- public boolean isEditable() {
- return getFirstOccurrence().getAttribute("readOnly") == null;
- }
-
- @Override
- protected String getXPath() {
- return "//*[@role='textbox']";
- }
- }
-
- private class StandardTextFieldWithPlaceHolder extends
- HTMLElementIdentifiedByXPath implements TextFieldType {
-
- private final String label;
-
- StandardTextFieldWithPlaceHolder(
- WebDriverWrapper driver, String label,
- SearchRegion... searchRegions
- ) {
- super(driver, searchRegions);
- this.label = label;
- }
-
- @Override
- public String getValue() {
- String result = getFirstOccurrence().getAttribute("value");
- if (result == null)
- return "";
- return result;
- }
-
- @Override
- public boolean isEnabled() {
- return super.isEnabled();
- }
-
- @Override
- public boolean isEditable() {
- return getFirstOccurrence().getAttribute("readOnly") == null;
- }
-
- @Override
- protected Object[] getConstructorArgsBeforeSearchRegions() {
- return new Object[] {label};
- }
-
- @Override
- protected String getXPath() {
- return String.format(
- "(%s)%s",
- new StandardTextFieldWithLabel(driver, label).getXPath(),
- predicate(matches.xpath("@placeholder", label))
- );
- }
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/TextImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/TextImpl.java
deleted file mode 100644
index fa7e9da..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/TextImpl.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-
-import static com.heliumhq.util.StringUtils.isEmpty;
-
-public class TextImpl extends HTMLElementContainingText {
-
- private final boolean includeFreeTexts;
-
- public TextImpl(WebDriverWrapper driver, SearchRegion... searchRegions) {
- super(driver, searchRegions);
- this.includeFreeTexts = true;
- }
-
- public TextImpl(
- WebDriverWrapper driver, String text, SearchRegion... searchRegions
- ) {
- super(driver, text, searchRegions);
- this.includeFreeTexts = true;
- }
-
- public TextImpl(
- WebDriverWrapper driver, String label, boolean includeFreeTexts
- ) {
- super(driver, label);
- this.includeFreeTexts = includeFreeTexts;
- }
-
- public String getValue() {
- return getFirstOccurrence().getText();
- }
-
- @Override
- protected String getXPath() {
- ButtonImpl buttonImpl = new ButtonImpl(driver, searchText);
- LinkImpl linkImpl = new LinkImpl(driver, searchText);
- String result = getSearchTextXPath();
- result += " | " + buttonImpl.getInputButtonXPath();
- result += " | " + linkImpl.getXPath();
- if (! isEmpty(searchText) && includeFreeTexts)
- result += " | " + new FreeText(driver, searchText).getXPath();
- return result;
- }
-
- String getSearchTextXPath() {
- String result;
- if (! isEmpty(searchText))
- result = super.getXPath();
- else {
- String noDescendantWithSameText =
- "not(.//*[normalize-space(.)=normalize-space(self::*)])";
- result =
- String.format("//*[text() and %s]", noDescendantWithSameText);
- }
- return result + "[not(self::option)]"
- + (this.includeFreeTexts ? "" : "[count(*) <= 1]");
- }
-
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/WindowImpl.java b/helium-java/src/main/java/com/heliumhq/api_impl/WindowImpl.java
deleted file mode 100644
index c2f5a73..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/WindowImpl.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package com.heliumhq.api_impl;
-
-import com.heliumhq.selenium_wrappers.WebDriverWrapper;
-import org.openqa.selenium.NoSuchWindowException;
-import org.openqa.selenium.WebDriver;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class WindowImpl extends GUIElementImpl {
-
- private final String searchTitle;
-
- public WindowImpl(WebDriverWrapper driver) {
- this(driver, null);
- }
-
- public WindowImpl(WebDriverWrapper driver, String title) {
- super(driver);
- searchTitle = title;
- }
-
- @Override
- protected Iterable findAllOccurrences() {
- List> resultScores =
- new ArrayList>();
- for (String handle : driver.unwrap().getWindowHandles()) {
- SeleniumWindow window = new SeleniumWindow(driver.unwrap(), handle);
- if (searchTitle == null)
- resultScores.add(new ResultScore(window));
- else {
- String title = window.getTitle();
- if (title.startsWith(searchTitle)) {
- int score = title.length() - searchTitle.length();
- resultScores.add(
- new ResultScore(window, score)
- );
- }
- }
- }
- return ResultScore.getSortedResults(resultScores);
- }
-
- public String getTitle() {
- return getFirstOccurrence().getTitle();
- }
-
- public String getHandle() {
- return getFirstOccurrence().getHandle();
- }
-
- @Override
- protected Object[] getConstructorArgs() {
- String title = isBound() ? getTitle() : searchTitle;
- return new Object[] {title};
- }
-
- static class SeleniumWindow {
- private final WebDriver driver;
- private final String handle;
- private String windowHandleBefore;
-
- public SeleniumWindow(WebDriver driver, String handle) {
- this.driver = driver;
- this.handle = handle;
- }
-
- public String getHandle() {
- return handle;
- }
-
- public String getTitle() {
- activateTemporarily();
- try {
- return driver.getTitle();
- } finally {
- restorePreviousWindow();
- }
- }
-
- private void activateTemporarily() {
- boolean doSwitch;
- try {
- windowHandleBefore = driver.getWindowHandle();
- doSwitch = ! windowHandleBefore.equals(handle);
- } catch (NoSuchWindowException windowClosed) {
- doSwitch = true;
- }
- if (doSwitch)
- driver.switchTo().window(handle);
- }
-
- private void restorePreviousWindow() {
- if (
- windowHandleBefore != null &&
- !driver.getWindowHandle().equals(windowHandleBefore)
- )
- driver.switchTo().window(windowHandleBefore);
- }
- }
-
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/APIConfig.java b/helium-java/src/main/java/com/heliumhq/api_impl/application_context/APIConfig.java
deleted file mode 100644
index 8a9200d..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/APIConfig.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.heliumhq.api_impl.application_context;
-
-import com.heliumhq.environment.ResourceLocator;
-import com.heliumhq.api_impl.APIImpl;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public abstract class APIConfig {
-
- private APIImpl apiImpl;
-
- public APIConfig() {
- initializeLogging();
- }
-
- protected abstract void initializeLogging();
-
- public APIImpl getAPIImpl() {
- if (apiImpl == null)
- apiImpl = new APIImpl(getResourceLocator());
- return apiImpl;
- }
-
- public abstract ResourceLocator getResourceLocator();
-
- protected void suppressSeleniumLoggers() {
- Logger.getLogger("org.openqa.selenium").setLevel(Level.WARNING);
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/ApplicationContext.java b/helium-java/src/main/java/com/heliumhq/api_impl/application_context/ApplicationContext.java
deleted file mode 100644
index ef7d677..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/ApplicationContext.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.heliumhq.api_impl.application_context;
-
-public class ApplicationContext {
-
- private static APIConfig APPLICATION_CONTEXT;
-
- public static APIConfig getApplicationContext() {
- if (APPLICATION_CONTEXT == null) {
- if (isDevelopment())
- APPLICATION_CONTEXT = new DevelopmentAPIConfig();
- else
- APPLICATION_CONTEXT = new StandaloneAPIConfig();
- }
- return APPLICATION_CONTEXT;
- }
-
- private static boolean isDevelopment() {
- return ! isRunningFromJar();
- }
-
- private static boolean isRunningFromJar() {
- String className = ApplicationContext.class.getName().replace('.', '/');
- String classFileLocation = ApplicationContext.class.getResource(
- "/" + className + ".class"
- ).toString();
- return classFileLocation.startsWith("jar:");
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/DevelopmentAPIConfig.java b/helium-java/src/main/java/com/heliumhq/api_impl/application_context/DevelopmentAPIConfig.java
deleted file mode 100644
index e523a4c..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/DevelopmentAPIConfig.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.heliumhq.api_impl.application_context;
-
-import com.heliumhq.environment.ResourceLocator;
-
-import java.io.File;
-import java.util.Arrays;
-
-import static com.heliumhq.util.System.*;
-
-public class DevelopmentAPIConfig extends APIConfig {
-
- private ResourceLocator resourceLocator;
-
- public static String getHeliumFile(String relPath) {
- File result = getHeliumDir();
- for (String relPathComponent : relPath.split("/"))
- result = new File(result, relPathComponent);
- return result.getAbsolutePath();
- }
-
- public static File getHeliumDir() {
- File result = new File(".").getAbsoluteFile();
- while (! Arrays.asList(result.list()).contains("pom.xml") ||
- ! result.getName().equalsIgnoreCase("helium"))
- result = result.getParentFile();
- return result;
- }
-
- @Override
- protected void initializeLogging() {
- suppressSeleniumLoggers();
- }
-
- @Override
- public ResourceLocator getResourceLocator() {
- if (resourceLocator == null) {
- String platfDir;
- if (isWindows())
- platfDir = "win";
- else if (isLinux())
- platfDir = "linux";
- else {
- assert isOSX();
- platfDir = "macosx";
- }
- resourceLocator = new ResourceLocator(
- getHeliumFile("src/main/resources/" + platfDir),
- getHeliumFile("target")
- );
- }
- return resourceLocator;
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/StandaloneAPIConfig.java b/helium-java/src/main/java/com/heliumhq/api_impl/application_context/StandaloneAPIConfig.java
deleted file mode 100644
index a9dd674..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/StandaloneAPIConfig.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.heliumhq.api_impl.application_context;
-
-import com.heliumhq.environment.ResourceLocator;
-import com.heliumhq.util.FileUtil;
-
-import java.io.*;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.*;
-
-import static com.heliumhq.util.Date.createDate;
-import static java.util.logging.Level.WARNING;
-
-public class StandaloneAPIConfig extends APIConfig {
-
- private ResourceLocator resourceLocator;
-
- @Override
- protected void initializeLogging() {
- suppressApacheHttpLogsOnStderr();
- suppressSeleniumLoggers();
- }
-
- /**
- * When starting IEDriverServer, the Java implementation of Selenium polls
- * the server by sending HTTP requests to it until it has initialized. Each
- * failed poll attempt before that prints some log output on stderr:
- *
- * org.apache.http.impl.client.DefaultHttpClient tryExecute
- * INFO: I/O exception (java.net.SocketException) caught when processing
- * request: Software caused connection abort: recv failed
- * org.apache.http.impl.client.DefaultHttpClient tryExecute
- * INFO: Retrying request
- *
- * suppressApacheHttpLogsOnStderr() prevents this log message from
- * appearing in most (but not all) cases.
- *
- * For further information on the issue, see http://jimevansmusic.blogspot.
- * com/2012/12/seeing-info-messages-in-log-does-not.html or https://groups.
- * google.com/forum/#!topic/selenium-users/iZKKXkhfV2k.
- */
- private void suppressApacheHttpLogsOnStderr() {
- Logger.getLogger("org.apache.http.impl").setLevel(Level.WARNING);
- }
-
- @Override
- public ResourceLocator getResourceLocator() {
- if (resourceLocator == null) {
- File containingJar = urlToFile(
- StandaloneAPIConfig.class.getProtectionDomain().getCodeSource().
- getLocation()
- );
- String heliumRoot = containingJar.getParentFile().
- getParentFile().getAbsolutePath();
- resourceLocator = new ResourceLocator(heliumRoot);
- }
- return resourceLocator;
- }
-
- /**
- * A file:// URL may contain special escape characters such as %20 in
- * file:///c:/Documents%20and%20Settings/... This method converts file URLs
- * to File objects while making a best effort to handle such cases (ie.
- * return File("c:/Documents and Settings/...")). Unfortunately, the current
- * implementation of this still isn't 100% bullet proof, see:
- * https://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html
- */
- private File urlToFile(URL fileURL) {
- try {
- return new File(fileURL.toURI());
- } catch (URISyntaxException e) {
- return new File(fileURL.getPath());
- }
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/StartupError.java b/helium-java/src/main/java/com/heliumhq/api_impl/application_context/StartupError.java
deleted file mode 100644
index 18fd006..0000000
--- a/helium-java/src/main/java/com/heliumhq/api_impl/application_context/StartupError.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.heliumhq.api_impl.application_context;
-
-import com.heliumhq.errors.HeliumError;
-
-public class StartupError extends HeliumError {
- public StartupError(String message) {
- super(message);
- }
-}
diff --git a/helium-java/src/main/java/com/heliumhq/environment/ResourceLocator.java b/helium-java/src/main/java/com/heliumhq/environment/ResourceLocator.java
deleted file mode 100644
index e8808a4..0000000
--- a/helium-java/src/main/java/com/heliumhq/environment/ResourceLocator.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.heliumhq.environment;
-
-import java.io.File;
-
-public class ResourceLocator {
-
- String[] rootDirs;
-
- public ResourceLocator(String... rootDirs) {
- this.rootDirs = rootDirs;
- }
-
- public String locate(String... relPathComponents) {
- for (String rootDir : rootDirs) {
- String location = constructPath(rootDir, relPathComponents);
- if (new File(location).exists())
- return location;
- }
- return constructPath(rootDirs[0], relPathComponents);
- }
-
- private String constructPath(String root, String... relPathComponents) {
- File result = new File(root);
- for (String relPathComponent : relPathComponents)
- result = new File(result, relPathComponent);
- return result.getAbsolutePath();
- }
-
-}
\ No newline at end of file
diff --git a/helium-java/src/main/java/com/heliumhq/errors/HeliumError.java b/helium-java/src/main/java/com/heliumhq/errors/HeliumError.java
deleted file mode 100644
index 6591433..0000000
--- a/helium-java/src/main/java/com/heliumhq/errors/HeliumError.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.heliumhq.errors;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-public class HeliumError extends Error {
-
- public HeliumError(String message) {
- super(message);
- }
-
- public HeliumError(Throwable cause) {
- super(cause);
- }
-
- public String toString() {
- return "- " + getMessage();
- }
-
- public void printStackTrace() {
- truncateStackTrace();
- super.printStackTrace();
- }
-
- private void truncateStackTrace() {
- StackTraceElement[] stackTrace = getStackTrace();
- List newStackTrace =
- new ArrayList();
- for (int i = stackTrace.length - 1; i >= 0; i--) {
- newStackTrace.add(0, stackTrace[i]);
- if (stackTrace[i].getClassName().startsWith("com.heliumhq.API"))
- break;
- }
- setStackTrace(newStackTrace.toArray(
- new StackTraceElement[newStackTrace.size()]
- ));
- }
-
- @Override
- public void printStackTrace(PrintStream s) {
- truncateStackTrace();
- super.printStackTrace(s);
- }
-
- @Override
- public void printStackTrace(PrintWriter s) {
- truncateStackTrace();
- super.printStackTrace(s);
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/FrameIterator.java b/helium-java/src/main/java/com/heliumhq/selenium_wrappers/FrameIterator.java
deleted file mode 100644
index e7892ed..0000000
--- a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/FrameIterator.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.heliumhq.selenium_wrappers;
-
-import com.heliumhq.util.Generator;
-import org.openqa.selenium.NoSuchFrameException;
-import org.openqa.selenium.WebDriverException;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-public class FrameIterator implements Iterable {
-
- private final WebDriverWrapper driver;
- private final int[] startFrame;
-
- public FrameIterator(WebDriverWrapper driver) {
- this(driver, new int[0]);
- }
-
- public FrameIterator(WebDriverWrapper driver, int[] startFrame) {
- this.driver = driver;
- this.startFrame = startFrame;
- }
-
- @Override
- public Iterator iterator() {
- return (new Generator() {
-
- boolean firstCall = true;
- int newFrame = 0;
- boolean newFrameChanged = true;
- Iterator results;
-
- protected int[] generateNext() {
- if (firstCall) {
- firstCall = false;
- return new int[0];
- }
- while (true) {
- if (newFrameChanged) {
- newFrameChanged = false;
- try {
- driver.switchTo().frame(newFrame);
- } catch (WebDriverException e) {
- throw new NoSuchElementException();
- }
- int[] newStartFrame =
- concat(startFrame, new int[]{newFrame});
- results =
- new FrameIterator(driver, newStartFrame).iterator();
- }
- if (results.hasNext())
- return concat(new int[]{newFrame}, results.next());
- try {
- switchToFrame(startFrame);
- } catch (NoSuchFrameException e) {
- throw new FramesChangedWhileIterating();
- }
- newFrame++;
- newFrameChanged = true;
- }
- }
-
- }).iterator();
- }
-
- public void switchToFrame(int[] frameIndexPath) {
- driver.switchTo().defaultContent();
- for (int frameIndex : frameIndexPath)
- driver.switchTo().frame(frameIndex);
- }
-
- int[] concat(int[] a, int[] b) {
- int aLen = a.length;
- int bLen = b.length;
- int[] result = new int[aLen + bLen];
- System.arraycopy(a, 0, result, 0, aLen);
- System.arraycopy(b, 0, result, aLen, bLen);
- return result;
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/FramesChangedWhileIterating.java b/helium-java/src/main/java/com/heliumhq/selenium_wrappers/FramesChangedWhileIterating.java
deleted file mode 100644
index dd4922d..0000000
--- a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/FramesChangedWhileIterating.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.heliumhq.selenium_wrappers;
-
-public class FramesChangedWhileIterating extends RuntimeException {
-}
diff --git a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/WebDriverWrapper.java b/helium-java/src/main/java/com/heliumhq/selenium_wrappers/WebDriverWrapper.java
deleted file mode 100644
index f800d30..0000000
--- a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/WebDriverWrapper.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.heliumhq.selenium_wrappers;
-
-import com.heliumhq.util.geom.Rectangle;
-import org.openqa.selenium.*;
-import org.openqa.selenium.interactions.Actions;
-import org.openqa.selenium.remote.RemoteWebDriver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-public class WebDriverWrapper extends Wrapper {
-
- private WebElementWrapper lastManipulatedElement;
-
- public WebDriverWrapper(WebDriver target) {
- super(target);
- }
-
- public double getDistanceToLastManipulated(WebElementWrapper element) {
- if (lastManipulatedElement == null)
- return 0;
- Rectangle lastManipulatedLocation;
- try {
- lastManipulatedLocation = lastManipulatedElement.getLocation();
- } catch (StaleElementReferenceException e) {
- return 0;
- }
- return element.getLocation().getDistanceTo(lastManipulatedLocation);
- }
-
- public void setLastManipulatedElement(WebElementWrapper value) {
- lastManipulatedElement = value;
- }
-
- public Actions action() {
- return new Actions(target);
- }
-
- public List findElements(By by) {
- List result = target.findElements(by);
- // The Python implementation sometimes returns None instead of [] for
- // find_elements_by_xpath(...). Just in case this also occurs in
- // Selenium's Java bindings, we add the null-check here too:
- if (result == null)
- result = new ArrayList();
- return result;
- }
-
- public void get(String url) {
- target.get(url);
- }
-
- public Object executeScript(String script, Object... args) {
- return ((JavascriptExecutor) target).executeScript(script, args);
- }
-
- public String getBrowserName() {
- return ((RemoteWebDriver) target).getCapabilities().getBrowserName();
- }
-
- public boolean isFirefox() {
- return "firefox".equals(getBrowserName());
- }
-
- public boolean isIE() {
- return "internet explorer".equals(getBrowserName());
- }
-
- public WebDriver.TargetLocator switchTo() {
- return target.switchTo();
- }
-
- public String getWindowHandle() {
- return target.getWindowHandle();
- }
-
- public Set getWindowHandles() {
- return target.getWindowHandles();
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/WebElementWrapper.java b/helium-java/src/main/java/com/heliumhq/selenium_wrappers/WebElementWrapper.java
deleted file mode 100644
index fd5dad6..0000000
--- a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/WebElementWrapper.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package com.heliumhq.selenium_wrappers;
-
-import com.heliumhq.util.geom.Rectangle;
-import org.openqa.selenium.*;
-
-public class WebElementWrapper extends Wrapper {
-
- private WebDriverWrapper driver;
-
- private Rectangle cachedLocation;
-
- private int[] frameIndex;
-
- public WebElementWrapper(WebDriverWrapper driver, WebElement target) {
- super(target);
- this.driver = driver;
- }
-
- public void setFrameIndex(int[] frameIndex) {
- this.frameIndex = frameIndex;
- }
-
- public Rectangle getLocation() {
- if (cachedLocation == null)
- cacheLocation();
- return cachedLocation;
- }
-
- private void cacheLocation() {
- if (frameIndex == null)
- cacheLocationWithoutHandlingErrors();
- else {
- try {
- cacheLocationWithoutHandlingErrors();
- } catch (StaleElementReferenceException originalExc) {
- try {
- new FrameIterator(driver).switchToFrame(frameIndex);
- cacheLocationWithoutHandlingErrors();
- } catch (NoSuchFrameException e2) {
- throw originalExc;
- }
- }
- }
- }
-
- // In the Python implementation of Selenium, when the browser is closed and
- // a WebElement's .location is accessed, an ugly socket.error is raised:
- // "No connection could be made because the target machine actively refused
- // it". The Python implementation of Helium catches this exception and
- // raises a more meaningful StaleElementReferenceException in this case (see
- // _translate_url_errors_caused_by_server_shutdown).
- // The Java implementation of Selenium does not have the problem described
- // above (it throws a descriptive error in the aforementioned situation).
- // Hence we don't need to do anything special here.
- private void cacheLocationWithoutHandlingErrors() {
- Point location = target.getLocation();
- Dimension size = target.getSize();
- cachedLocation = new Rectangle(
- location.getX(), location.getY(),
- size.getWidth(), size.getHeight()
- );
- }
-
- public boolean isDisplayed() {
- try {
- return target.isDisplayed() && getLocation().intersects(
- new Rectangle(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE)
- );
- } catch (StaleElementReferenceException e) {
- return false;
- }
- }
-
- public String getAttribute(String name) {
- if (frameIndex == null)
- return target.getAttribute(name);
- try {
- return target.getAttribute(name);
- } catch (StaleElementReferenceException originalExc) {
- try {
- new FrameIterator(driver).switchToFrame(frameIndex);
- return target.getAttribute(name);
- } catch (NoSuchFrameException e) {
- throw originalExc;
- }
- }
- }
-
- public String getText() {
- if (frameIndex == null)
- return target.getText();
- try {
- return target.getText();
- } catch (StaleElementReferenceException originalExc) {
- try {
- new FrameIterator(driver).switchToFrame(frameIndex);
- return target.getText();
- } catch (NoSuchFrameException e) {
- throw originalExc;
- }
- }
- }
-
- public String getTagName() {
- if (frameIndex == null)
- return target.getTagName();
- try {
- return target.getTagName();
- } catch (StaleElementReferenceException originalExc) {
- try {
- new FrameIterator(driver).switchToFrame(frameIndex);
- return target.getTagName();
- } catch (NoSuchFrameException e) {
- throw originalExc;
- }
- }
- }
-
- public String toString() {
- return String.format(
- "<%s>%s%s>", getTagName(), getText(), getTagName()
- );
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/Wrapper.java b/helium-java/src/main/java/com/heliumhq/selenium_wrappers/Wrapper.java
deleted file mode 100644
index 6f43016..0000000
--- a/helium-java/src/main/java/com/heliumhq/selenium_wrappers/Wrapper.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.heliumhq.selenium_wrappers;
-
-public class Wrapper {
-
- protected final T target;
-
- protected Wrapper(T target) {
- this.target = target;
- }
-
- public T unwrap() {
- return target;
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/util/Collections.java b/helium-java/src/main/java/com/heliumhq/util/Collections.java
deleted file mode 100644
index 41a2a4e..0000000
--- a/helium-java/src/main/java/com/heliumhq/util/Collections.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.heliumhq.util;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-public class Collections {
- public static Map> inverse(Map> map) {
- Map> result = new HashMap>();
- for (Map.Entry> entry : map.entrySet())
- for (V value : entry.getValue()) {
- if (! result.containsKey(value))
- result.put(value, new HashSet());
- result.get(value).add(entry.getKey());
- }
- return result;
- }
-}
diff --git a/helium-java/src/main/java/com/heliumhq/util/Date.java b/helium-java/src/main/java/com/heliumhq/util/Date.java
deleted file mode 100644
index 8b2bfaf..0000000
--- a/helium-java/src/main/java/com/heliumhq/util/Date.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.heliumhq.util;
-
-import java.util.GregorianCalendar;
-
-public class Date {
-
- public static GregorianCalendar createDate() {
- return new GregorianCalendar();
- }
-
- public static GregorianCalendar createDate(int year, int month, int day) {
- return new GregorianCalendar(year, month - 1, day);
- }
-
- public static GregorianCalendar createDate(long date) {
- GregorianCalendar result = new GregorianCalendar();
- result.setTimeInMillis(date);
- return result;
- }
-
-}
diff --git a/helium-java/src/main/java/com/heliumhq/util/FileUtil.java b/helium-java/src/main/java/com/heliumhq/util/FileUtil.java
deleted file mode 100644
index 9e0a949..0000000
--- a/helium-java/src/main/java/com/heliumhq/util/FileUtil.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.heliumhq.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-
-public class FileUtil {
-
- public static void copyFile(File sourceFile, File destFile) throws
- IOException {
- // make sure the destination directory exists
- File outDirectory = getDirectory(destFile);
- if (!outDirectory.exists()) {
- outDirectory.mkdirs();
- }
-
- if (!destFile.exists()) {
- destFile.createNewFile();
- }
- FileChannel source = null;
- FileChannel destination = null;
- try {
- source = new FileInputStream(sourceFile).getChannel();
- destination = new FileOutputStream(destFile).getChannel();
- destination.transferFrom(source, 0, source.size());
- } finally {
- if (source != null) {
- source.close();
- }
- if (destination != null) {
- destination.close();
- }
- }
- }
-
- public static File getDirectory(File file) {
- int sep = file.getAbsolutePath().lastIndexOf(File.separator);
- File outDirectory = new File(file.getAbsolutePath().substring(0, sep));
- return outDirectory;
- }
-}
diff --git a/helium-java/src/main/java/com/heliumhq/util/Generator.java b/helium-java/src/main/java/com/heliumhq/util/Generator.java
deleted file mode 100644
index 92f0b09..0000000
--- a/helium-java/src/main/java/com/heliumhq/util/Generator.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.heliumhq.util;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-public abstract class Generator implements Iterable