From 7012222837546382d70806d3e8c7975000b99250 Mon Sep 17 00:00:00 2001 From: ractoc Date: Mon, 15 Jul 2019 08:57:07 +0200 Subject: [PATCH 01/23] updated the elementShouldContain, elementShouldNotContain, elementTextShouldBe and elementText ShouldNotBe to support either case sensitive or case insensitive operation. This is in line with recent changes to the Python version of the selenium library. Unfortunately, along the way, the indentation has been changed from tabs to all spaces. --- .../seleniumlibrary/keywords/Element.java | 1927 +++++++++-------- 1 file changed, 973 insertions(+), 954 deletions(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java index 706c841..d120aeb 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java @@ -5,6 +5,7 @@ import java.util.Iterator; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.openqa.selenium.By; import org.openqa.selenium.Dimension; import org.openqa.selenium.JavascriptExecutor; @@ -25,367 +26,373 @@ @RobotKeywords public class Element extends RunOnFailureKeywordsAdapter { - /** - * Instantiated BrowserManagement keyword bean - */ - @Autowired - protected BrowserManagement browserManagement; - - /** - * Instantiated FormElement keyword bean - */ - @Autowired - protected FormElement formElement; - - /** - * Instantiated Logging keyword bean - */ - @Autowired - protected Logging logging; - - @Autowired - protected Robot robot; - - // ############################## - // Keywords - Element Lookups - // ############################## - - @RobotKeyword("Verify the current frame contains ``text``.\n\r" - + "\n\r" - + "See `Introduction` for details about log levels.") - @ArgumentNames({ "text", "logLevel=INFO" }) - public void currentFrameContains(String text, String...params) { - String logLevel = robot.getParamsValue(params, 0, "INFO"); - if (!isTextPresent(text)) { - logging.log(String.format("Current Frame Contains: %s => FAILED", text), logLevel); - throw new SeleniumLibraryNonFatalException( - String.format("Page should have contained text '%s', but did not.", text)); - } else { - logging.log(String.format("Current Frame Contains: %s => OK", text), logLevel); - } - } + /** + * Instantiated BrowserManagement keyword bean + */ + @Autowired + protected BrowserManagement browserManagement; + + /** + * Instantiated FormElement keyword bean + */ + @Autowired + protected FormElement formElement; + + /** + * Instantiated Logging keyword bean + */ + @Autowired + protected Logging logging; + + @Autowired + protected Robot robot; + + // ############################## + // Keywords - Element Lookups + // ############################## + + @RobotKeyword("Verify the current frame contains ``text``.\n\r" + + "\n\r" + + "See `Introduction` for details about log levels.") + @ArgumentNames({ "text", "logLevel=INFO" }) + public void currentFrameContains(String text, String...params) { + String logLevel = robot.getParamsValue(params, 0, "INFO"); + if (!isTextPresent(text)) { + logging.log(String.format("Current Frame Contains: %s => FAILED", text), logLevel); + throw new SeleniumLibraryNonFatalException( + String.format("Page should have contained text '%s', but did not.", text)); + } else { + logging.log(String.format("Current Frame Contains: %s => OK", text), logLevel); + } + } @RobotKeyword("Verify the current frame does not contain ``text``.\n\r" + "\n\r" + "See `Introduction` for details about log levels.") - @ArgumentNames({ "text", "logLevel=INFO" }) - public void currentFrameShouldNotContain(String text, String...params) { - String logLevel = robot.getParamsValue(params, 0, "INFO"); - if (isTextPresent(text)) { - logging.log(String.format("Current Frame Should Not Contain: %s => FAILED", text), logLevel); - throw new SeleniumLibraryNonFatalException( - String.format("Page should have not contained text '%s', but did.", text)); - } else { - logging.log(String.format("Current Frame Should Not Contain: %s => OK", text), logLevel); - } - } - - @RobotKeyword("Verify the element identified by ``locator`` contains ``text``.\n\r" - + "\n\r" - + "See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "text", "message=NONE" }) - public void elementShouldContain(String locator, String text, String...params) { - String message = robot.getParamsValue(params, 0, ""); - String actual = getText(locator); - - if (!actual.toLowerCase().contains(text.toLowerCase())) { - logging.info(String.format("Element Should Contain: %s => FAILED", text)); - throw new SeleniumLibraryNonFatalException( - String.format("Element should have contained text '%s', but its text was %s.", text, actual)); - } else { - logging.info(String.format("Element Should Contain: %s => OK", text)); - } - } - - @RobotKeyword("Verify the element identified by ``locator`` does not contain ``text``.\r\n" - + "\r\n" - + "See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "text", "message=NONE" }) - public void elementShouldNotContain(String locator, String text, String...params) { - String message = robot.getParamsValue(params, 0, ""); - String actual = getText(locator); - - if (actual.toLowerCase().contains(text.toLowerCase())) { - logging.info(String.format("Element Should Not Contain: %s => FAILED", text)); - throw new SeleniumLibraryNonFatalException( - String.format("Element should not have contained text '%s', but its text was %s.", text, actual)); - } else { - logging.info(String.format("Element Should Not Contain: %s => OK", text)); - } - } - - @RobotKeyword("Verify the frame identified by ``locator`` contains ``text``.\n\r" - + "\n\r" - + "See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "text", "logLevel=INFO" }) - public void frameShouldContain(String locator, String text, String...params) { - String logLevel = robot.getParamsValue(params, 0, "INFO"); - if (!frameContains(locator, text)) { - logging.log(String.format("Frame Should Contain: %s => FAILED", text), logLevel); - throw new SeleniumLibraryNonFatalException( - String.format("Frame should have contained text '%s', but did not.", text)); - } else { - logging.log(String.format("Frame Should Contain: %s => OK", text), logLevel); - } - } - - @RobotKeyword("Verify the frame identified by ``locator`` does not contain ``text``.\n\r" - + "\n\r" - + "See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "text", "logLevel=INFO" }) - public void frameShouldNotContain(String locator, String text, String...params) { + @ArgumentNames({ "text", "logLevel=INFO" }) + public void currentFrameShouldNotContain(String text, String...params) { String logLevel = robot.getParamsValue(params, 0, "INFO"); - if (frameContains(locator, text)) { - logging.log(String.format("Frame Should Not Contain: %s => FAILED", text), logLevel); - throw new SeleniumLibraryNonFatalException( - String.format("Frame should not have contained text '%s', but did.", text)); - } else { - logging.log(String.format("Frame Should Not Contain: %s => OK", text), logLevel); - } - } - - @RobotKeyword("Verify the current page contains ``text``.\n\r" - + "\n\r" - + "See `Introduction` for details about log levels.") - @ArgumentNames({ "text", "logLevel=INFO" }) - public void pageShouldContain(String text, String...params) { + if (isTextPresent(text)) { + logging.log(String.format("Current Frame Should Not Contain: %s => FAILED", text), logLevel); + throw new SeleniumLibraryNonFatalException( + String.format("Page should have not contained text '%s', but did.", text)); + } else { + logging.log(String.format("Current Frame Should Not Contain: %s => OK", text), logLevel); + } + } + + @RobotKeyword("Verify the element identified by ``locator`` contains ``text``.\n\r" + + "\n\r" + + "See `Introduction` for details about locators.") + @ArgumentNames({ "locator", "text", "message=NONE", "ignore_case=False" }) + public void elementShouldContain(String locator, String text, String...params) { + String message = robot.getParamsValue(params, 0, StringUtils.EMPTY); + Boolean ignoreCase = robot.getParamsValue(params, 1, Boolean.FALSE); + String actual = getText(locator); + + if (!textContains(actual, text, ignoreCase)) { + if (StringUtils.isEmpty(message)) { + message = String.format("Element should have contained text '%s', but its text was %s.", text, actual); + } + logging.info(String.format("Element Should Contain: %s => FAILED", text)); + throw new SeleniumLibraryNonFatalException(message); + } else { + logging.info(String.format("Element Should Contain: %s => OK", text)); + } + } + + @RobotKeyword("Verify the element identified by ``locator`` does not contain ``text``.\r\n" + + "\r\n" + + "See `Introduction` for details about locators.") + @ArgumentNames({ "locator", "text", "message=NONE", "ignore_case=False" }) + public void elementShouldNotContain(String locator, String text, String...params) { + String message = robot.getParamsValue(params, 0, StringUtils.EMPTY); + Boolean ignoreCase = robot.getParamsValue(params, 1, Boolean.FALSE); + String actual = getText(locator); + + if (textContains(actual, text, ignoreCase)) { + if (StringUtils.isEmpty(message)) { + message = String.format("Element should not have contained text '%s', but its text was %s.", text, actual); + } + logging.info(String.format("Element Should Not Contain: %s => FAILED", text)); + throw new SeleniumLibraryNonFatalException(message); + } else { + logging.info(String.format("Element Should Not Contain: %s => OK", text)); + } + } + + @RobotKeyword("Verify the frame identified by ``locator`` contains ``text``.\n\r" + + "\n\r" + + "See `Introduction` for details about locators.") + @ArgumentNames({ "locator", "text", "logLevel=INFO" }) + public void frameShouldContain(String locator, String text, String...params) { String logLevel = robot.getParamsValue(params, 0, "INFO"); - if (!pageContains(text)) { - logging.log(String.format("Page Should Contain: %s => FAILED", text), logLevel); - throw new SeleniumLibraryNonFatalException( - String.format("Page should have contained text '%s' but did not.", text)); - } else { - logging.log(String.format("Page Should Contain: %s => OK", text), logLevel); - } - } - - @RobotKeyword("Verify the current page does not contain ``text``.\n\r" - + "\n\r" - + "See `Introduction` for details about log levels.") - @ArgumentNames({ "text", "logLevel=INFO" }) - public void pageShouldNotContain(String text, String...params) { + if (!frameContains(locator, text)) { + logging.log(String.format("Frame Should Contain: %s => FAILED", text), logLevel); + throw new SeleniumLibraryNonFatalException( + String.format("Frame should have contained text '%s', but did not.", text)); + } else { + logging.log(String.format("Frame Should Contain: %s => OK", text), logLevel); + } + } + + @RobotKeyword("Verify the frame identified by ``locator`` does not contain ``text``.\n\r" + + "\n\r" + + "See `Introduction` for details about locators.") + @ArgumentNames({ "locator", "text", "logLevel=INFO" }) + public void frameShouldNotContain(String locator, String text, String...params) { String logLevel = robot.getParamsValue(params, 0, "INFO"); - if (pageContains(text)) { - logging.log(String.format("Page Should Not Contain: %s => FAILED", text), logLevel); - throw new SeleniumLibraryNonFatalException( - String.format("Page should not have contained text '%s' but did.", text)); - } else { - logging.log(String.format("Page Should Not Contain: %s => OK", text), logLevel); - } - } - - @RobotKeyword("Verify the element identified by ``locator`` is found on the current page\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about log levels and locators.") - @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) - public void pageShouldContainElement(String locator, String...params) { - String message = robot.getParamsValue(params, 0, ""); - String logLevel = robot.getParamsValue(params, 1, "INFO"); - pageShouldContainElement(locator, null, message, logLevel); - } - - protected void pageShouldContainElement(String locator, String tag, String message, String logLevel) { - String name = tag != null ? tag : "element"; - if (!isElementPresent(locator, tag)) { - if (message == null || message.equals("")) { - message = String.format("Page should have contained %s '%s' but did not", name, locator); - } - logging.log(message, logLevel); - throw new SeleniumLibraryNonFatalException(message); - } else { - logging.log(String.format("Current page contains %s '%s'.", name, locator), logLevel); - } - } + if (frameContains(locator, text)) { + logging.log(String.format("Frame Should Not Contain: %s => FAILED", text), logLevel); + throw new SeleniumLibraryNonFatalException( + String.format("Frame should not have contained text '%s', but did.", text)); + } else { + logging.log(String.format("Frame Should Not Contain: %s => OK", text), logLevel); + } + } + + @RobotKeyword("Verify the current page contains ``text``.\n\r" + + "\n\r" + + "See `Introduction` for details about log levels.") + @ArgumentNames({ "text", "logLevel=INFO" }) + public void pageShouldContain(String text, String...params) { + String logLevel = robot.getParamsValue(params, 0, "INFO"); + if (!pageContains(text)) { + logging.log(String.format("Page Should Contain: %s => FAILED", text), logLevel); + throw new SeleniumLibraryNonFatalException( + String.format("Page should have contained text '%s' but did not.", text)); + } else { + logging.log(String.format("Page Should Contain: %s => OK", text), logLevel); + } + } + + @RobotKeyword("Verify the current page does not contain ``text``.\n\r" + + "\n\r" + + "See `Introduction` for details about log levels.") + @ArgumentNames({ "text", "logLevel=INFO" }) + public void pageShouldNotContain(String text, String...params) { + String logLevel = robot.getParamsValue(params, 0, "INFO"); + if (pageContains(text)) { + logging.log(String.format("Page Should Not Contain: %s => FAILED", text), logLevel); + throw new SeleniumLibraryNonFatalException( + String.format("Page should not have contained text '%s' but did.", text)); + } else { + logging.log(String.format("Page Should Not Contain: %s => OK", text), logLevel); + } + } + + @RobotKeyword("Verify the element identified by ``locator`` is found on the current page\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about log levels and locators.") + @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) + public void pageShouldContainElement(String locator, String...params) { + String message = robot.getParamsValue(params, 0, ""); + String logLevel = robot.getParamsValue(params, 1, "INFO"); + pageShouldContainElement(locator, null, message, logLevel); + } + + protected void pageShouldContainElement(String locator, String tag, String message, String logLevel) { + String name = tag != null ? tag : "element"; + if (!isElementPresent(locator, tag)) { + if (message == null || message.equals("")) { + message = String.format("Page should have contained %s '%s' but did not", name, locator); + } + logging.log(message, logLevel); + throw new SeleniumLibraryNonFatalException(message); + } else { + logging.log(String.format("Current page contains %s '%s'.", name, locator), logLevel); + } + } @RobotKeyword("Verify the element identified by ``locator`` is not found on the current page\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about log levels and locators.") - @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) - public void pageShouldNotContainElement(String locator, String...params) { + @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) + public void pageShouldNotContainElement(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); String logLevel = robot.getParamsValue(params, 1, "INFO"); - pageShouldNotContainElement(locator, null, message, logLevel); - } - - protected void pageShouldNotContainElement(String locator, String tag, String message, String logLevel) { - String name = tag != null ? tag : "element"; - if (isElementPresent(locator, tag)) { - if (message == null || message.equals("")) { - message = String.format("Page should not have contained %s '%s' but did", name, locator); - } - logging.log(message, logLevel); - throw new SeleniumLibraryNonFatalException(message); - } else { - logging.log(String.format("Current page does not contain %s '%s'.", name, locator), logLevel); - } - } - - // ############################## - // Keywords - Attributes - // ############################## - - @RobotKeyword("Assigns a temporary identifier to the element identified by ``locator``.\r\n" + - "\r\n" + - "This is mainly useful, when the locator is a complicated and slow XPath expression. The identifier expires when the page is reloaded.\r\n" + - "\r\n" + - "Example:\r\n" + - " | Assign ID to Element | xpath://div[@id=\\\"first_div\\\"] | my id | \r\n" + - " | Page Should Contain Element | my id |") - @ArgumentNames({ "locator", "id" }) - public void assignIdToElement(String locator, String id) { - logging.info(String.format("Assigning temporary id '%s' to element '%s'", id, locator)); - List elements = elementFind(locator, true, true); - - ((JavascriptExecutor) browserManagement.getCurrentWebDriver()) - .executeScript(String.format("arguments[0].id = '%s';", id), elements.get(0)); - } + pageShouldNotContainElement(locator, null, message, logLevel); + } + + protected void pageShouldNotContainElement(String locator, String tag, String message, String logLevel) { + String name = tag != null ? tag : "element"; + if (isElementPresent(locator, tag)) { + if (message == null || message.equals("")) { + message = String.format("Page should not have contained %s '%s' but did", name, locator); + } + logging.log(message, logLevel); + throw new SeleniumLibraryNonFatalException(message); + } else { + logging.log(String.format("Current page does not contain %s '%s'.", name, locator), logLevel); + } + } + + // ############################## + // Keywords - Attributes + // ############################## + + @RobotKeyword("Assigns a temporary identifier to the element identified by ``locator``.\r\n" + + "\r\n" + + "This is mainly useful, when the locator is a complicated and slow XPath expression. The identifier expires when the page is reloaded.\r\n" + + "\r\n" + + "Example:\r\n" + + " | Assign ID to Element | xpath://div[@id=\\\"first_div\\\"] | my id | \r\n" + + " | Page Should Contain Element | my id |") + @ArgumentNames({ "locator", "id" }) + public void assignIdToElement(String locator, String id) { + logging.info(String.format("Assigning temporary id '%s' to element '%s'", id, locator)); + List elements = elementFind(locator, true, true); + + ((JavascriptExecutor) browserManagement.getCurrentWebDriver()) + .executeScript(String.format("arguments[0].id = '%s';", id), elements.get(0)); + } @RobotKeyword("Verify the element identified by ``locator`` is found on the current page\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about log levels and locators.") - @ArgumentNames({ "locator" }) - public void elementShouldBeEnabled(String locator) { - if (!isEnabled(locator)) { - throw new SeleniumLibraryNonFatalException(String.format("Element %s is disabled.", locator)); - } - } + @ArgumentNames({ "locator" }) + public void elementShouldBeEnabled(String locator) { + if (!isEnabled(locator)) { + throw new SeleniumLibraryNonFatalException(String.format("Element %s is disabled.", locator)); + } + } @RobotKeyword("Verify the element identified by ``locator`` is disabled.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void elementShouldBeDisabled(String locator) { - if (isEnabled(locator)) { - throw new SeleniumLibraryNonFatalException(String.format("Element %s is enabled.", locator)); - } - } - - @RobotKeyword("Verify the element identified by ``locator`` is selected.\r\n" + + @ArgumentNames({ "locator" }) + public void elementShouldBeDisabled(String locator) { + if (isEnabled(locator)) { + throw new SeleniumLibraryNonFatalException(String.format("Element %s is enabled.", locator)); + } + } + + @RobotKeyword("Verify the element identified by ``locator`` is selected.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "message=NONE" }) - public void elementShouldBeSelected(String locator, String...params) { + @ArgumentNames({ "locator", "message=NONE" }) + public void elementShouldBeSelected(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); - logging.info(String.format("Verifying element '%s' is selected.", locator)); - boolean selected = isSelected(locator); - - if (!selected) { - if (message == null || message.equals("")) { - message = String.format("Element '%s' should be selected, but it is not.", locator); - } - throw new SeleniumLibraryNonFatalException(message); - } - } - - @RobotKeyword("Verify the element identified by ``locator`` is not selected.\r\n" + + logging.info(String.format("Verifying element '%s' is selected.", locator)); + boolean selected = isSelected(locator); + + if (!selected) { + if (message == null || message.equals("")) { + message = String.format("Element '%s' should be selected, but it is not.", locator); + } + throw new SeleniumLibraryNonFatalException(message); + } + } + + @RobotKeyword("Verify the element identified by ``locator`` is not selected.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "message=NONE" }) - public void elementShouldNotBeSelected(String locator, String...params) { + @ArgumentNames({ "locator", "message=NONE" }) + public void elementShouldNotBeSelected(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); - logging.info(String.format("Verifying element '%s' is not selected.", locator)); - boolean selected = isSelected(locator); - - if (selected) { - if (message == null || message.equals("")) { - message = String.format("Element '%s' should not be selected, but it is.", locator); - } - throw new SeleniumLibraryNonFatalException(message); - } - } - - @RobotKeyword("Verify the element identified by ``locator`` is visible.\r\n" + - "\r\n" + - "Herein, visible means that the element is logically visible, not optically visible in the current browser viewport. For example, an element that carries display:none is not logically visible, so using this keyword on that element would fail.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "message=NONE" }) - public void elementShouldBeVisible(String locator, String...params) { + logging.info(String.format("Verifying element '%s' is not selected.", locator)); + boolean selected = isSelected(locator); + + if (selected) { + if (message == null || message.equals("")) { + message = String.format("Element '%s' should not be selected, but it is.", locator); + } + throw new SeleniumLibraryNonFatalException(message); + } + } + + @RobotKeyword("Verify the element identified by ``locator`` is visible.\r\n" + + "\r\n" + + "Herein, visible means that the element is logically visible, not optically visible in the current browser viewport. For example, an element that carries display:none is not logically visible, so using this keyword on that element would fail.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator", "message=NONE" }) + public void elementShouldBeVisible(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); - logging.info(String.format("Verifying element '%s' is visible.", locator)); - boolean visible = isVisible(locator); + logging.info(String.format("Verifying element '%s' is visible.", locator)); + boolean visible = isVisible(locator); - if (!visible) { - if (message == null || message.equals("")) { - message = String.format("Element '%s' should be visible, but it is not.", locator); - } - throw new SeleniumLibraryNonFatalException(message); - } - } + if (!visible) { + if (message == null || message.equals("")) { + message = String.format("Element '%s' should be visible, but it is not.", locator); + } + throw new SeleniumLibraryNonFatalException(message); + } + } @RobotKeyword("Verify the element identified by ``locator`` is not visible.\r\n" + "\r\n" + "Herein, visible means that the element is logically visible, not optically visible in the current browser viewport. For example, an element that carries display:none is not logically visible, so using this keyword on that element would fail.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "message=NONE" }) - public void elementShouldNotBeVisible(String locator, String...params) { + @ArgumentNames({ "locator", "message=NONE" }) + public void elementShouldNotBeVisible(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); - logging.info(String.format("Verifying element '%s' is not visible.", locator)); - boolean visible = isVisible(locator); + logging.info(String.format("Verifying element '%s' is not visible.", locator)); + boolean visible = isVisible(locator); - if (visible) { - if (message == null || message.equals("")) { - message = String.format("Element '%s' should not be visible, but it is.", locator); - } - throw new SeleniumLibraryNonFatalException(message); - } - } + if (visible) { + if (message == null || message.equals("")) { + message = String.format("Element '%s' should not be visible, but it is.", locator); + } + throw new SeleniumLibraryNonFatalException(message); + } + } @RobotKeyword("Verify the element identified by ``locator`` is clickable.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "message=NONE" }) - public void elementShouldBeClickable(String locator, String...params) { + @ArgumentNames({ "locator", "message=NONE" }) + public void elementShouldBeClickable(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); - logging.info(String.format("Verifying element '%s' is clickable.", locator)); - boolean clickable = isClickable(locator); + logging.info(String.format("Verifying element '%s' is clickable.", locator)); + boolean clickable = isClickable(locator); - if (!clickable) { - if (message == null || message.equals("")) { - message = String.format("Element '%s' should be clickable, but it is not.", locator); - } - throw new SeleniumLibraryNonFatalException(message); - } - } + if (!clickable) { + if (message == null || message.equals("")) { + message = String.format("Element '%s' should be clickable, but it is not.", locator); + } + throw new SeleniumLibraryNonFatalException(message); + } + } @RobotKeyword("Verify the element identified by ``locator`` is not clickable.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "message=NONE" }) - public void elementShouldNotBeClickable(String locator, String...params) { + @ArgumentNames({ "locator", "message=NONE" }) + public void elementShouldNotBeClickable(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); - logging.info(String.format("Verifying element '%s' is not clickable.", locator)); - boolean clickable = isClickable(locator); - - if (clickable) { - if (message == null || message.equals("")) { - message = String.format("Element '%s' should not be clickable, but it is.", locator); - } - throw new SeleniumLibraryNonFatalException(message); - } - } - - @RobotKeyword("Verify the text of the element identified by ``locator`` is exactly ``text``.\r\n" + - "\r\n" + - "In contrast to `Element Should Contain`, this keyword does not try a substring match but an exact match on the element identified by locator.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "text", "message=NONE" }) - public void elementTextShouldBe(String locator, String text, String...params) { + logging.info(String.format("Verifying element '%s' is not clickable.", locator)); + boolean clickable = isClickable(locator); + + if (clickable) { + if (message == null || message.equals("")) { + message = String.format("Element '%s' should not be clickable, but it is.", locator); + } + throw new SeleniumLibraryNonFatalException(message); + } + } + + @RobotKeyword("Verify the text of the element identified by ``locator`` is exactly ``text``.\r\n" + + "\r\n" + + "In contrast to `Element Should Contain`, this keyword does not try a substring match but an exact match on the element identified by locator.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator", "text", "message=NONE", "ignore_case=False" }) + public void elementTextShouldBe(String locator, String text, String...params) { String message = robot.getParamsValue(params, 0, ""); - List elements = elementFind(locator, true, true); - String actual = elements.get(0).getText(); - - if (!text.equals(actual)) { - if (message == null || message.equals("")) { - message = String.format("The text of element '%s' should have been '%s', but it was '%s'.", locator, - text, actual); - } - throw new SeleniumLibraryNonFatalException(message); - } - } + Boolean ignoreCase = robot.getParamsValue(params, 1, Boolean.FALSE); + List elements = elementFind(locator, true, true); + String actual = elements.get(0).getText(); + if (!textIs(actual, text, ignoreCase)) { + if (StringUtils.isEmpty(message)) { + message = String.format("The text of element '%s' should have been '%s', but it was '%s'.", locator, + text, actual); + } + throw new SeleniumLibraryNonFatalException(message); + } + } @RobotKeyword("Verify the text of the element identified by ``locator`` is not exactly ``text``.\r\n" + @@ -393,707 +400,719 @@ public void elementTextShouldBe(String locator, String text, String...params) { "In contrast to `Element Should Not Contain`, this keyword does not try a substring match but an exact match on the element identified by locator.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "text", "message=NONE" }) - public void elementTextShouldNotBe(String locator, String text, String...params) { + @ArgumentNames({ "locator", "text", "message=NONE", "ignore_case=False" }) + public void elementTextShouldNotBe(String locator, String text, String...params) { String message = robot.getParamsValue(params, 0, ""); - List elements = elementFind(locator, true, true); - String actual = elements.get(0).getText(); - - if (text.equals(actual)) { - if (message == null || message.equals("")) { - message = String.format("The text of element '%s' should have been '%s', but it was '%s'.", locator, - text, actual); - } - throw new SeleniumLibraryNonFatalException(message); - } - } - - @RobotKeyword("Returns the value of an element attribute.\r\n" + - "\r\n" + - "The ``attribute_locator`` consists of element locator followed by an @ sign and attribute name. Example: element_id@class\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "attributeLocator" }) - public String getElementAttribute(String attributeLocator) { - String[] parts = parseAttributeLocator(attributeLocator); - - List elements = elementFind(parts[0], true, false); - - if (elements.size() == 0) { - throw new SeleniumLibraryNonFatalException(String.format("Element '%s' not found.", parts[0])); - } - - return elements.get(0).getAttribute(parts[1]); - } - - @RobotKeyword("Clears the text from element identified by ``locator``.\r\n" + - "\r\n" + - "This keyword does not execute any checks on whether or not the clear method has succeeded, so if any subsequent checks are needed, they should be executed using method `Element Text Should Be`.\r\n" + - "\r\n" + - "Also, this method will use WebDriver's internal _element.clear()_ method, i.e. it will not send any keypresses, and it will not have any effect whatsoever on elements other than input textfields or input textareas. Clients relying on keypresses should implement their own methods.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void clearElementText(String locator) { - List elements = elementFind(locator, true, true); - - elements.get(0).clear(); - } - - @RobotKeyword("Returns inner element id by index```` of element identified by ``locator`` which is matched by ``matchid``.\r\n" - + "\r\n" - + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "matchid", "index" }) - public String getInnerElementId(String locator, String matchid, int index) { - List elements = elementFind(locator, true, true); - - if (elements.size() == 0) { - throw new SeleniumLibraryNonFatalException(String.format("get Inner element '%s' not found.", locator)); - } - - String xpathId = ".//*[contains(@id," + matchid + ")]"; - - List tmpe = elements.get(0).findElements((By.xpath(xpathId))); - if (tmpe.size() == 0) { - throw new SeleniumLibraryNonFatalException( - String.format("No Inner element '%s' not found by '%s'", locator, matchid)); - } - String eId = tmpe.get(index).getAttribute("id"); - - logging.info(String.format("Found element ID: '%s'.", eId)); - - return eId; - - } - - @RobotKeyword("Returns horizontal position of element identified by ``locator``.\r\n" + - "\r\n" + - "The position is returned in pixels off the left side of the page, as an integer. Fails if the matching element is not found.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public int getHorizontalPosition(String locator) { - List elements = elementFind(locator, true, false); - - if (elements.size() == 0) { - throw new SeleniumLibraryNonFatalException( - String.format("Could not determine position for '%s'.", locator)); - } - - return elements.get(0).getLocation().getX(); - } + List elements = elementFind(locator, true, true); + Boolean ignoreCase = robot.getParamsValue(params, 1, Boolean.FALSE); + String actual = elements.get(0).getText(); + if (textIs(actual, text, ignoreCase)) { + if (StringUtils.isEmpty(message)) { + message = String.format("The text of element '%s' should have been '%s', but it was '%s'.", locator, + text, actual); + } + throw new SeleniumLibraryNonFatalException(message); + } + } + + @RobotKeyword("Returns the value of an element attribute.\r\n" + + "\r\n" + + "The ``attribute_locator`` consists of element locator followed by an @ sign and attribute name. Example: element_id@class\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "attributeLocator" }) + public String getElementAttribute(String attributeLocator) { + String[] parts = parseAttributeLocator(attributeLocator); + + List elements = elementFind(parts[0], true, false); + + if (elements.size() == 0) { + throw new SeleniumLibraryNonFatalException(String.format("Element '%s' not found.", parts[0])); + } + + return elements.get(0).getAttribute(parts[1]); + } + + @RobotKeyword("Clears the text from element identified by ``locator``.\r\n" + + "\r\n" + + "This keyword does not execute any checks on whether or not the clear method has succeeded, so if any subsequent checks are needed, they should be executed using method `Element Text Should Be`.\r\n" + + "\r\n" + + "Also, this method will use WebDriver's internal _element.clear()_ method, i.e. it will not send any keypresses, and it will not have any effect whatsoever on elements other than input textfields or input textareas. Clients relying on keypresses should implement their own methods.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public void clearElementText(String locator) { + List elements = elementFind(locator, true, true); + + elements.get(0).clear(); + } + + @RobotKeyword("Returns inner element id by index```` of element identified by ``locator`` which is matched by ``matchid``.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator", "matchid", "index" }) + public String getInnerElementId(String locator, String matchid, int index) { + List elements = elementFind(locator, true, true); + + if (elements.size() == 0) { + throw new SeleniumLibraryNonFatalException(String.format("get Inner element '%s' not found.", locator)); + } + + String xpathId = ".//*[contains(@id," + matchid + ")]"; + + List tmpe = elements.get(0).findElements((By.xpath(xpathId))); + if (tmpe.size() == 0) { + throw new SeleniumLibraryNonFatalException( + String.format("No Inner element '%s' not found by '%s'", locator, matchid)); + } + String eId = tmpe.get(index).getAttribute("id"); + + logging.info(String.format("Found element ID: '%s'.", eId)); + + return eId; + + } + + @RobotKeyword("Returns horizontal position of element identified by ``locator``.\r\n" + + "\r\n" + + "The position is returned in pixels off the left side of the page, as an integer. Fails if the matching element is not found.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public int getHorizontalPosition(String locator) { + List elements = elementFind(locator, true, false); + + if (elements.size() == 0) { + throw new SeleniumLibraryNonFatalException( + String.format("Could not determine position for '%s'.", locator)); + } + + return elements.get(0).getLocation().getX(); + } @RobotKeyword("Returns the value attribute of the element identified by ``locator``..\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public String getValue(String locator) { - return getValue(locator, null); - } + @ArgumentNames({ "locator" }) + public String getValue(String locator) { + return getValue(locator, null); + } - protected String getValue(String locator, String tag) { - List elements = elementFind(locator, true, false, tag); + protected String getValue(String locator, String tag) { + List elements = elementFind(locator, true, false, tag); - if (elements.size() == 0) { - return null; - } + if (elements.size() == 0) { + return null; + } - return elements.get(0).getAttribute("value"); - } + return elements.get(0).getAttribute("value"); + } @RobotKeyword("Returns the text of the element identified by ``locator``..\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public String getText(String locator) { - List elements = elementFind(locator, true, true); + @ArgumentNames({ "locator" }) + public String getText(String locator) { + List elements = elementFind(locator, true, true); - if (elements.size() == 0) { - return null; - } + if (elements.size() == 0) { + return null; + } - return elements.get(0).getText(); - } + return elements.get(0).getText(); + } @RobotKeyword("Returns vertical position of element identified by ``locator``.\r\n" + "\r\n" + "The position is returned in pixels off the left side of the page, as an integer. Fails if the matching element is not found.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public int getVerticalPosition(String locator) { - List elements = elementFind(locator, true, false); + @ArgumentNames({ "locator" }) + public int getVerticalPosition(String locator) { + List elements = elementFind(locator, true, false); - if (elements.size() == 0) { - throw new SeleniumLibraryNonFatalException( - String.format("Could not determine position for '%s'.", locator)); - } + if (elements.size() == 0) { + throw new SeleniumLibraryNonFatalException( + String.format("Could not determine position for '%s'.", locator)); + } - return elements.get(0).getLocation().getY(); - } + return elements.get(0).getLocation().getY(); + } - // ############################## - // Keywords - Mouse Input/Events - // ############################## + // ############################## + // Keywords - Mouse Input/Events + // ############################## @RobotKeyword("Click on the element identified by ``locator``.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void clickElement(String locator) { - logging.info(String.format("Clicking element '%s'.", locator)); - List elements = elementFind(locator, true, true); + @ArgumentNames({ "locator" }) + public void clickElement(String locator) { + logging.info(String.format("Clicking element '%s'.", locator)); + List elements = elementFind(locator, true, true); - elements.get(0).click(); - } + elements.get(0).click(); + } @RobotKeyword("Click on the element identified by locator at the coordinates ``xOffset`` and ``yOffset``.\r\n" + "\r\n" + "The cursor is moved at the center of the element and the to the given x/y offset from that point. Both offsets are specified as negative (left/up) or positive (right/down) number.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "xOffset", "yOffset" }) - public void clickElementAtCoordinates(String locator, String xOffset, String yOffset) { - logging.info(String.format("Clicking element '%s'in coordinates '%s', '%s'.", locator, xOffset, yOffset)); - List elements = elementFind(locator, true, true); + @ArgumentNames({ "locator", "xOffset", "yOffset" }) + public void clickElementAtCoordinates(String locator, String xOffset, String yOffset) { + logging.info(String.format("Clicking element '%s'in coordinates '%s', '%s'.", locator, xOffset, yOffset)); + List elements = elementFind(locator, true, true); - WebElement element = elements.get(0); - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.moveToElement(element).moveByOffset(Integer.parseInt(xOffset), Integer.parseInt(yOffset)).perform(); - } + WebElement element = elements.get(0); + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.moveToElement(element).moveByOffset(Integer.parseInt(xOffset), Integer.parseInt(yOffset)).perform(); + } @RobotKeyword("Double-Click on the element identified by ``locator``.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void doubleClickElement(String locator) { - logging.info(String.format("Double clicking element '%s'.", locator)); + @ArgumentNames({ "locator" }) + public void doubleClickElement(String locator) { + logging.info(String.format("Double clicking element '%s'.", locator)); - List elements = elementFind(locator, true, true); - Actions action = new Actions(browserManagement.getCurrentWebDriver()); + List elements = elementFind(locator, true, true); + Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.doubleClick(elements.get(0)).perform(); - } + action.doubleClick(elements.get(0)).perform(); + } @RobotKeyword("Set the focus to the element identified by ``locator``.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void focus(String locator) { - List elements = elementFind(locator, true, true); - ((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeScript("arguments[0].focus();", - elements.get(0)); - } - - @RobotKeyword("Drag the element identified by the locator ``source`` and move it on top of the element identified by the locator ``target``.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.\r\n" + - "\r\n" + - "Example:\r\n" + - " | Drag And Drop | elem1 | elem2 | # Move elem1 over elem2 |") - @ArgumentNames({ "source", "target" }) - public void dragAndDrop(String source, String target) { - List sourceElements = elementFind(source, true, true); - List targetElements = elementFind(target, true, true); - - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.dragAndDrop(sourceElements.get(0), targetElements.get(0)).perform(); - } - - @RobotKeyword("Drag the element identified by the locator ``source`` and move it on top of the element identified by the locator ``target``.\r\n" + - "\r\n" + - "Both offsets are specified as negative (left/up) or positive (right/down) number.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.\r\n" + - "\r\n" + - "Example:\r\n" + - " | Drag And Drop By Offset | elem1 | 50 | 35 | # Move elem1 50px right and 35px down. |") - @ArgumentNames({ "source", "xOffset", "yOffset" }) - public void dragAndDropByOffset(String source, int xOffset, int yOffset) { - List elements = elementFind(source, true, true); - - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.dragAndDropBy(elements.get(0), xOffset, yOffset).perform(); - } - - @RobotKeyword("Simulates pressing the left mouse button on the element identified by ``locator``.\r\n" + - "\r\n" + - "The element is pressed without releasing the mouse button.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void mouseDown(String locator) { - logging.info(String.format("Simulating Mouse Down on element '%s'.", locator)); - List elements = elementFind(locator, true, false); - - if (elements.size() == 0) { - throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s not found.", locator)); - } - - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.clickAndHold(elements.get(0)).perform(); - } + @ArgumentNames({ "locator" }) + public void focus(String locator) { + List elements = elementFind(locator, true, true); + ((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeScript("arguments[0].focus();", + elements.get(0)); + } + + @RobotKeyword("Drag the element identified by the locator ``source`` and move it on top of the element identified by the locator ``target``.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.\r\n" + + "\r\n" + + "Example:\r\n" + + " | Drag And Drop | elem1 | elem2 | # Move elem1 over elem2 |") + @ArgumentNames({ "source", "target" }) + public void dragAndDrop(String source, String target) { + List sourceElements = elementFind(source, true, true); + List targetElements = elementFind(target, true, true); + + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.dragAndDrop(sourceElements.get(0), targetElements.get(0)).perform(); + } + + @RobotKeyword("Drag the element identified by the locator ``source`` and move it on top of the element identified by the locator ``target``.\r\n" + + "\r\n" + + "Both offsets are specified as negative (left/up) or positive (right/down) number.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.\r\n" + + "\r\n" + + "Example:\r\n" + + " | Drag And Drop By Offset | elem1 | 50 | 35 | # Move elem1 50px right and 35px down. |") + @ArgumentNames({ "source", "xOffset", "yOffset" }) + public void dragAndDropByOffset(String source, int xOffset, int yOffset) { + List elements = elementFind(source, true, true); + + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.dragAndDropBy(elements.get(0), xOffset, yOffset).perform(); + } + + @RobotKeyword("Simulates pressing the left mouse button on the element identified by ``locator``.\r\n" + + "\r\n" + + "The element is pressed without releasing the mouse button.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public void mouseDown(String locator) { + logging.info(String.format("Simulating Mouse Down on element '%s'.", locator)); + List elements = elementFind(locator, true, false); + + if (elements.size() == 0) { + throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s not found.", locator)); + } + + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.clickAndHold(elements.get(0)).perform(); + } @RobotKeyword("Simulates moving the mouse away from the element identified by ``locator``.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void mouseOut(String locator) { - logging.info(String.format("Simulating Mouse Out on element '%s'.", locator)); - List elements = elementFind(locator, true, false); - - if (elements.size() == 0) { - throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s not found.", locator)); - } - - WebElement element = elements.get(0); - Dimension size = element.getSize(); - int offsetX = size.getWidth() / 2 + 1; - int offsetY = size.getHeight() / 2 + 1; - - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.moveToElement(element).moveByOffset(offsetX, offsetY).perform(); - } - - @RobotKeyword("Simulates moving the mouse over the element identified by ``locator``.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void mouseOver(String locator) { - logging.info(String.format("Simulating Mouse Over on element '%s'.", locator)); - List elements = elementFind(locator, true, false); - - if (elements.size() == 0) { - throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s not found.", locator)); - } - - WebElement element = elements.get(0); - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.moveToElement(element).perform(); - } - - @RobotKeyword("Simulates releasing the left mouse button on the element identified by ``locator``.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void mouseUp(String locator) { - logging.info(String.format("Simulating Mouse Up on element '%s'.", locator)); - List elements = elementFind(locator, true, false); - - if (elements.size() == 0) { - throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s not found.", locator)); - } - - WebElement element = elements.get(0); - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.release(element).perform(); - } - - @RobotKeyword("Opens the context menu on the element identified by ``locator``.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void openContextMenu(String locator) { - List elements = elementFind(locator, true, true); - - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.contextClick(elements.get(0)).perform(); - } - - @RobotKeyword("Simulates the given ``event`` on the element identified by ``locator``.\r\n" + - "\r\n" + - "This keyword is especially useful, when the element has an OnEvent handler that needs to be explicitly invoked.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") - @ArgumentNames({ "locator", "event" }) - public void simulate(String locator, String event) { - List elements = elementFind(locator, true, true); - String script = "element = arguments[0];" + "eventName = arguments[1];" + "if (document.createEventObject) {" - + "return element.fireEvent('on' + eventName, document.createEventObject());" + "}" - + "var evt = document.createEvent(\"HTMLEvents\");" + "evt.initEvent(eventName, true, true);" - + "return !element.dispatchEvent(evt);"; - - ((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeScript(script, elements.get(0), event); - } - - @RobotKeyword("Simulates pressing key on the element identified by ``locator``.\r\n" + - "\r\n" + - "Key is either a single character, or a numerical ASCII code of the key lead by '\\\\'.\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.\r\n" + - "\r\n" + - "Example:\r\n" + - " | Press Key | text_field | q | # Press 'q' | \r\n" + - " | Press Key | login_button | \\\\13 | # ASCII code for enter key |") - @ArgumentNames({ "locator", "key" }) - public void pressKey(String locator, String key) { - if (key.startsWith("\\") && key.length() > 1) { - key = mapAsciiKeyCodeToKey(Integer.parseInt(key.substring(1))).toString(); - } - List element = elementFind(locator, true, true); - element.get(0).sendKeys(key); - } - - // ############################## - // Keywords - Links - // ############################## - - - @RobotKeyword("Click on the link identified by ``locator``.\r\n" + - "\r\n" + - "Key attributes for links are id, name, href and link text. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void clickLink(String locator) { - logging.info(String.format("Clicking link '%s'.", locator)); - List elements = elementFind(locator, true, true, "a"); - - elements.get(0).click(); - } - - @RobotKeyword("Returns a list containing ids of all links found in current page.\r\n" + - "\r\n" + - "If a link has no id, an empty string will be in the list instead.") - public ArrayList getAllLinks() { - ArrayList ret = new ArrayList(); - - List elements = elementFind("tag:a", false, false, "a"); - for (WebElement element : elements) { - ret.add(element.getAttribute("id")); - } - - return ret; - } - - @RobotKeyword("Simulates pressing the left mouse button on the link identified by ``locator``.\r\n" + - "\r\n" + - "The element is pressed without releasing the mouse button.\r\n" + - "\r\n" + - "Key attributes for links are id, name, href and link text. See `Introduction` for details about locators.\r\n" + - "\r\n") - @ArgumentNames({ "locator" }) - public void mouseDownOnLink(String locator) { - List elements = elementFind(locator, true, true, "link"); - - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.clickAndHold(elements.get(0)).perform(); - } - - @RobotKeyword("Verify the link identified by ``locator`` is found on the current page.\r\n" + - "\r\n" + - "Key attributes for links are id, name, href and link text. See `Introduction` for details about log levels and locators.") - @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) - public void pageShouldContainLink(String locator, String...params) { + @ArgumentNames({ "locator" }) + public void mouseOut(String locator) { + logging.info(String.format("Simulating Mouse Out on element '%s'.", locator)); + List elements = elementFind(locator, true, false); + + if (elements.size() == 0) { + throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s not found.", locator)); + } + + WebElement element = elements.get(0); + Dimension size = element.getSize(); + int offsetX = size.getWidth() / 2 + 1; + int offsetY = size.getHeight() / 2 + 1; + + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.moveToElement(element).moveByOffset(offsetX, offsetY).perform(); + } + + @RobotKeyword("Simulates moving the mouse over the element identified by ``locator``.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public void mouseOver(String locator) { + logging.info(String.format("Simulating Mouse Over on element '%s'.", locator)); + List elements = elementFind(locator, true, false); + + if (elements.size() == 0) { + throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s not found.", locator)); + } + + WebElement element = elements.get(0); + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.moveToElement(element).perform(); + } + + @RobotKeyword("Simulates releasing the left mouse button on the element identified by ``locator``.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public void mouseUp(String locator) { + logging.info(String.format("Simulating Mouse Up on element '%s'.", locator)); + List elements = elementFind(locator, true, false); + + if (elements.size() == 0) { + throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s not found.", locator)); + } + + WebElement element = elements.get(0); + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.release(element).perform(); + } + + @RobotKeyword("Opens the context menu on the element identified by ``locator``.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public void openContextMenu(String locator) { + List elements = elementFind(locator, true, true); + + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.contextClick(elements.get(0)).perform(); + } + + @RobotKeyword("Simulates the given ``event`` on the element identified by ``locator``.\r\n" + + "\r\n" + + "This keyword is especially useful, when the element has an OnEvent handler that needs to be explicitly invoked.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator", "event" }) + public void simulate(String locator, String event) { + List elements = elementFind(locator, true, true); + String script = "element = arguments[0];" + "eventName = arguments[1];" + "if (document.createEventObject) {" + + "return element.fireEvent('on' + eventName, document.createEventObject());" + "}" + + "var evt = document.createEvent(\"HTMLEvents\");" + "evt.initEvent(eventName, true, true);" + + "return !element.dispatchEvent(evt);"; + + ((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeScript(script, elements.get(0), event); + } + + @RobotKeyword("Simulates pressing key on the element identified by ``locator``.\r\n" + + "\r\n" + + "Key is either a single character, or a numerical ASCII code of the key lead by '\\\\'.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.\r\n" + + "\r\n" + + "Example:\r\n" + + " | Press Key | text_field | q | # Press 'q' | \r\n" + + " | Press Key | login_button | \\\\13 | # ASCII code for enter key |") + @ArgumentNames({ "locator", "key" }) + public void pressKey(String locator, String key) { + if (key.startsWith("\\") && key.length() > 1) { + key = mapAsciiKeyCodeToKey(Integer.parseInt(key.substring(1))).toString(); + } + List element = elementFind(locator, true, true); + element.get(0).sendKeys(key); + } + + // ############################## + // Keywords - Links + // ############################## + + + @RobotKeyword("Click on the link identified by ``locator``.\r\n" + + "\r\n" + + "Key attributes for links are id, name, href and link text. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public void clickLink(String locator) { + logging.info(String.format("Clicking link '%s'.", locator)); + List elements = elementFind(locator, true, true, "a"); + + elements.get(0).click(); + } + + @RobotKeyword("Returns a list containing ids of all links found in current page.\r\n" + + "\r\n" + + "If a link has no id, an empty string will be in the list instead.") + public ArrayList getAllLinks() { + ArrayList ret = new ArrayList(); + + List elements = elementFind("tag:a", false, false, "a"); + for (WebElement element : elements) { + ret.add(element.getAttribute("id")); + } + + return ret; + } + + @RobotKeyword("Simulates pressing the left mouse button on the link identified by ``locator``.\r\n" + + "\r\n" + + "The element is pressed without releasing the mouse button.\r\n" + + "\r\n" + + "Key attributes for links are id, name, href and link text. See `Introduction` for details about locators.\r\n" + + "\r\n") + @ArgumentNames({ "locator" }) + public void mouseDownOnLink(String locator) { + List elements = elementFind(locator, true, true, "link"); + + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.clickAndHold(elements.get(0)).perform(); + } + + @RobotKeyword("Verify the link identified by ``locator`` is found on the current page.\r\n" + + "\r\n" + + "Key attributes for links are id, name, href and link text. See `Introduction` for details about log levels and locators.") + @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) + public void pageShouldContainLink(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); String logLevel = robot.getParamsValue(params, 1, "INFO"); - pageShouldContainElement(locator, "link", message, logLevel); - } - - @RobotKeyword("Verify the link identified by ``locator`` is not found on the current page.\r\n" + - "\r\n" + - "Key attributes for links are id, name, href and link text. See `Introduction` for details about log levels and locators.") - @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) - public void pageShouldNotContainLink(String locator, String...params) { + pageShouldContainElement(locator, "link", message, logLevel); + } + + @RobotKeyword("Verify the link identified by ``locator`` is not found on the current page.\r\n" + + "\r\n" + + "Key attributes for links are id, name, href and link text. See `Introduction` for details about log levels and locators.") + @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) + public void pageShouldNotContainLink(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); String logLevel = robot.getParamsValue(params, 1, "INFO"); - pageShouldNotContainElement(locator, "link", message, logLevel); - } - - // ############################## - // Keywords - Images - // ############################## - - @RobotKeyword("Click on the image identified by ``locator``.\r\n" + - "\r\n" + - "Key attributes for images are id, src and alt. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void clickImage(String locator) { - logging.info(String.format("Clicking image '%s'.", locator)); - - List elements = elementFind(locator, true, false, "image"); - - if (elements.size() == 0) { - elements = elementFind(locator, true, true, "input"); - } - WebElement element = elements.get(0); - element.click(); - } - - @RobotKeyword("Simulates pressing the left mouse button on the image identified by ``locator``.\r\n" + - "\r\n" + - "The element is pressed without releasing the mouse button.\r\n" + - "\r\n" + - "Key attributes for images are id, src and alt. See `Introduction` for details about locators.") - @ArgumentNames({ "locator" }) - public void mouseDownOnImage(String locator) { - List elements = elementFind(locator, true, true, "image"); - - Actions action = new Actions(browserManagement.getCurrentWebDriver()); - action.clickAndHold(elements.get(0)).perform(); - } - - @RobotKeyword("Verify the image identified by ``locator`` is found on the current page.\r\n" + - "\r\n" + - "Key attributes for images are id, src and alt. See `Introduction` for details about log levels and locators.") - @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) - public void pageShouldContainImage(String locator, String...params) { + pageShouldNotContainElement(locator, "link", message, logLevel); + } + + // ############################## + // Keywords - Images + // ############################## + + @RobotKeyword("Click on the image identified by ``locator``.\r\n" + + "\r\n" + + "Key attributes for images are id, src and alt. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public void clickImage(String locator) { + logging.info(String.format("Clicking image '%s'.", locator)); + + List elements = elementFind(locator, true, false, "image"); + + if (elements.size() == 0) { + elements = elementFind(locator, true, true, "input"); + } + WebElement element = elements.get(0); + element.click(); + } + + @RobotKeyword("Simulates pressing the left mouse button on the image identified by ``locator``.\r\n" + + "\r\n" + + "The element is pressed without releasing the mouse button.\r\n" + + "\r\n" + + "Key attributes for images are id, src and alt. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public void mouseDownOnImage(String locator) { + List elements = elementFind(locator, true, true, "image"); + + Actions action = new Actions(browserManagement.getCurrentWebDriver()); + action.clickAndHold(elements.get(0)).perform(); + } + + @RobotKeyword("Verify the image identified by ``locator`` is found on the current page.\r\n" + + "\r\n" + + "Key attributes for images are id, src and alt. See `Introduction` for details about log levels and locators.") + @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) + public void pageShouldContainImage(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); String logLevel = robot.getParamsValue(params, 1, "INFO"); - pageShouldContainElement(locator, "image", message, logLevel); - } - - @RobotKeyword("Verify the image identified by ``locator`` is not found on the current page.\r\n" + - "\r\n" + - "Key attributes for images are id, src and alt. See `Introduction` for details about log levels and locators.") - @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) - public void pageShouldNotContainImage(String locator, String...params) { + pageShouldContainElement(locator, "image", message, logLevel); + } + + @RobotKeyword("Verify the image identified by ``locator`` is not found on the current page.\r\n" + + "\r\n" + + "Key attributes for images are id, src and alt. See `Introduction` for details about log levels and locators.") + @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" }) + public void pageShouldNotContainImage(String locator, String...params) { String message = robot.getParamsValue(params, 0, ""); String logLevel = robot.getParamsValue(params, 1, "INFO"); - pageShouldNotContainElement(locator, "image", message, logLevel); - } - - // ############################## - // Keywords - Xpath - // ############################## - - @RobotKeyword("Returns the number of elements located the given ``xpath``.\r\n" + - " \r\n" + - "If you wish to assert the number of located elements, use `Xpath Should Match X Times`.") - @ArgumentNames({ "xpath" }) - public int getMatchingXpathCount(String xpath) { - if (!xpath.startsWith("xpath=") && !xpath.startsWith("xpath:")) { - xpath = "xpath:" + xpath; - } - List elements = elementFind(xpath, false, false); - - return elements.size(); - } - - @RobotKeyword("Verify that the page contains the ``expectedXpathCount`` of elements located by the given ``xpath``.") - @ArgumentNames({ "xpath", "expectedXpathCount", "message=NONE", "logLevel=INFO" }) - public void xpathShouldMatchXTimes(String xpath, int expectedXpathCount, String...params) { + pageShouldNotContainElement(locator, "image", message, logLevel); + } + + // ############################## + // Keywords - Xpath + // ############################## + + @RobotKeyword("Returns the number of elements located the given ``xpath``.\r\n" + + " \r\n" + + "If you wish to assert the number of located elements, use `Xpath Should Match X Times`.") + @ArgumentNames({ "xpath" }) + public int getMatchingXpathCount(String xpath) { + if (!xpath.startsWith("xpath=") && !xpath.startsWith("xpath:")) { + xpath = "xpath:" + xpath; + } + List elements = elementFind(xpath, false, false); + + return elements.size(); + } + + @RobotKeyword("Verify that the page contains the ``expectedXpathCount`` of elements located by the given ``xpath``.") + @ArgumentNames({ "xpath", "expectedXpathCount", "message=NONE", "logLevel=INFO" }) + public void xpathShouldMatchXTimes(String xpath, int expectedXpathCount, String...params) { String message = robot.getParamsValue(params, 0, ""); String logLevel = robot.getParamsValue(params, 1, "INFO"); - if (!xpath.startsWith("xpath=") && !xpath.startsWith("xpath:")) { - xpath = "xpath:" + xpath; - } - List elements = elementFind(xpath, false, false); - int actualXpathCount = elements.size(); - - if (actualXpathCount != expectedXpathCount) { - if (message.isEmpty()) { - message = String.format("Xpath %s should have matched %s times but matched %s times.", xpath, - expectedXpathCount, actualXpathCount); - } - throw new SeleniumLibraryNonFatalException(message); - } - - logging.log(String.format("Current page contains %s elements matching '%s'.", actualXpathCount, xpath), - logLevel); - } - - @RobotKeyword("Click to element from list elements by locator ``xpath``.") - @ArgumentNames({"xpath", "index=0", "message=NONE"}) - public void clickElementByIndex(String xpath, String... params) { - String message = robot.getParamsValue(params, 0, ""); - int index = robot.getParamsValue(params, 1, 0); - List elements = elementFind(xpath, false, false); - if (elements.isEmpty()) { - if (message.isEmpty()) { - message = String.format("The Element was not found by locator '%s' with index '%d'", xpath, index); - } - throw new SeleniumLibraryNonFatalException(message); - } - WebElement element = elements.get(index); - element.click(); - } - - // ############################## - // Internal Methods - // ############################## - - protected List elementFind(String locator, boolean firstOnly, boolean required) { - return elementFind(locator, firstOnly, required, null); - } - - protected List elementFind(String locator, boolean firstOnly, boolean required, String tag) { - List elements = ElementFinder.find(browserManagement.getCurrentWebDriver(), locator, tag); - - if (required && elements.size() == 0) { - throw new SeleniumLibraryNonFatalException( - String.format("Element locator '%s' did not match any elements.", locator)); - } - - if (firstOnly) { - if (elements.size() > 1) { - List tmp = new ArrayList(); - tmp.add(elements.get(0)); - elements = tmp; - } - } - - return elements; - } - - protected boolean frameContains(String locator, String text) { - WebDriver current = browserManagement.getCurrentWebDriver(); - List elements = elementFind(locator, true, true); - - current.switchTo().frame(elements.get(0)); - logging.info(String.format("Searching for text from frame '%s'.", locator)); - boolean found = isTextPresent(text); - current.switchTo().defaultContent(); - - return found; - } - - protected boolean isTextPresent(String text) { - String locator = String.format("xpath://*[contains(., %s)]", escapeXpathValue(text)); - - return isElementPresent(locator); - } - - protected boolean isEnabled(String locator) { - List elements = elementFind(locator, true, true); - WebElement element = elements.get(0); - - if (!formElement.isFormElement(element)) { - throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s is not an input.", locator)); - } - if (!element.isEnabled()) { - return false; - } - String readonly = element.getAttribute("readonly"); - if (readonly != null && (readonly.equals("readonly") || readonly.equals("true"))) { - return false; - } - - return true; - } - - protected boolean isVisible(String locator) { - List elements = elementFind(locator, true, false); - if (elements.size() == 0) { - return false; - } - WebElement element = elements.get(0); - return element.isDisplayed(); - } - - protected boolean isClickable(String locator) { - List webElements = elementFind(locator, true, false); - if (webElements.size() == 0) { - return false; - } - WebElement element = webElements.get(0); - return element.isDisplayed() && element.isEnabled(); - } - - protected boolean isSelected(String locator) { - List webElements = elementFind(locator, true, false); - if (webElements.size() == 0) { - return false; - } - WebElement element = webElements.get(0); - return element.isSelected(); - } - - protected String[] parseAttributeLocator(String attributeLocator) { - int index = attributeLocator.lastIndexOf('@'); - if (index <= 0) { - throw new SeleniumLibraryNonFatalException( - String.format("Attribute locator '%s' does not contain an element locator.", attributeLocator)); - } - if (index + 1 == attributeLocator.length()) { - throw new SeleniumLibraryNonFatalException( - String.format("Attribute locator '%s' does not contain an attribute name.", attributeLocator)); - } - String[] parts = new String[2]; - parts[0] = attributeLocator.substring(0, index); - parts[1] = attributeLocator.substring(index + 1); - - return parts; - } - - protected boolean isElementPresent(String locator) { - return isElementPresent(locator, null); - } - - protected boolean isElementPresent(String locator, String tag) { - return elementFind(locator, true, false, tag).size() != 0; - } - - protected boolean pageContains(String text) { - WebDriver current = browserManagement.getCurrentWebDriver(); - current.switchTo().defaultContent(); - - if (isTextPresent(text)) { - return true; - } - - List elements = elementFind("xpath://frame|//iframe", false, false); - Iterator it = elements.iterator(); - while (it.hasNext()) { - current.switchTo().frame(it.next()); - boolean found = isTextPresent(text); - current.switchTo().defaultContent(); - if (found) { - return true; - } - } - - return false; - } - - protected CharSequence mapAsciiKeyCodeToKey(int keyCode) { - switch (keyCode) { - case 0: - return Keys.NULL; - case 8: - return Keys.BACK_SPACE; - case 9: - return Keys.TAB; - case 10: - return Keys.RETURN; - case 13: - return Keys.ENTER; - case 24: - return Keys.CANCEL; - case 27: - return Keys.ESCAPE; - case 32: - return Keys.SPACE; - case 42: - return Keys.MULTIPLY; - case 43: - return Keys.ADD; - case 44: - return Keys.SEPARATOR; - case 45: - return Keys.SUBTRACT; - case 56: - return Keys.DECIMAL; - case 57: - return Keys.DIVIDE; - case 59: - return Keys.SEMICOLON; - case 61: - return Keys.EQUALS; - case 127: - return Keys.DELETE; - default: - return new StringBuffer((char) keyCode); - } - } - - public static String escapeXpathValue(String value) { - if (value.contains("\"") && value.contains("'")) { - String[] partsWoApos = value.split("'"); - return String.format("concat('%s')", Python.join("', \"'\", '", Arrays.asList(partsWoApos))); - } - if (value.contains("'")) { - return String.format("\"%s\"", value); - } - return String.format("'%s'", value); - } + if (!xpath.startsWith("xpath=") && !xpath.startsWith("xpath:")) { + xpath = "xpath:" + xpath; + } + List elements = elementFind(xpath, false, false); + int actualXpathCount = elements.size(); + + if (actualXpathCount != expectedXpathCount) { + if (message.isEmpty()) { + message = String.format("Xpath %s should have matched %s times but matched %s times.", xpath, + expectedXpathCount, actualXpathCount); + } + throw new SeleniumLibraryNonFatalException(message); + } + + logging.log(String.format("Current page contains %s elements matching '%s'.", actualXpathCount, xpath), + logLevel); + } + + @RobotKeyword("Click to element from list elements by locator ``xpath``.") + @ArgumentNames({"xpath", "index=0", "message=NONE"}) + public void clickElementByIndex(String xpath, String... params) { + String message = robot.getParamsValue(params, 0, ""); + int index = robot.getParamsValue(params, 1, 0); + List elements = elementFind(xpath, false, false); + if (elements.isEmpty()) { + if (message.isEmpty()) { + message = String.format("The Element was not found by locator '%s' with index '%d'", xpath, index); + } + throw new SeleniumLibraryNonFatalException(message); + } + WebElement element = elements.get(index); + element.click(); + } + + // ############################## + // Internal Methods + // ############################## + + protected List elementFind(String locator, boolean firstOnly, boolean required) { + return elementFind(locator, firstOnly, required, null); + } + + protected List elementFind(String locator, boolean firstOnly, boolean required, String tag) { + List elements = ElementFinder.find(browserManagement.getCurrentWebDriver(), locator, tag); + + if (required && elements.size() == 0) { + throw new SeleniumLibraryNonFatalException( + String.format("Element locator '%s' did not match any elements.", locator)); + } + + if (firstOnly) { + if (elements.size() > 1) { + List tmp = new ArrayList(); + tmp.add(elements.get(0)); + elements = tmp; + } + } + + return elements; + } + + protected boolean frameContains(String locator, String text) { + WebDriver current = browserManagement.getCurrentWebDriver(); + List elements = elementFind(locator, true, true); + + current.switchTo().frame(elements.get(0)); + logging.info(String.format("Searching for text from frame '%s'.", locator)); + boolean found = isTextPresent(text); + current.switchTo().defaultContent(); + + return found; + } + + protected boolean isTextPresent(String text) { + String locator = String.format("xpath://*[contains(., %s)]", escapeXpathValue(text)); + + return isElementPresent(locator); + } + + protected boolean isEnabled(String locator) { + List elements = elementFind(locator, true, true); + WebElement element = elements.get(0); + + if (!formElement.isFormElement(element)) { + throw new SeleniumLibraryNonFatalException(String.format("ERROR: Element %s is not an input.", locator)); + } + if (!element.isEnabled()) { + return false; + } + String readonly = element.getAttribute("readonly"); + if (readonly != null && (readonly.equals("readonly") || readonly.equals("true"))) { + return false; + } + + return true; + } + + protected boolean isVisible(String locator) { + List elements = elementFind(locator, true, false); + if (elements.size() == 0) { + return false; + } + WebElement element = elements.get(0); + return element.isDisplayed(); + } + + protected boolean isClickable(String locator) { + List webElements = elementFind(locator, true, false); + if (webElements.size() == 0) { + return false; + } + WebElement element = webElements.get(0); + return element.isDisplayed() && element.isEnabled(); + } + + protected boolean isSelected(String locator) { + List webElements = elementFind(locator, true, false); + if (webElements.size() == 0) { + return false; + } + WebElement element = webElements.get(0); + return element.isSelected(); + } + + protected String[] parseAttributeLocator(String attributeLocator) { + int index = attributeLocator.lastIndexOf('@'); + if (index <= 0) { + throw new SeleniumLibraryNonFatalException( + String.format("Attribute locator '%s' does not contain an element locator.", attributeLocator)); + } + if (index + 1 == attributeLocator.length()) { + throw new SeleniumLibraryNonFatalException( + String.format("Attribute locator '%s' does not contain an attribute name.", attributeLocator)); + } + String[] parts = new String[2]; + parts[0] = attributeLocator.substring(0, index); + parts[1] = attributeLocator.substring(index + 1); + + return parts; + } + + protected boolean isElementPresent(String locator) { + return isElementPresent(locator, null); + } + + protected boolean isElementPresent(String locator, String tag) { + return elementFind(locator, true, false, tag).size() != 0; + } + + protected boolean pageContains(String text) { + WebDriver current = browserManagement.getCurrentWebDriver(); + current.switchTo().defaultContent(); + + if (isTextPresent(text)) { + return true; + } + + List elements = elementFind("xpath://frame|//iframe", false, false); + Iterator it = elements.iterator(); + while (it.hasNext()) { + current.switchTo().frame(it.next()); + boolean found = isTextPresent(text); + current.switchTo().defaultContent(); + if (found) { + return true; + } + } + + return false; + } + + protected CharSequence mapAsciiKeyCodeToKey(int keyCode) { + switch (keyCode) { + case 0: + return Keys.NULL; + case 8: + return Keys.BACK_SPACE; + case 9: + return Keys.TAB; + case 10: + return Keys.RETURN; + case 13: + return Keys.ENTER; + case 24: + return Keys.CANCEL; + case 27: + return Keys.ESCAPE; + case 32: + return Keys.SPACE; + case 42: + return Keys.MULTIPLY; + case 43: + return Keys.ADD; + case 44: + return Keys.SEPARATOR; + case 45: + return Keys.SUBTRACT; + case 56: + return Keys.DECIMAL; + case 57: + return Keys.DIVIDE; + case 59: + return Keys.SEMICOLON; + case 61: + return Keys.EQUALS; + case 127: + return Keys.DELETE; + default: + return new StringBuffer((char) keyCode); + } + } + + public static String escapeXpathValue(String value) { + if (value.contains("\"") && value.contains("'")) { + String[] partsWoApos = value.split("'"); + return String.format("concat('%s')", Python.join("', \"'\", '", Arrays.asList(partsWoApos))); + } + if (value.contains("'")) { + return String.format("\"%s\"", value); + } + return String.format("'%s'", value); + } + + private boolean textContains(String actual, String text, boolean ignoreCase) { + return ignoreCase + ? StringUtils.containsIgnoreCase(actual, text) + : StringUtils.contains(actual, text); + } + + private boolean textIs(String actual, String text, boolean ignoreCase) { + return ignoreCase + ? StringUtils.equalsIgnoreCase(actual, text) + : StringUtils.equals(actual, text); + } } From 65942affa8ce70c28502d930a09fa1d60807e3c8 Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Tue, 9 Jul 2019 11:15:28 +0300 Subject: [PATCH 02/23] Replaced Maven plugin for webdriver download with WebdriverManager (thanks to @YauheniPo) Suite setup to handle download in a way that tests doesn't need to be changed --- .gitignore | 3 +- README.md | 32 +++++- pom.xml | 103 +----------------- .../robotframework/settings/Settings.robot | 1 + .../testsuites/UnitTests/__init__.robot | 7 ++ 5 files changed, 46 insertions(+), 100 deletions(-) create mode 100644 src/test/robotframework/testsuites/UnitTests/__init__.robot diff --git a/.gitignore b/.gitignore index d6944f9..0b0dee8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .settings .classpath target -webdriver \ No newline at end of file +webdriver +/libspecs/ diff --git a/README.md b/README.md index 90c4e28..7b14403 100644 --- a/README.md +++ b/README.md @@ -59,11 +59,36 @@ which contains all required libraries. Running of tests with this can be done wi [Library Specs](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.26/robotframework-seleniumlibrary-3.141.59.26.xml) and place it in your PYTHONPATH. +Usage, Selenium 4 (WIP) +----------------- + +If you are using the robotframework-maven-plugin you can +use this library by adding the following dependency to +your pom.xml: + + + com.github.hi-fi + robotframework-seleniumlibrary + 4.0.0-alpha-1.0 + test + + +If you cannot use the robotframework-maven-plugin you can use the +[jar-with-dependencies](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/4.0.0-alpha-1.0/robotframework-seleniumlibrary-4.0.0-alpha-1.0-jar-with-dependencies.jar), +which contains all required libraries. Running of tests with this can be done with command `java -jar robotframework-seleniumlibrary-4.0.0-alpha-1.0-jar-with-dependencies.jar `. + +* More information about this library can be found in the + [Keyword Documentation](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/4.0.0-alpha-1.0/robotframework-seleniumlibrary-4.0.0-alpha-1.0.html). +* For keyword completion in RIDE you can download this + [Library Specs](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/4.0.0-alpha-1.0/robotframework-seleniumlibrary-4.0.0-alpha-1.0.xml) + and place it in your PYTHONPATH. + Differences ----------- * Some keyword differences between this and [Python version](https://github.com/robotframework/SeleniumLibrary) exists. (Same) keywords should be aligned in upcoming versions. -* Older version of the library was imported as `Library Selenium2Library` (both Java and Python versions). Since 2.53.1.1 (and all 3.x versions) import is done as `Library SeleniumLibrary` +* Older version of the library was imported as `Library Selenium2Library` (both Java and Python versions). +Since 2.53.1.1 (and later major versions) import is done as `Library SeleniumLibrary` Browser drivers @@ -86,6 +111,8 @@ to know when to update drivers you use. Drivers can also be fetched with [https://github.com/Ardesco/selenium-standalone-server-plugin|Selenium Driver Binary Downloader plugin]. +With Selenium 4 [https://github.com/bonigarcia/webdrivermanager|WebdriverManager] is taken to use, so handling of drivers can also be done with standalone JAR from tests itself. + __ https://seleniumhq.github.io/selenium/docs/api/py/index.html#drivers __ https://en.wikipedia.org/wiki/PATH_(variable) @@ -96,7 +123,8 @@ This is a maven project. You can execute the integration tests (using [jBrowser] mvn integration-test -Other browsers are behind profiles (require browser installation with Firefox and Google Chrome, but not driver): +Other browsers are behind profiles +(require browser installation with Firefox and Google Chrome, but not driver. Driver downloaded directly from Internet, so runner needs to have access to it.): * Firefox: mvn integration-test -Pfirefox * Google Chrome: mvn integration-test -Pgooglechrome diff --git a/pom.xml b/pom.xml index 50013c1..487ca3d 100644 --- a/pom.xml +++ b/pom.xml @@ -74,6 +74,7 @@ 3.141.59 SeleniumLibrary jbrowser + False @@ -203,27 +204,6 @@ - - com.lazerycode.selenium - driver-binary-downloader-maven-plugin - 1.0.16 - - - webdriver/binaries - - webdriver/zips - - src/test/resources/RepositoryMap.xml - - - - - selenium - - - - org.robotframework @@ -241,6 +221,7 @@ ${project.basedir}/src/test/robotframework/testsuites browser:${browser} + downloadWebDriver:${downloadWebDriver} target/robotframework-reports/${browser}_report.html target/robotframework-reports/${browser}_log.html @@ -384,101 +365,29 @@ firefox firefox + True - - - - com.lazerycode.selenium - driver-binary-downloader-maven-plugin - - - org.robotframework - robotframework-maven-plugin - - - - -Dwebdriver.gecko.driver=${webdriver.gecko.driver} - - - - - - firefoxheadless firefoxheadless + True - - - - com.lazerycode.selenium - driver-binary-downloader-maven-plugin - - - org.robotframework - robotframework-maven-plugin - - - - -Dwebdriver.gecko.driver=${webdriver.gecko.driver} - - - - - - googlechrome googlechrome + True - - - - com.lazerycode.selenium - driver-binary-downloader-maven-plugin - - - org.robotframework - robotframework-maven-plugin - - - - -Dwebdriver.chrome.driver=${webdriver.chrome.driver} - - - - - - googlechromeheadless googlechromeheadless + True - - - - com.lazerycode.selenium - driver-binary-downloader-maven-plugin - - - org.robotframework - robotframework-maven-plugin - - - - -Dwebdriver.chrome.driver=${webdriver.chrome.driver} - - - - - - release diff --git a/src/test/robotframework/settings/Settings.robot b/src/test/robotframework/settings/Settings.robot index 85b3c03..5881611 100644 --- a/src/test/robotframework/settings/Settings.robot +++ b/src/test/robotframework/settings/Settings.robot @@ -6,6 +6,7 @@ Library SeleniumLibrary *** Variables *** ${Profile} Local ${browser} jbrowser +${downloadWebDriver} ${False} ${Selenium.Browser.Name} ${browser} ${Selenium.Browser.Version} 17 ${Selenium.Timeout} 30.0 diff --git a/src/test/robotframework/testsuites/UnitTests/__init__.robot b/src/test/robotframework/testsuites/UnitTests/__init__.robot new file mode 100644 index 0000000..4127098 --- /dev/null +++ b/src/test/robotframework/testsuites/UnitTests/__init__.robot @@ -0,0 +1,7 @@ +*** Settings *** +Resource ../../settings/Settings.robot +Suite Setup Handle WebDriver + +*** Keywords *** +Handle WebDriver + Run Keyword If ${downloadWebDriver} WebDriver Manager Setup ${browser} \ No newline at end of file From 15e0540bd54026fc971b8e21c336fd634f0f0cad Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Tue, 16 Jul 2019 11:06:05 +0300 Subject: [PATCH 03/23] Release 3.141.59.265 --- README.md | 26 +------------------------- pom.xml | 2 +- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 7b14403..a457322 100644 --- a/README.md +++ b/README.md @@ -59,30 +59,6 @@ which contains all required libraries. Running of tests with this can be done wi [Library Specs](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.26/robotframework-seleniumlibrary-3.141.59.26.xml) and place it in your PYTHONPATH. -Usage, Selenium 4 (WIP) ------------------ - -If you are using the robotframework-maven-plugin you can -use this library by adding the following dependency to -your pom.xml: - - - com.github.hi-fi - robotframework-seleniumlibrary - 4.0.0-alpha-1.0 - test - - -If you cannot use the robotframework-maven-plugin you can use the -[jar-with-dependencies](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/4.0.0-alpha-1.0/robotframework-seleniumlibrary-4.0.0-alpha-1.0-jar-with-dependencies.jar), -which contains all required libraries. Running of tests with this can be done with command `java -jar robotframework-seleniumlibrary-4.0.0-alpha-1.0-jar-with-dependencies.jar `. - -* More information about this library can be found in the - [Keyword Documentation](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/4.0.0-alpha-1.0/robotframework-seleniumlibrary-4.0.0-alpha-1.0.html). -* For keyword completion in RIDE you can download this - [Library Specs](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/4.0.0-alpha-1.0/robotframework-seleniumlibrary-4.0.0-alpha-1.0.xml) - and place it in your PYTHONPATH. - Differences ----------- @@ -111,7 +87,7 @@ to know when to update drivers you use. Drivers can also be fetched with [https://github.com/Ardesco/selenium-standalone-server-plugin|Selenium Driver Binary Downloader plugin]. -With Selenium 4 [https://github.com/bonigarcia/webdrivermanager|WebdriverManager] is taken to use, so handling of drivers can also be done with standalone JAR from tests itself. +With At 3.141.59.265 [https://github.com/bonigarcia/webdrivermanager|WebdriverManager] is taken to use, so handling of drivers can also be done with standalone JAR from tests itself. __ https://seleniumhq.github.io/selenium/docs/api/py/index.html#drivers __ https://en.wikipedia.org/wiki/PATH_(variable) diff --git a/pom.xml b/pom.xml index 487ca3d..e56820f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.github.hi-fi robotframework-seleniumlibrary - 3.141.59.265-SNAPSHOT + 3.141.59.265 jar Robot Framework :: SeleniumLibrary From ae6c18f6b8b9afc38a9a6d6072fdaad36bb48be3 Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Tue, 16 Jul 2019 11:35:41 +0300 Subject: [PATCH 04/23] Next 3.x version to POM --- README.md | 10 +++++----- pom.xml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a457322..e05745c 100644 --- a/README.md +++ b/README.md @@ -45,18 +45,18 @@ your pom.xml: com.github.hi-fi robotframework-seleniumlibrary - 3.141.59.26 + 3.141.59.265 test If you cannot use the robotframework-maven-plugin you can use the -[jar-with-dependencies](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.26/robotframework-seleniumlibrary-3.141.59.26-jar-with-dependencies.jar), -which contains all required libraries. Running of tests with this can be done with command `java -jar robotframework-seleniumlibrary-3.141.59.26-jar-with-dependencies.jar `. +[jar-with-dependencies](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.265/robotframework-seleniumlibrary-3.141.59.265-jar-with-dependencies.jar), +which contains all required libraries. Running of tests with this can be done with command `java -jar robotframework-seleniumlibrary-3.141.59.265-jar-with-dependencies.jar `. * More information about this library can be found in the - [Keyword Documentation](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.26/robotframework-seleniumlibrary-3.141.59.26.html). + [Keyword Documentation](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.265/robotframework-seleniumlibrary-3.141.59.265.html). * For keyword completion in RIDE you can download this - [Library Specs](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.26/robotframework-seleniumlibrary-3.141.59.26.xml) + [Library Specs](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.265/robotframework-seleniumlibrary-3.141.59.265.xml) and place it in your PYTHONPATH. Differences diff --git a/pom.xml b/pom.xml index e56820f..03ded72 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.github.hi-fi robotframework-seleniumlibrary - 3.141.59.265 + 3.141.59.2653-SNAPSHOT jar Robot Framework :: SeleniumLibrary From a3c66509301b701cb96377f1cd28e3c42abf8a89 Mon Sep 17 00:00:00 2001 From: ractoc Date: Tue, 16 Jul 2019 15:19:09 +0200 Subject: [PATCH 05/23] Added setFocusToElement. This keyword should eventually replace the Focus keyword. For backwards compatibilty the Focus keyword has been deprecated and just forwards all calls to the new SetFocusToElement keyword. Added the ElementShouldBeFocused keyword. This is the companion keyword to the SetFocusToElement. It retreives the element identified by the locator and the currently active element. Then does an equals to see if it's the same element. --- .../seleniumlibrary/keywords/Element.java | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java index d120aeb..636e601 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java @@ -247,8 +247,8 @@ public void assignIdToElement(String locator, String id) { .executeScript(String.format("arguments[0].id = '%s';", id), elements.get(0)); } - @RobotKeyword("Verify the element identified by ``locator`` is found on the current page\r\n" + - "\r\n" + + @RobotKeyword("Verify the element identified by ``locator`` is enabled\r\n" + + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about log levels and locators.") @ArgumentNames({ "locator" }) public void elementShouldBeEnabled(String locator) { @@ -257,7 +257,7 @@ public void elementShouldBeEnabled(String locator) { } } - @RobotKeyword("Verify the element identified by ``locator`` is disabled.\r\n" + + @RobotKeyword("Verify the element identified by ``locator`` is disabled.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") @ArgumentNames({ "locator" }) @@ -267,6 +267,16 @@ public void elementShouldBeDisabled(String locator) { } } + @RobotKeyword("Verify the element identified by ``locator`` is focused\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about log levels and locators.") + @ArgumentNames({ "locator" }) + public void elementShouldBeFocused(String locator) { + if (!isFocused(locator)) { + throw new SeleniumLibraryNonFatalException(String.format("Element %s is disabled.", locator)); + } + } + @RobotKeyword("Verify the element identified by ``locator`` is selected.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") @@ -582,11 +592,20 @@ public void doubleClickElement(String locator) { action.doubleClick(elements.get(0)).perform(); } - @RobotKeyword("Set the focus to the element identified by ``locator``.\r\n" + - "\r\n" + + @RobotKeyword("Set the focus to the element identified by ``locator``.\r\n" + + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") @ArgumentNames({ "locator" }) + @Deprecated public void focus(String locator) { + setFocusToElement(locator); + } + + @RobotKeyword("Set the focus to the element identified by ``locator``.\r\n" + + "\r\n" + + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + @ArgumentNames({ "locator" }) + public void setFocusToElement(String locator) { List elements = elementFind(locator, true, true); ((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeScript("arguments[0].focus();", elements.get(0)); @@ -977,6 +996,14 @@ protected boolean isEnabled(String locator) { return true; } + protected boolean isFocused(String locator) { + List elements = elementFind(locator, true, true); + WebElement element = elements.get(0); + WebDriver current = browserManagement.getCurrentWebDriver(); + WebElement focused = current.switchTo().activeElement(); + return element.equals(focused); + } + protected boolean isVisible(String locator) { List elements = elementFind(locator, true, false); if (elements.size() == 0) { From cc61a10797064aa1d32952a7671749cc7b60d194 Mon Sep 17 00:00:00 2001 From: ractoc Date: Wed, 17 Jul 2019 08:03:40 +0200 Subject: [PATCH 06/23] small copy paste error in the error message --- .../markusbernhardt/seleniumlibrary/keywords/Element.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java index 636e601..8370d97 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java @@ -273,7 +273,7 @@ public void elementShouldBeDisabled(String locator) { @ArgumentNames({ "locator" }) public void elementShouldBeFocused(String locator) { if (!isFocused(locator)) { - throw new SeleniumLibraryNonFatalException(String.format("Element %s is disabled.", locator)); + throw new SeleniumLibraryNonFatalException(String.format("Element %s is not focused.", locator)); } } From aaba73b2d4ffb9c3a1e4e3b32b7835bc2321bbe8 Mon Sep 17 00:00:00 2001 From: ractoc Date: Mon, 22 Jul 2019 15:38:31 +0200 Subject: [PATCH 07/23] added the new version of Get Element Attribute which uses 2 parameters instead of just 1. --- .../seleniumlibrary/keywords/Element.java | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java index 8370d97..a8c3ac4 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java @@ -429,18 +429,32 @@ public void elementTextShouldNotBe(String locator, String text, String...params) "\r\n" + "The ``attribute_locator`` consists of element locator followed by an @ sign and attribute name. Example: element_id@class\r\n" + "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.\r\n" + + "\r\n" + + "Passing attribute name as part of the locator was removed in SeleniumLibrary 3.2. The explicit attribute argument should be used instead.") @ArgumentNames({ "attributeLocator" }) + @Deprecated public String getElementAttribute(String attributeLocator) { String[] parts = parseAttributeLocator(attributeLocator); + return getElementAttribute(parts[0], parts[1]); + } - List elements = elementFind(parts[0], true, false); + @RobotKeyword("Returns value of attribute from element locator.\r\n" + + "\r\n" + + "See the `Locating elements` section for details about the locator syntax.\r\n" + + "\r\n" + + "Example: ${id}= Get Element Attribute css:h1 id\r\n" + + "\r\n" + + "Passing attribute name as part of the locator was removed in SeleniumLibrary 3.2. The explicit attribute argument should be used instead.") + @ArgumentNames({ "locator", "attribute" }) + public String getElementAttribute(String locator, String attribute) { + + List elements = elementFind(locator, true, false); if (elements.size() == 0) { - throw new SeleniumLibraryNonFatalException(String.format("Element '%s' not found.", parts[0])); + throw new SeleniumLibraryNonFatalException(String.format("Element '%s' not found.", locator)); } - - return elements.get(0).getAttribute(parts[1]); + return elements.get(0).getAttribute(attribute); } @RobotKeyword("Clears the text from element identified by ``locator``.\r\n" + From 54dae8bf14478f05795ff24a0ac8a8113e788c5d Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Tue, 23 Jul 2019 14:52:20 +0300 Subject: [PATCH 08/23] Added HTMLUnit support back Fixes #79 Prevented running 'Run Keyword on failure' again, if given keyword fails --- .travis.yml | 1 + pom.xml | 12 ++++++++++++ .../keywords/BrowserManagement.java | 16 +++++++++++++++- .../seleniumlibrary/keywords/RunOnFailure.java | 1 + .../keywords/BrowserManagementTest.java | 6 ++++++ .../testsuites/UnitTests/AW3Schools.robot | 2 +- .../testsuites/UnitTests/ExtJS.robot | 1 - .../testsuites/UnitTests/GetInnerElementId.robot | 1 - 8 files changed, 36 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f23414..a2c991b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ env: - PROFILE=build,firefox - PROFILE=build,googlechromeheadless - PROFILE=build,firefoxheadless + - PROFILE=build,htmlunitwithjs stages: - test diff --git a/pom.xml b/pom.xml index 03ded72..8f7a6b4 100644 --- a/pom.xml +++ b/pom.xml @@ -129,6 +129,11 @@ jbrowserdriver 1.0.1 + + org.seleniumhq.selenium + htmlunit-driver + 2.35.1 + org.mockito mockito-core @@ -361,6 +366,13 @@ + + htmlunitwithjs + + htmlunitwithjs + False + + firefox diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/BrowserManagement.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/BrowserManagement.java index 21949d5..66ceec0 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/BrowserManagement.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/BrowserManagement.java @@ -38,6 +38,7 @@ import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxOptions; import org.openqa.selenium.firefox.FirefoxProfile; +import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.ie.InternetExplorerOptions; import org.openqa.selenium.opera.OperaDriver; @@ -168,7 +169,9 @@ public void closeBrowser() { "| Opera | opera |\r\n" + "| Android | android |\r\n" + "| Iphone | iphone |\r\n" + - "| JBrowser | jbrowser |\r\n" + + "| JBrowser | jbrowser |\r\n" + + "| HTMLUnit | htmlunit |\r\n" + + "| HTMLUnit with Javascript | htmlunitwithjs |\r\n" + "\r\n" + "To be able to actually use one of these browsers, you need to have a matching Selenium browser driver available. See the [https://github.com/Hi-Fi/robotframework-seleniumlibrary-java#browser-drivers|project documentation] for more details.\r\n" + "\r\n" + @@ -677,6 +680,12 @@ protected WebDriver createLocalWebDriver(String browserName, Capabilities desire } catch (Exception e) { throw new SeleniumLibraryFatalException("Creating " + browserName + " instance failed.", e); } + case "htmlunit": + return new HtmlUnitDriver(desiredCapabilities); + case "htmlunitwithjs": + HtmlUnitDriver driver = new HtmlUnitDriver(desiredCapabilities); + driver.setJavascriptEnabled(true); + return driver; default: throw new SeleniumLibraryFatalException(browserName + " is not a supported browser."); } @@ -769,6 +778,11 @@ protected Capabilities createCapabilities(String browserName, String desiredCapa case "jbrowser": desiredCapabilities = new DesiredCapabilities("jbrowser", "1", Platform.ANY); break; + case "htmlunit": + case "htmlunitwithjs": + desiredCapabilities = DesiredCapabilities.htmlUnit(); + ((DesiredCapabilities) desiredCapabilities).setBrowserName("htmlunit"); + break; default: throw new SeleniumLibraryFatalException(browserName + " is not a supported browser."); } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/RunOnFailure.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/RunOnFailure.java index 50da8e6..0b9af9b 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/RunOnFailure.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/RunOnFailure.java @@ -81,6 +81,7 @@ public void runOnFailure() { if(runOnFailurePythonInterpreter.get().eval("EXECUTION_CONTEXTS.current").toString().equals("None")) { return; } + runningOnFailureRoutine = true; try { runOnFailurePythonInterpreter.get().exec( diff --git a/src/test/java/com/github/markusbernhardt/seleniumlibrary/keywords/BrowserManagementTest.java b/src/test/java/com/github/markusbernhardt/seleniumlibrary/keywords/BrowserManagementTest.java index 7fbffe2..b9f7e2a 100644 --- a/src/test/java/com/github/markusbernhardt/seleniumlibrary/keywords/BrowserManagementTest.java +++ b/src/test/java/com/github/markusbernhardt/seleniumlibrary/keywords/BrowserManagementTest.java @@ -62,6 +62,12 @@ public void testCreateDesiredCapabilitiesWithOnlyBrowserOptions() { assertTrue(profile.getStringPreference("network.proxy.http", "wrong") != "wrong"); } + @Test + public void testCreateDesiredCapabilitiesForHtmlUnit() { + Capabilities dc = bm.createCapabilities("htmlunitwithjs", null, ""); + assertTrue(dc.getBrowserName().equals("htmlunit")); + } + @Test public void parseChromeBrowserOptions() { ChromeOptions chromeOptions = new ChromeOptions(); diff --git a/src/test/robotframework/testsuites/UnitTests/AW3Schools.robot b/src/test/robotframework/testsuites/UnitTests/AW3Schools.robot index 01fd369..32504b6 100644 --- a/src/test/robotframework/testsuites/UnitTests/AW3Schools.robot +++ b/src/test/robotframework/testsuites/UnitTests/AW3Schools.robot @@ -1,13 +1,13 @@ *** Settings *** Suite Teardown Close All Browsers Resource ../../settings/Settings.robot +Default Tags htmlunitwith htmlunitwithjs *** Variables *** ${URL Application} http://www.w3schools.com *** Test Cases *** Select - [Tags] jbrowser Open Browser https://developer.mozilla.org/en/docs/Web/HTML/Element/select#Examples ${browser} mainbrowser Wait Until Page Contains Element xpath://select Select From List xpath://select Third Value diff --git a/src/test/robotframework/testsuites/UnitTests/ExtJS.robot b/src/test/robotframework/testsuites/UnitTests/ExtJS.robot index dded819..4cc8fa1 100644 --- a/src/test/robotframework/testsuites/UnitTests/ExtJS.robot +++ b/src/test/robotframework/testsuites/UnitTests/ExtJS.robot @@ -2,7 +2,6 @@ Suite Setup Open Page Suite Teardown Close Browser Resource ../../settings/Settings.robot -Default Tags jbrowser *** Variables *** ${URL Application} http://examples.sencha.com/extjs/6.5.0/examples/classic/ticket-app/index.html diff --git a/src/test/robotframework/testsuites/UnitTests/GetInnerElementId.robot b/src/test/robotframework/testsuites/UnitTests/GetInnerElementId.robot index 64eb575..058ab1f 100644 --- a/src/test/robotframework/testsuites/UnitTests/GetInnerElementId.robot +++ b/src/test/robotframework/testsuites/UnitTests/GetInnerElementId.robot @@ -1,6 +1,5 @@ *** Settings *** Resource ../../settings/Settings.robot -Default Tags jbrowser *** Test Cases *** Get Inner Element Id test From 01b20bb4efe74c9a198660f07a43043abb18e13d Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Wed, 24 Jul 2019 12:26:29 +0300 Subject: [PATCH 09/23] Changed android and ios testing dependencies as provided so those are not included in fat-jar Instructions how to take ios/android testing to use with Maven Fixes #62 Forcing to use Trusty image --- .travis.yml | 1 + README.md | 9 +++++++-- pom.xml | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1f364f9..e9cd902 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: java +dist: trusty matrix: include: diff --git a/README.md b/README.md index 7b14403..77abd01 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ which contains all required libraries. Running of tests with this can be done wi and place it in your PYTHONPATH. Usage, Selenium 4 (WIP) ------------------ +----------------------- If you are using the robotframework-maven-plugin you can use this library by adding the following dependency to @@ -75,7 +75,7 @@ your pom.xml: If you cannot use the robotframework-maven-plugin you can use the [jar-with-dependencies](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/4.0.0-alpha-1.0/robotframework-seleniumlibrary-4.0.0-alpha-1.0-jar-with-dependencies.jar), -which contains all required libraries. Running of tests with this can be done with command `java -jar robotframework-seleniumlibrary-4.0.0-alpha-1.0-jar-with-dependencies.jar `. +which contains all required libraries except ios/android ones (Appium and Selendroid). Running of tests with this can be done with command `java -jar robotframework-seleniumlibrary-4.0.0-alpha-1.0-jar-with-dependencies.jar `. * More information about this library can be found in the [Keyword Documentation](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/4.0.0-alpha-1.0/robotframework-seleniumlibrary-4.0.0-alpha-1.0.html). @@ -83,6 +83,11 @@ which contains all required libraries. Running of tests with this can be done wi [Library Specs](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/4.0.0-alpha-1.0/robotframework-seleniumlibrary-4.0.0-alpha-1.0.xml) and place it in your PYTHONPATH. +Testing IOS/Android browsers with library +----------------------------------------- +Pre-Selenium 4 fat-jar contains Appium and Selendroid that allow testing of IOS and Android browsers. Those are dropped in Selenium 4 -versions, +so dependencies needs to be handles self with either Maven/Gradle or manually. If there's need to have fat-jar with those, please create issue about that. + Differences ----------- diff --git a/pom.xml b/pom.xml index 60e9d1b..eda56a8 100644 --- a/pom.xml +++ b/pom.xml @@ -113,6 +113,7 @@ selenium-java + provided io.appium @@ -128,6 +129,7 @@ selenium-api + provided org.apache.commons From f87307294d151082fb3810e9176f91ccf55e566e Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Thu, 25 Jul 2019 21:32:23 +0300 Subject: [PATCH 10/23] Updating keys manually before update --- .travis/setup_xvfb.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis/setup_xvfb.sh b/.travis/setup_xvfb.sh index 64fc616..32f7cbc 100755 --- a/.travis/setup_xvfb.sh +++ b/.travis/setup_xvfb.sh @@ -1,5 +1,6 @@ #!/bin/bash +sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 762E3157 sudo apt-get -qq update sudo apt-get install -y dbus-x11 export DISPLAY=:99.0 From 43198b7f4630d2ec02cb52c44fc519ed472dbddf Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Thu, 25 Jul 2019 21:43:15 +0300 Subject: [PATCH 11/23] Testing only headless browsers (issues with Trusty and Xvfb) --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e9cd902..ab942c3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,8 +12,6 @@ jdk: env: - PROFILE=build - - PROFILE=build,googlechrome - - PROFILE=build,firefox - PROFILE=build,googlechromeheadless - PROFILE=build,firefoxheadless @@ -31,7 +29,6 @@ addons: before_install: - if [ ! -z "$GPG_SECRET_KEYS" ]; then echo $GPG_SECRET_KEYS | base64 --decode | $GPG_EXECUTABLE --import; fi - if [ ! -z "$GPG_OWNERTRUST" ]; then echo $GPG_OWNERTRUST | base64 --decode | $GPG_EXECUTABLE --import-ownertrust; fi - - .travis/setup_xvfb.sh install: mvn --settings .travis/settings.xml verify -Dgpg.skip -B -V -P$PROFILE script: skip From 265e2b18a025c2c14009e31ea34bc1015f72a171 Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Thu, 25 Jul 2019 21:49:18 +0300 Subject: [PATCH 12/23] Removed headfull browsers from testing Forcing to use Trusty that has OracleJDK8 available --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f23414..728b516 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ language: java +dist: trusty + jdk: - oraclejdk8 env: - PROFILE=build - - PROFILE=build,googlechrome - - PROFILE=build,firefox - PROFILE=build,googlechromeheadless - PROFILE=build,firefoxheadless From cf753286cc061db0f3c61565be5bc21fa1e69fc6 Mon Sep 17 00:00:00 2001 From: YauheniPo Date: Sat, 27 Jul 2019 18:37:00 +0300 Subject: [PATCH 13/23] Code refactoring --- .../seleniumlibrary/SeleniumLibrary.java | 3 - .../seleniumlibrary/keywords/Cookie.java | 6 +- .../seleniumlibrary/keywords/Element.java | 14 +- .../seleniumlibrary/keywords/JavaScript.java | 12 +- .../seleniumlibrary/keywords/Logging.java | 21 +-- .../seleniumlibrary/keywords/Robot.java | 36 +++-- .../keywords/RunOnFailure.java | 14 +- .../seleniumlibrary/keywords/Screenshot.java | 33 ++-- .../keywords/SelectElement.java | 30 ++-- .../keywords/TableElement.java | 2 +- .../seleniumlibrary/keywords/Waiting.java | 144 ++++-------------- .../seleniumlibrary/keywords/Window.java | 7 +- .../locators/ElementFinder.java | 120 +++++++-------- .../locators/TableElementFinder.java | 20 +-- .../locators/WindowManager.java | 50 ++---- .../seleniumlibrary/utils/Python.java | 4 +- .../seleniumlibrary/utils/WebDriverCache.java | 16 +- 17 files changed, 189 insertions(+), 343 deletions(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/SeleniumLibrary.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/SeleniumLibrary.java index a889e27..bfc3491 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/SeleniumLibrary.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/SeleniumLibrary.java @@ -63,7 +63,6 @@ public SeleniumLibrary(String timeout, String implicitWait, String keywordToRunO if (!screenshotPath.isEmpty()) { screenshot.setScreenshotDirectory(screenshotPath); } - } // ############################## @@ -79,7 +78,6 @@ public SeleniumLibrary(String timeout, String implicitWait, String keywordToRunO @Autowired Screenshot screenshot; - @Override public String getKeywordDocumentation(String keywordName) { if (keywordName.equals("__intro__")) { @@ -185,6 +183,5 @@ public String getKeywordDocumentation(String keywordName) { } } return keywordName; - } } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Cookie.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Cookie.java index db21fc2..4fd1939 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Cookie.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Cookie.java @@ -42,12 +42,12 @@ public void deleteCookie(String name) { @RobotKeyword("Returns all cookies of the current page.") public String getCookies() { - StringBuffer ret = new StringBuffer(); + StringBuilder ret = new StringBuilder(); - ArrayList cookies = new ArrayList(browserManagement + ArrayList cookies = new ArrayList<>(browserManagement .getCurrentWebDriver().manage().getCookies()); for (int i = 0; i < cookies.size(); i++) { - ret.append(cookies.get(i).getName() + "=" + cookies.get(i).getValue()); + ret.append(cookies.get(i).getName()).append("=").append(cookies.get(i).getValue()); if (i != cookies.size() - 1) { ret.append("; "); } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java index a8c3ac4..d480b92 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java @@ -366,7 +366,6 @@ public void elementShouldBeClickable(String locator, String...params) { } } - @RobotKeyword("Verify the element identified by ``locator`` is not clickable.\r\n" + "\r\n" + "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.") @@ -404,7 +403,6 @@ public void elementTextShouldBe(String locator, String text, String...params) { } } - @RobotKeyword("Verify the text of the element identified by ``locator`` is not exactly ``text``.\r\n" + "\r\n" + "In contrast to `Element Should Not Contain`, this keyword does not try a substring match but an exact match on the element identified by locator.\r\n" + @@ -448,7 +446,6 @@ public String getElementAttribute(String attributeLocator) { "Passing attribute name as part of the locator was removed in SeleniumLibrary 3.2. The explicit attribute argument should be used instead.") @ArgumentNames({ "locator", "attribute" }) public String getElementAttribute(String locator, String attribute) { - List elements = elementFind(locator, true, false); if (elements.size() == 0) { @@ -494,7 +491,6 @@ public String getInnerElementId(String locator, String matchid, int index) { logging.info(String.format("Found element ID: '%s'.", eId)); return eId; - } @RobotKeyword("Returns horizontal position of element identified by ``locator``.\r\n" + @@ -778,7 +774,6 @@ public void pressKey(String locator, String key) { // Keywords - Links // ############################## - @RobotKeyword("Click on the link identified by ``locator``.\r\n" + "\r\n" + "Key attributes for links are id, name, href and link text. See `Introduction` for details about locators.") @@ -794,7 +789,7 @@ public void clickLink(String locator) { "\r\n" + "If a link has no id, an empty string will be in the list instead.") public ArrayList getAllLinks() { - ArrayList ret = new ArrayList(); + ArrayList ret = new ArrayList<>(); List elements = elementFind("tag:a", false, false, "a"); for (WebElement element : elements) { @@ -965,7 +960,7 @@ protected List elementFind(String locator, boolean firstOnly, boolea if (firstOnly) { if (elements.size() > 1) { - List tmp = new ArrayList(); + List tmp = new ArrayList<>(); tmp.add(elements.get(0)); elements = tmp; } @@ -1079,9 +1074,8 @@ protected boolean pageContains(String text) { } List elements = elementFind("xpath://frame|//iframe", false, false); - Iterator it = elements.iterator(); - while (it.hasNext()) { - current.switchTo().frame(it.next()); + for (WebElement element : elements) { + current.switchTo().frame(element); boolean found = isTextPresent(text); current.switchTo().defaultContent(); if (found) { diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/JavaScript.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/JavaScript.java index b2b249c..2d26459 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/JavaScript.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/JavaScript.java @@ -137,7 +137,7 @@ public String confirmAction() { @ArgumentNames({ "*code" }) public Object executeJavascript(String... code) { String js = getJavascriptToExecute(Python.join("", Arrays.asList(code))); - String.format("Executing JavaScript:\n%s", js); + logging.html(String.format("Executing JavaScript:\n%s", js)); return ((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeScript(js); } @@ -155,7 +155,7 @@ public Object executeJavascript(String... code) { @ArgumentNames({ "*code" }) public Object executeAsyncJavascript(String... code) { String js = getJavascriptToExecute(Python.join("", Arrays.asList(code))); - String.format("Executing JavaScript:\n%s", js); + logging.html(String.format("Executing JavaScript:\n%s", js)); return ((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeAsyncScript(js); } @@ -165,8 +165,7 @@ public Object executeAsyncJavascript(String... code) { public String getAlertMessage() { try { Alert alert = browserManagement.getCurrentWebDriver().switchTo().alert(); - String text = alert.getText().replace("\n", ""); - return text; + return alert.getText().replace("\n", ""); } catch (WebDriverException wde) { throw new SeleniumLibraryNonFatalException("There were no alerts"); } @@ -177,14 +176,11 @@ public String getAlertMessage() { // ############################## protected static String readFile(String path) throws IOException { - FileInputStream stream = new FileInputStream(new File(path)); - try { + try (FileInputStream stream = new FileInputStream(new File(path))) { FileChannel fc = stream.getChannel(); MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); /* Instead of using default, pass in a decoder. */ return Charset.defaultCharset().decode(bb).toString(); - } finally { - stream.close(); } } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Logging.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Logging.java index 3047fba..8f75c51 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Logging.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Logging.java @@ -24,7 +24,7 @@ public class Logging extends RunOnFailureKeywordsAdapter { protected static String logDir = null; static { - VALID_LOG_LEVELS = new HashMap(); + VALID_LOG_LEVELS = new HashMap<>(); VALID_LOG_LEVELS.put("debug", new String[] { "debug", "" }); VALID_LOG_LEVELS.put("html", new String[] { "info", ", True, False" }); VALID_LOG_LEVELS.put("info", new String[] { "info", "" }); @@ -60,7 +60,6 @@ public List logWindowIdentifiers(String...params) { return windowIdentifiers; } - @RobotKeyword("Logs and returns the names of all windows known to the current browser instance.\r\n" + "\r\n" + "See `Introduction` for details about the ``logLevel``.") @@ -131,7 +130,6 @@ public String logSystemInfo(String...params) { return actual; } - @RobotKeyword("Returns the actually supported capabilities of the remote browser instance.\r\n" + "\r\n" + "Not all server implementations will support every WebDriver feature. Therefore, the client and server should use JSON objects with the properties listed below when describing which features a user requests that a session support. *If a session cannot support a capability that is requested in the desired capabilities, no error is thrown*; a read-only capabilities object is returned that indicates the capabilities the session actually supports. For more information see: [https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities|DesiredCapabilities]\r\n" + @@ -239,7 +237,6 @@ protected void log0(String msg, String methodName, String methodArguments) { } protected File getLogDir() { - if (logDir == null && !loggingPythonInterpreter.get().eval("EXECUTION_CONTEXTS.current").toString().equals("None")) { PyString logDirName = (PyString) loggingPythonInterpreter.get() @@ -258,14 +255,10 @@ public static void setLogDir(String logDirectory) { logDir = logDirectory; } - protected static ThreadLocal loggingPythonInterpreter = new ThreadLocal() { - - @Override - protected PythonInterpreter initialValue() { - PythonInterpreter pythonInterpreter = new PythonInterpreter(); - pythonInterpreter.exec( - "from robot.libraries.BuiltIn import BuiltIn; from robot.running.context import EXECUTION_CONTEXTS; from robot.api import logger;"); - return pythonInterpreter; - } - }; + protected static ThreadLocal loggingPythonInterpreter = ThreadLocal.withInitial(() -> { + PythonInterpreter pythonInterpreter = new PythonInterpreter(); + pythonInterpreter.exec( + "from robot.libraries.BuiltIn import BuiltIn; from robot.running.context import EXECUTION_CONTEXTS; from robot.api import logger;"); + return pythonInterpreter; + }); } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Robot.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Robot.java index 987be24..bd0f9bd 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Robot.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Robot.java @@ -1,13 +1,11 @@ package com.github.markusbernhardt.seleniumlibrary.keywords; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - +import com.google.gson.Gson; import org.python.util.PythonInterpreter; import org.robotframework.javalib.annotation.RobotKeywords; -import com.google.gson.Gson; +import java.util.List; +import java.util.Map; @RobotKeywords public class Robot { @@ -38,20 +36,20 @@ public T getParamsValue(String[] params, int index, T defaultValue) { } @SuppressWarnings({ "unchecked", "resource" }) - public Map parseRobotDictionary(String dictionary) { - logging.debug("Dictionary going to be parsed to Map: " + dictionary); - Map json = new HashMap(); - try { - PythonInterpreter py = new PythonInterpreter(); - py.exec("import json"); - json = new Gson().fromJson(py.eval("json.dumps(" + dictionary + ")").toString(), Map.class); - } catch (RuntimeException e) { - logging.error(String.format("Parsing of dictionary %s failed.", dictionary)); - throw e; - } - - return json; - } + public Map parseRobotDictionary(String dictionary) { + logging.debug("Dictionary going to be parsed to Map: " + dictionary); + Map json; + try { + PythonInterpreter py = new PythonInterpreter(); + py.exec("import json"); + json = new Gson().fromJson(py.eval("json.dumps(" + dictionary + ")").toString(), Map.class); + } catch (RuntimeException e) { + logging.error(String.format("Parsing of dictionary %s failed.", dictionary)); + throw e; + } + + return json; + } @SuppressWarnings("unchecked") public List parseRobotList(String list) { diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/RunOnFailure.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/RunOnFailure.java index 50da8e6..3787571 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/RunOnFailure.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/RunOnFailure.java @@ -61,15 +61,11 @@ public String registerKeywordToRunOnFailure(String keyword) { // Internal Methods // ############################## - protected static ThreadLocal runOnFailurePythonInterpreter = new ThreadLocal() { - - @Override - protected PythonInterpreter initialValue() { - PythonInterpreter pythonInterpreter = new PythonInterpreter(); - pythonInterpreter.exec("from robot.libraries.BuiltIn import BuiltIn; from robot.running.context import EXECUTION_CONTEXTS; BIN = BuiltIn();"); - return pythonInterpreter; - } - }; + protected static ThreadLocal runOnFailurePythonInterpreter = ThreadLocal.withInitial(() -> { + PythonInterpreter pythonInterpreter = new PythonInterpreter(); + pythonInterpreter.exec("from robot.libraries.BuiltIn import BuiltIn; from robot.running.context import EXECUTION_CONTEXTS; BIN = BuiltIn();"); + return pythonInterpreter; + }); public void runOnFailure() { if (runOnFailureKeyword == null) { diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Screenshot.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Screenshot.java index 4645957..17c5afc 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Screenshot.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Screenshot.java @@ -1,9 +1,7 @@ package com.github.markusbernhardt.seleniumlibrary.keywords; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - +import com.github.markusbernhardt.seleniumlibrary.RunOnFailureKeywordsAdapter; +import com.github.markusbernhardt.seleniumlibrary.utils.Robotframework; import org.apache.commons.lang3.exception.ExceptionUtils; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; @@ -13,8 +11,9 @@ import org.robotframework.javalib.annotation.RobotKeyword; import org.robotframework.javalib.annotation.RobotKeywords; -import com.github.markusbernhardt.seleniumlibrary.RunOnFailureKeywordsAdapter; -import com.github.markusbernhardt.seleniumlibrary.utils.Robotframework; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; @RobotKeywords public class Screenshot extends RunOnFailureKeywordsAdapter { @@ -50,15 +49,15 @@ public String setScreenshotDirectory(String path) { screenshotDir = new File(path); return oldDir; } - - @RobotKeyword("Take a screenshot of the current page and embed it into the log.\r\n" + - "\r\n" + - "The ``filename`` argument specifies the name of the file to write the screenshot into. If no filename is given, the screenshot is saved into file selenium-screenshot-{index}.png under the directory where the Robot Framework log file is written into. The filename is also considered relative to the same directory, if it is not given in absolute format.\r\n" + - "\r\n" + - "if ``filename`` contains marker {index}, it will be automatically replaced with unique running index preventing files to be overwritten. Indices start from 1.\r\n" + - "\r\n" + - "A CSS can be used to modify how the screenshot is taken. By default the background color is changed to avoid possible problems with background leaking when the page layout is somehow broken.") - @ArgumentNames({ "filename=selenium-screenshot-{index}.png" }) + + @RobotKeyword("Take a screenshot of the current page and embed it into the log.\r\n" + + "\r\n" + + "The ``filename`` argument specifies the name of the file to write the screenshot into. If no filename is given, the screenshot is saved into file selenium-screenshot-{index}.png under the directory where the Robot Framework log file is written into. The filename is also considered relative to the same directory, if it is not given in absolute format.\r\n" + + "\r\n" + + "if ``filename`` contains marker {index}, it will be automatically replaced with unique running index preventing files to be overwritten. Indices start from 1.\r\n" + + "\r\n" + + "A CSS can be used to modify how the screenshot is taken. By default the background color is changed to avoid possible problems with background leaking when the page layout is somehow broken.") + @ArgumentNames({"filename=selenium-screenshot-{index}.png"}) public void capturePageScreenshot(String...params) { String filename = robot.getParamsValue(params, 0, null); File logdir = screenshotDir != null ? screenshotDir : logging.getLogDir(); @@ -68,7 +67,6 @@ public void capturePageScreenshot(String...params) { if (currentWebDriver.getClass().toString().contains("HtmlUnit")) { logging.warn("HTMLunit is not supporting screenshots."); - return; } else { try { TakesScreenshot takesScreenshot = ((TakesScreenshot) currentWebDriver); @@ -79,8 +77,7 @@ public void capturePageScreenshot(String...params) { "", link, link)); } catch (NullPointerException e) { logging.warn("Can't take screenshot. No open browser found"); - return; - } + } } } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java index 43b2b8c..76feb8b 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java @@ -1,6 +1,7 @@ package com.github.markusbernhardt.seleniumlibrary.keywords; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.openqa.selenium.NoSuchElementException; @@ -47,7 +48,6 @@ public List getListItems(String locator) { return getLabelsForOptions(options); } - @RobotKeyword("Returns the visible label of the first selected element from the select list identified by ``locator``.\r\n" + "\r\n" + "Select list keywords work on both lists and combo boxes. Key attributes for select lists are id and name. See `Introduction` for details about locators.") @@ -142,11 +142,11 @@ public void listShouldHaveNoSelections(String locator) { logging.info(String.format("Verifying list '%s' has no selection.", locator)); List options = getSelectListOptionsSelected(locator); - if (!options.equals(null)) { + if (options != null) { List selectedLabels = getLabelsForOptions(options); String items = Python.join(" | ", selectedLabels); throw new SeleniumLibraryNonFatalException(String.format( - "List '%s' should have had no selection (selection was [ %s ]).", locator, items.toString())); + "List '%s' should have had no selection (selection was [ %s ]).", locator, items)); } } @@ -211,7 +211,7 @@ public void selectFromList(String locator, String... items) { } boolean lastItemFound = false; - List nonExistingItems = new ArrayList(); + List nonExistingItems = new ArrayList<>(); for (String item : items) { lastItemFound = true; try { @@ -222,7 +222,6 @@ public void selectFromList(String locator, String... items) { } catch (NoSuchElementException e2) { nonExistingItems.add(item); lastItemFound = false; - continue; } } } @@ -257,10 +256,7 @@ public void selectFromListByIndex(String locator, String... indexes) { throw new SeleniumLibraryNonFatalException("No index given."); } - List tmp = new ArrayList(); - for (String index : indexes) { - tmp.add(index); - } + List tmp = new ArrayList<>(Arrays.asList(indexes)); String items = String.format("index(es) '%s'", Python.join(", ", tmp)); logging.info(String.format("Selecting %s from list '%s'.", items, locator)); @@ -343,11 +339,11 @@ public void unselectFromList(String locator, String... items) { "Select list keywords work on both lists and combo boxes. Key attributes for select lists are id and name. See `Introduction` for details about locators.") @ArgumentNames({ "locator", "*indexes" }) public void unselectFromListByIndex(String locator, Integer... indexes) { - if (indexes.equals(null)) { + if (indexes.length == 0) { throw new SeleniumLibraryNonFatalException("No index given."); } - List tmp = new ArrayList(); + List tmp = new ArrayList<>(); for (Integer index : indexes) { tmp.add(index.toString()); } @@ -371,7 +367,7 @@ public void unselectFromListByIndex(String locator, Integer... indexes) { "Select list keywords work on both lists and combo boxes. Key attributes for select lists are id and name. See `Introduction` for details about locators.") @ArgumentNames({ "locator", "*values" }) public void unselectFromListByValue(String locator, String... values) { - if (values.equals(null)) { + if (values.length == 0) { throw new SeleniumLibraryNonFatalException("No value given."); } @@ -395,7 +391,7 @@ public void unselectFromListByValue(String locator, String... values) { "Select list keywords work on both lists and combo boxes. Key attributes for select lists are id and name. See `Introduction` for details about locators.") @ArgumentNames({ "locator", "*labels" }) public void unselectFromListByLabel(String locator, String... labels) { - if (labels.equals(null)) { + if (labels.length == 0) { throw new SeleniumLibraryNonFatalException("No value given."); } @@ -419,7 +415,7 @@ public void unselectFromListByLabel(String locator, String... labels) { // ############################## protected List getLabelsForOptions(List options) { - List labels = new ArrayList(); + List labels = new ArrayList<>(); for (WebElement option : options) { labels.add(option.getText()); @@ -435,7 +431,7 @@ protected Select getSelectList(String locator) { } protected List getSelectListOptions(Select select) { - return new ArrayList(select.getOptions()); + return new ArrayList<>(select.getOptions()); } protected List getSelectListOptions(String locator) { @@ -447,11 +443,11 @@ protected List getSelectListOptions(String locator) { protected List getSelectListOptionsSelected(String locator) { Select select = getSelectList(locator); - return new ArrayList(select.getAllSelectedOptions()); + return new ArrayList<>(select.getAllSelectedOptions()); } protected List getValuesForOptions(List options) { - ArrayList labels = new ArrayList(); + ArrayList labels = new ArrayList<>(); for (WebElement option : options) { labels.add(option.getAttribute("value")); diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/TableElement.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/TableElement.java index 507c3d6..e956e9a 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/TableElement.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/TableElement.java @@ -80,7 +80,7 @@ public void tableCellShouldContain(String tableLocator, int row, int column, Str String message = String.format("Cell in table '%s' in row #%d and column #%d should have contained text '%s'.", tableLocator, row, column, text); - String content = ""; + String content; try { content = getTableCell(tableLocator, row, column, logLevel); } catch (SeleniumLibraryNonFatalException e) { diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Waiting.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Waiting.java index 06842e9..7a8c0e1 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Waiting.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Waiting.java @@ -52,14 +52,8 @@ public void waitForCondition(final String condition, String...params) { if (message == null) { message = String.format("Condition '%s' did not become true in ", condition); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return Boolean.TRUE.equals(((JavascriptExecutor) browserManagement.getCurrentWebDriver()) - .executeScript(condition)); - } - }); + waitUntil(timeout, message, () -> Boolean.TRUE.equals(((JavascriptExecutor) browserManagement.getCurrentWebDriver()) + .executeScript(condition))); } @RobotKeyword("Waits until the current page contains ``text``.\r\n" + @@ -74,13 +68,7 @@ public void waitUntilPageContains(final String text, String...params) { if (message == null) { message = String.format("Text '%s' did not appear in ", text); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return element.isTextPresent(text); - } - }); + waitUntil(timeout, message, () -> element.isTextPresent(text)); } @RobotKeyword("Waits until the current page does not contain ``text``.\r\n" + @@ -95,13 +83,7 @@ public void waitUntilPageNotContains(final String text, String...params) { if (message == null) { message = String.format("Text '%s' did not disappear in ", text); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return !element.isTextPresent(text); - } - }); + waitUntil(timeout, message, () -> !element.isTextPresent(text)); } @RobotKeyword("Waits until the current page does not contain ``text``.\r\n" + @@ -128,13 +110,7 @@ public void waitUntilPageContainsElement(final String locator, String...params) if (message == null) { message = String.format("Element '%s' did not appear in ", locator); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return element.isElementPresent(locator); - } - }); + waitUntil(timeout, message, () -> element.isElementPresent(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not found on the current page.\r\n" + @@ -149,13 +125,7 @@ public void waitUntilPageNotContainsElement(final String locator, String...param if (message == null) { message = String.format("Element '%s' did not disappear in ", locator); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return !element.isElementPresent(locator); - } - }); + waitUntil(timeout, message, () -> !element.isElementPresent(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not found on the current page.\r\n" + @@ -182,13 +152,7 @@ public void waitUntilElementIsVisible(final String locator, String...params) { if (message == null) { message = String.format("Element '%s' not visible in ", locator); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return element.isVisible(locator); - } - }); + waitUntil(timeout, message, () -> element.isVisible(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not visible.\r\n" + @@ -203,13 +167,7 @@ public void waitUntilElementIsNotVisible(final String locator, String...params) if (message == null) { message = String.format("Element '%s' still visible in ", locator); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return !element.isVisible(locator); - } - }); + waitUntil(timeout, message, () -> !element.isVisible(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is clickable.\r\n" + @@ -224,13 +182,7 @@ public void waitUntilElementIsClickable(final String locator, String...params) { if (message == null) { message = String.format("Element '%s' not clickable in ", locator); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return element.isClickable(locator); - } - }); + waitUntil(timeout, message, () -> element.isClickable(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not clickable.\r\n" + @@ -245,13 +197,7 @@ public void waitUntilElementIsNotClickable(final String locator, String...params if (message == null) { message = String.format("Element '%s' still clickable in ", locator); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return !element.isClickable(locator); - } - }); + waitUntil(timeout, message, () -> !element.isClickable(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is succesfully clicked on.\r\n" + @@ -266,13 +212,9 @@ public void waitUntilElementIsSuccessfullyClicked(final String locator, String.. if (message == null) { message = String.format("Element '%s' not successfully clicked in ", locator); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - element.clickElement(locator); - return true; - } + waitUntil(timeout, message, () -> { + element.clickElement(locator); + return true; }); } @@ -288,13 +230,7 @@ public void waitUntilElementIsSelected(final String locator, String...params) { if (message == null) { message = String.format("Element '%s' not selected in ", locator); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return element.isSelected(locator); - } - }); + waitUntil(timeout, message, () -> element.isSelected(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not selected.\r\n" + @@ -309,13 +245,7 @@ public void waitUntilElementIsNotSelected(final String locator, String...params) if (message == null) { message = String.format("Element '%s' still selected in ", locator); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - return !element.isSelected(locator); - } - }); + waitUntil(timeout, message, () -> !element.isSelected(locator)); } @RobotKeyword("Waits until the current page title contains ``title``.\r\n" + @@ -330,13 +260,9 @@ public void waitUntilTitleContains(final String title, String...params) { if (message == null) { message = String.format("Title '%s' did not appear in ", title); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - String currentTitle = browserManagement.getTitle(); - return currentTitle != null && currentTitle.contains(title); - } + waitUntil(timeout, message, () -> { + String currentTitle = browserManagement.getTitle(); + return currentTitle != null && currentTitle.contains(title); }); } @@ -352,13 +278,9 @@ public void waitUntilTitleNotContains(final String title, String...params) { if (message == null) { message = String.format("Title '%s' did not appear in ", title); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - String currentTitle = browserManagement.getTitle(); - return currentTitle == null || !currentTitle.contains(title); - } + waitUntil(timeout, message, () -> { + String currentTitle = browserManagement.getTitle(); + return currentTitle == null || !currentTitle.contains(title); }); } @@ -374,13 +296,9 @@ public void waitUntilTitleIs(final String title, String...params) { if (message == null) { message = String.format("Title '%s' did not appear in ", title); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - String currentTitle = browserManagement.getTitle(); - return currentTitle != null && currentTitle.equals(title); - } + waitUntil(timeout, message, () -> { + String currentTitle = browserManagement.getTitle(); + return currentTitle != null && currentTitle.equals(title); }); } @@ -396,13 +314,9 @@ public void waitUntilTitleIsNot(final String title, String...params) { if (message == null) { message = String.format("Title '%s' did not appear in ", title); } - waitUntil(timeout, message, new WaitUntilFunction() { - - @Override - public boolean isFinished() { - String currentTitle = browserManagement.getTitle(); - return currentTitle == null || !currentTitle.equals(title); - } + waitUntil(timeout, message, () -> { + String currentTitle = browserManagement.getTitle(); + return currentTitle == null || !currentTitle.equals(title); }); } @@ -429,12 +343,12 @@ protected void waitUntil(String timestr, String message, WaitUntilFunction funct } try { Thread.sleep(200); - } catch (InterruptedException e) { + } catch (InterruptedException ignored) { } } } - protected static interface WaitUntilFunction { + protected interface WaitUntilFunction { boolean isFinished(); } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Window.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Window.java index fcf90ae..1fb90d8 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Window.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Window.java @@ -75,7 +75,7 @@ public List getWindowTitles() { @RobotKeyword("Returns and logs URLs of all known browser windows.") public List getLocations() { - List locations = new ArrayList(); + List locations = new ArrayList<>(); for (SessionIdAliasWebDriverTuple sessionIdAliasWebdriverTuple : browserManagement.getWebDriverCache().getWebDrivers()) { locations.add(sessionIdAliasWebdriverTuple.webDriver.getCurrentUrl()); } @@ -114,14 +114,13 @@ public void setWindowSize(String width, String height) { browserManagement.getWebDriverCache().getCurrent().manage().window() .setSize(new Dimension(Integer.parseInt(width), Integer.parseInt(height))); } - - + protected List toList(List items) { return toList(items, "item"); } protected List toList(List items, String what) { - List msg = new ArrayList(); + List msg = new ArrayList<>(); msg.add(String.format("Altogether %d %s%s.\n", items.size(), what, items.size() == 1 ? "" : "s")); for (int index = 0; index < items.size(); index++) { msg.add(String.format("%d: %s", index + 1, items.get(index))); diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/ElementFinder.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/ElementFinder.java index 2566cf0..f7f0fb0 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/ElementFinder.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/ElementFinder.java @@ -1,31 +1,24 @@ package com.github.markusbernhardt.seleniumlibrary.locators; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; - -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.SearchContext; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.python.util.PythonInterpreter; - import com.github.markusbernhardt.seleniumlibrary.SeleniumLibraryNonFatalException; import com.github.markusbernhardt.seleniumlibrary.keywords.Element; import com.github.markusbernhardt.seleniumlibrary.utils.Python; +import org.openqa.selenium.*; +import org.python.util.PythonInterpreter; + +import java.util.*; +import java.util.Map.Entry; public class ElementFinder { - protected final static Hashtable registeredLocationStrategies = new Hashtable(); + protected final static Hashtable registeredLocationStrategies = new Hashtable<>(); protected enum KeyAttrs { - DEFAULT("@id,@name"), A("@id,@name,@href,normalize-space(descendant-or-self::text())"), IMG( - "@id,@name,@src,@alt"), INPUT("@id,@name,@value,@src"), BUTTON( - "@id,@name,@value,normalize-space(descendant-or-self::text())"); + DEFAULT("@id,@name"), + A("@id,@name,@href,normalize-space(descendant-or-self::text())"), + IMG("@id,@name,@src,@alt"), + INPUT("@id,@name,@value,@src"), + BUTTON("@id,@name,@value,normalize-space(descendant-or-self::text())"); protected String[] keyAttrs; @@ -40,8 +33,7 @@ public String[] getKeyAttrs() { protected interface Strategy { List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates); - - }; + } protected enum StrategyEnum implements Strategy { DEFAULT { @@ -150,7 +142,7 @@ protected static List filterElements(List elements, Find return elements; } - List result = new ArrayList(); + List result = new ArrayList<>(); for (WebElement element : elements) { if (elementMatches(element, findByCoordinates)) { result.add(element); @@ -189,13 +181,13 @@ protected static List findByKeyAttrs(WebDriver webDriver, FindByCoor if (findByCoordinates.tag == null) { xpathTag = "*"; } - List xpathConstraints = new ArrayList(); + List xpathConstraints = new ArrayList<>(); if (findByCoordinates.constraints != null) { for (Entry entry : findByCoordinates.constraints.entrySet()) { xpathConstraints.add(String.format("@%s='%s'", entry.getKey(), entry.getValue())); } } - List xpathSearchers = new ArrayList(); + List xpathSearchers = new ArrayList<>(); for (String attr : keyAttrs.getKeyAttrs()) { xpathSearchers.add(String.format("%s=%s", attr, xpathCriteria)); } @@ -207,7 +199,7 @@ protected static List findByKeyAttrs(WebDriver webDriver, FindByCoor } protected static List getAttrsWithUrl(WebDriver webDriver, KeyAttrs keyAttrs, String criteria) { - List attrs = new ArrayList(); + List attrs = new ArrayList<>(); String url = null; String xpathUrl = null; String[] srcHref = { "@src", "@href" }; @@ -252,19 +244,15 @@ public static List find(WebDriver webDriver, String locator, String FindByCoordinates findByCoordinates = new FindByCoordinates(); Strategy strategy = parseLocator(findByCoordinates, locator); - parseTag(findByCoordinates, strategy, tag); + parseTag(findByCoordinates, tag); return strategy.findBy(webDriver, findByCoordinates); } - protected static ThreadLocal loggingPythonInterpreter = new ThreadLocal() { - - @Override - protected PythonInterpreter initialValue() { - PythonInterpreter pythonInterpreter = new PythonInterpreter(); - pythonInterpreter.exec("from robot.libraries.BuiltIn import BuiltIn; from robot.api import logger;"); - return pythonInterpreter; - } - }; + protected static ThreadLocal loggingPythonInterpreter = ThreadLocal.withInitial(() -> { + PythonInterpreter pythonInterpreter = new PythonInterpreter(); + pythonInterpreter.exec("from robot.libraries.BuiltIn import BuiltIn; from robot.api import logger;"); + return pythonInterpreter; + }); protected static void warn(String msg) { loggingPythonInterpreter.get().exec( @@ -301,33 +289,43 @@ protected static Strategy parseLocator(FindByCoordinates findByCoordinates, Stri return strategy; } - protected static void parseTag(FindByCoordinates findByCoordinates, Strategy strategy, String tag) { + protected static void parseTag(FindByCoordinates findByCoordinates, String tag) { if (tag == null) { return; } + tag = tag.toLowerCase(); - Map constraints = new TreeMap(); - if (tag.equals("link")) { - tag = "a"; - } else if (tag.equals("image")) { - tag = "img"; - } else if (tag.equals("list")) { - tag = "select"; - } else if (tag.equals("text area")) { - tag = "textarea"; - } else if (tag.equals("radio button")) { - tag = "input"; - constraints.put("type", "radio"); - } else if (tag.equals("checkbox")) { - tag = "input"; - constraints.put("type", "checkbox"); - } else if (tag.equals("text field")) { - tag = "input"; - constraints.put("type", "text"); - } else if (tag.equals("file upload")) { - tag = "input"; - constraints.put("type", "file"); - } + Map constraints = new TreeMap<>(); + switch (tag) { + case "link": + tag = "a"; + break; + case "image": + tag = "img"; + break; + case "list": + tag = "select"; + break; + case "text area": + tag = "textarea"; + break; + case "radio button": + tag = "input"; + constraints.put("type", "radio"); + break; + case "checkbox": + tag = "input"; + constraints.put("type", "checkbox"); + break; + case "text field": + tag = "input"; + constraints.put("type", "text"); + break; + case "file upload": + tag = "input"; + constraints.put("type", "file"); + break; + } findByCoordinates.tag = tag; findByCoordinates.constraints = constraints; } @@ -337,7 +335,7 @@ protected static List toList(Object o) { if (o instanceof List) { return (List) o; } - List list = new ArrayList(); + List list = new ArrayList<>(); if (o instanceof WebElement) { list.add((WebElement) o); return list; @@ -369,16 +367,14 @@ public List findBy(final WebDriver webDriver, final FindByCoordinate @Override public List findElements(SearchContext context) { - Object[] arguments = null; + Object[] arguments; if (delimiter == null) { arguments = new Object[1]; arguments[0] = findByCoordinates.criteria; } else { String[] splittedCriteria = findByCoordinates.criteria.split(delimiter); arguments = new Object[splittedCriteria.length]; - for (int i = 0; i < splittedCriteria.length; i++) { - arguments[i] = splittedCriteria[i]; - } + System.arraycopy(splittedCriteria, 0, arguments, 0, splittedCriteria.length); } Object o = ((JavascriptExecutor) webDriver).executeScript(functionDefinition, arguments); return toList(o); diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/TableElementFinder.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/TableElementFinder.java index 61b4143..82ca493 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/TableElementFinder.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/TableElementFinder.java @@ -1,9 +1,6 @@ package com.github.markusbernhardt.seleniumlibrary.locators; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; @@ -13,7 +10,7 @@ public class TableElementFinder { protected final static TreeMap> locatorSuffixesMap; static { - locatorSuffixesMap = new TreeMap>(); + locatorSuffixesMap = new TreeMap<>(); addLocatorSuffix(locatorSuffixesMap, "css.default", ""); addLocatorSuffix(locatorSuffixesMap, "css.content", ""); addLocatorSuffix(locatorSuffixesMap, "css.header", " th"); @@ -58,7 +55,7 @@ public static WebElement findByFooter(WebDriver webDriver, String tableLocator, public static WebElement findByRow(WebDriver webDriver, String tableLocator, int row, String content) { List locators = parseTableLocator(tableLocator, "row"); - List formattedLocators = new ArrayList(); + List formattedLocators = new ArrayList<>(); for (String locator : locators) { formattedLocators.add(String.format(locator, Integer.toString(row))); } @@ -67,7 +64,7 @@ public static WebElement findByRow(WebDriver webDriver, String tableLocator, int public static WebElement findByCol(WebDriver webDriver, String tableLocator, int col, String content) { List locators = parseTableLocator(tableLocator, "col"); - List formattedLocators = new ArrayList(); + List formattedLocators = new ArrayList<>(); for (String locator : locators) { formattedLocators.add(String.format(locator, Integer.toString(col))); } @@ -75,15 +72,12 @@ public static WebElement findByCol(WebDriver webDriver, String tableLocator, int } protected static void addLocatorSuffix(Map> locatorSuffixesMap, String key, String... values) { - List list = new ArrayList(); - for (String value : values) { - list.add(value); - } + List list = new ArrayList<>(Arrays.asList(values)); locatorSuffixesMap.put(key, list); } protected static List parseTableLocator(String tableLocator, String locationMethod) { - String tableLocatorType = null; + String tableLocatorType; if (tableLocator.startsWith("xpath=") || tableLocator.startsWith("xpath:")) { tableLocatorType = "xpath."; @@ -99,7 +93,7 @@ protected static List parseTableLocator(String tableLocator, String loca List locatorSuffixes = locatorSuffixesMap.get(tableLocatorType + locationMethod); - List parsedTabeLocators = new ArrayList(); + List parsedTabeLocators = new ArrayList<>(); for (String locatorSuffix : locatorSuffixes) { parsedTabeLocators.add(tableLocator + locatorSuffix); } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/WindowManager.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/WindowManager.java index 4e6956d..787464e 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/WindowManager.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/WindowManager.java @@ -29,13 +29,13 @@ public void select(WebDriver webDriver, SelectCoordinates selectCoordinates) { try { NAME.select(webDriver, selectCoordinates); return; - } catch (Throwable t) { + } catch (Throwable ignored) { } try { TITLE.select(webDriver, selectCoordinates); return; - } catch (Throwable t) { + } catch (Throwable ignored) { } throw new SeleniumLibraryNonFatalException("Unable to locate window with name or title '" + selectCoordinates.criteria + "'"); @@ -45,45 +45,24 @@ public void select(WebDriver webDriver, SelectCoordinates selectCoordinates) { @Override public void select(WebDriver webDriver, final SelectCoordinates selectCoordinates) { - selectMatching(webDriver, new Matcher() { - - @Override - public boolean match(List currentWindowInfo) { - return currentWindowInfo.get(WINDOW_INFO_INDEX_DOCUMENT_TITLE).trim().toLowerCase() - .equals(selectCoordinates.criteria.toLowerCase()); - } - - }, "Unable to locate window with title '" + selectCoordinates.criteria + "'"); + selectMatching(webDriver, currentWindowInfo -> currentWindowInfo.get(WINDOW_INFO_INDEX_DOCUMENT_TITLE).trim().toLowerCase() + .equals(selectCoordinates.criteria.toLowerCase()), "Unable to locate window with title '" + selectCoordinates.criteria + "'"); } }, NAME { @Override public void select(WebDriver webDriver, final SelectCoordinates selectCoordinates) { - selectMatching(webDriver, new Matcher() { - - @Override - public boolean match(List currentWindowInfo) { - return currentWindowInfo.get(WINDOW_INFO_INDEX_WINDOW_NAME).trim().toLowerCase() - .equals(selectCoordinates.criteria.toLowerCase()); - } - - }, "Unable to locate window with name '" + selectCoordinates.criteria + "'"); + selectMatching(webDriver, currentWindowInfo -> currentWindowInfo.get(WINDOW_INFO_INDEX_WINDOW_NAME).trim().toLowerCase() + .equals(selectCoordinates.criteria.toLowerCase()), "Unable to locate window with name '" + selectCoordinates.criteria + "'"); } }, URL { @Override public void select(WebDriver webDriver, final SelectCoordinates selectCoordinates) { - selectMatching(webDriver, new Matcher() { - - @Override - public boolean match(List currentWindowInfo) { - return currentWindowInfo.get(WINDOW_INFO_INDEX_DOCUMENT_URL).trim().toLowerCase() - .equals(selectCoordinates.criteria.toLowerCase()); - } - - }, "Unable to locate window with URL '" + selectCoordinates.criteria + "'"); + selectMatching(webDriver, currentWindowInfo -> currentWindowInfo.get(WINDOW_INFO_INDEX_DOCUMENT_URL).trim().toLowerCase() + .equals(selectCoordinates.criteria.toLowerCase()), "Unable to locate window with URL '" + selectCoordinates.criteria + "'"); } }; @@ -112,7 +91,7 @@ protected static void selectMatching(WebDriver webDriver, Matcher matcher, Strin } public static List getWindowIds(WebDriver webDriver) { - List windowIds = new ArrayList(); + List windowIds = new ArrayList<>(); for (List windowInfo : getWindowInfos(webDriver)) { windowIds.add(windowInfo.get(0)); } @@ -120,7 +99,7 @@ public static List getWindowIds(WebDriver webDriver) { } public static List getWindowNames(WebDriver webDriver) { - List windowNames = new ArrayList(); + List windowNames = new ArrayList<>(); for (List windowInfo : getWindowInfos(webDriver)) { windowNames.add(windowInfo.get(1)); } @@ -128,7 +107,7 @@ public static List getWindowNames(WebDriver webDriver) { } public static List getWindowTitles(WebDriver webDriver) { - List windowTitles = new ArrayList(); + List windowTitles = new ArrayList<>(); for (List windowInfo : getWindowInfos(webDriver)) { windowTitles.add(windowInfo.get(2)); } @@ -143,7 +122,7 @@ public static List> getWindowInfos(WebDriver webDriver) { // Window of current WebDriver instance is already closed } - List> windowInfos = new ArrayList>(); + List> windowInfos = new ArrayList<>(); try { for (String handle : webDriver.getWindowHandles()) { webDriver.switchTo().window(handle); @@ -199,13 +178,10 @@ protected static List getCurrentWindowInfo(WebDriver webDriver) { } protected static class SelectCoordinates { - String criteria; } - protected static interface Matcher { - + protected interface Matcher { boolean match(List currentWindowInfo); - } } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/utils/Python.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/utils/Python.java index 48605b3..14fcc03 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/utils/Python.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/utils/Python.java @@ -33,7 +33,7 @@ public static Map zip(List keys, List values) { return null; } - Map map = new HashMap(); + Map map = new HashMap<>(); Iterator valueIterator = values.listIterator(); for (A key : keys) { map.put(key, valueIterator.next()); @@ -50,7 +50,7 @@ public static String osPathDirname(String path) { int index = path.lastIndexOf(File.separatorChar) + 1; String head = path.substring(0, index); if (head.length() != 0) { - String regex = ""; + String regex; if (File.separatorChar == '/') { regex = String.format("/{%d}", head.length()); } else { diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/utils/WebDriverCache.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/utils/WebDriverCache.java index f39d4a1..0668232 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/utils/WebDriverCache.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/utils/WebDriverCache.java @@ -24,22 +24,22 @@ public class WebDriverCache { /** * Stack of currently open session ids to reuse */ - Stack openSessionIds = new Stack(); + Stack openSessionIds = new Stack<>(); /** * Stack of already closed session ids to reuse */ - Stack closedSessionIds = new Stack(); + Stack closedSessionIds = new Stack<>(); /** * Map session ids to webdrivers */ - Map tupleBySessionId = new TreeMap(); + Map tupleBySessionId = new TreeMap<>(); /** * Map aliases to webdrivers */ - Map tupleByAlias = new TreeMap(); + Map tupleByAlias = new TreeMap<>(); public String register(WebDriver webDriver, String alias) { // create the new tuple @@ -104,10 +104,10 @@ public void closeAll() { } maxAssignedSessionId = 0; currentSessionIdAliasWebDriverTuple = null; - openSessionIds = new Stack(); - closedSessionIds = new Stack(); - tupleBySessionId = new TreeMap(); - tupleByAlias = new TreeMap(); + openSessionIds = new Stack<>(); + closedSessionIds = new Stack<>(); + tupleBySessionId = new TreeMap<>(); + tupleByAlias = new TreeMap<>(); } public void switchBrowser(String sessionIdOrAlias) { From c7961e0f0cab95501d319d4a68cd5ef80070486d Mon Sep 17 00:00:00 2001 From: YauheniPo Date: Sat, 27 Jul 2019 18:48:02 +0300 Subject: [PATCH 14/23] Code refactoring --- .../markusbernhardt/seleniumlibrary/keywords/SelectElement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java index 76feb8b..8f4c3ab 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java @@ -142,7 +142,7 @@ public void listShouldHaveNoSelections(String locator) { logging.info(String.format("Verifying list '%s' has no selection.", locator)); List options = getSelectListOptionsSelected(locator); - if (options != null) { + if (!options.isEmpty()) { List selectedLabels = getLabelsForOptions(options); String items = Python.join(" | ", selectedLabels); throw new SeleniumLibraryNonFatalException(String.format( From 15982cc9968164a3d586764a9eb974ccb4157afc Mon Sep 17 00:00:00 2001 From: YauheniPo Date: Sun, 28 Jul 2019 01:01:33 +0300 Subject: [PATCH 15/23] Added keywords for data utils --- .../CustomRobotDriverElement.java | 9 +-- .../seleniumlibrary/keywords/DataUtils.java | 64 +++++++++++++++++++ .../seleniumlibrary/keywords/Element.java | 4 +- 3 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/DataUtils.java diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/CustomRobotDriverElement.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/CustomRobotDriverElement.java index 2f2d194..5a20a16 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/CustomRobotDriverElement.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/CustomRobotDriverElement.java @@ -1,6 +1,7 @@ package com.github.markusbernhardt.seleniumlibrary; import com.github.markusbernhardt.seleniumlibrary.keywords.BrowserManagement; +import com.github.markusbernhardt.seleniumlibrary.keywords.Logging; import com.github.markusbernhardt.seleniumlibrary.keywords.Robot; import org.openqa.selenium.WebDriver; @@ -16,7 +17,8 @@ public class CustomRobotDriverElement { private static SeleniumLibrary s; private static BrowserManagement b; - private Robot robot = new Robot(); + protected Robot robot = new Robot(); + protected Logging logging = new Logging(); public CustomRobotDriverElement() throws NoSuchFieldException, IllegalAccessException { try { @@ -41,9 +43,4 @@ private static SeleniumLibrary getLibraryInstance() throws ScriptException { protected WebDriver getCurrentBrowser() { return b.getCurrentWebDriver(); } - - protected Robot getRobot() { - return robot; - } - } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/DataUtils.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/DataUtils.java new file mode 100644 index 0000000..912ccbb --- /dev/null +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/DataUtils.java @@ -0,0 +1,64 @@ +package com.github.markusbernhardt.seleniumlibrary.keywords; + +import com.github.markusbernhardt.seleniumlibrary.RunOnFailureKeywordsAdapter; +import org.robotframework.javalib.annotation.ArgumentNames; +import org.robotframework.javalib.annotation.Autowired; +import org.robotframework.javalib.annotation.RobotKeyword; +import org.robotframework.javalib.annotation.RobotKeywords; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@RobotKeywords +public class DataUtils extends RunOnFailureKeywordsAdapter { + + private static final String ASCENDING = "ascending"; + private static final String DESCENDING = "descending"; + + @Autowired + protected Robot robot; + + /** + * Instantiated Logging keyword bean + */ + @Autowired + protected Logging logging; + + // ############################## + // Keywords + // ############################## + + @RobotKeyword + @ArgumentNames({"list", "order=ascending"}) + public List sortStringList(String listToString, String... params) { + List listOfStrings = robot.parseRobotList(listToString); + String order = robot.getParamsValue(params, 0, ASCENDING); + List sortedList = new ArrayList<>(listOfStrings); + if (order.equalsIgnoreCase(DESCENDING)) { + listOfStrings.sort(Collections.reverseOrder()); + } else { + Collections.sort(listOfStrings); + } + logging.info(String.format("Sorted list '%s' by %s", sortedList, order.toUpperCase())); + return sortedList; + } + + @RobotKeyword + @ArgumentNames({"text", "regExpPattern", "groupIndex"}) + public String getStringByRegexpGroup(String text, String regExpPattern, int groupIndex) { + Matcher matcher = Pattern.compile(regExpPattern).matcher(text); + matcher.find(); + String matchedText = matcher.group(groupIndex); + logging.info(String.format("Matched text '%s' by pattern '%s' and group index '%d' from the text '%s'", matchedText, regExpPattern, groupIndex, text)); + return matchedText; + } + + @RobotKeyword + @ArgumentNames({"text", "regExpPattern"}) + public boolean isTextMatchPattern(String text, String regExpPattern) { + return Pattern.compile(regExpPattern).matcher(text).matches(); + } +} diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java index a8c3ac4..ff74415 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java @@ -934,8 +934,8 @@ public void xpathShouldMatchXTimes(String xpath, int expectedXpathCount, String. @RobotKeyword("Click to element from list elements by locator ``xpath``.") @ArgumentNames({"xpath", "index=0", "message=NONE"}) public void clickElementByIndex(String xpath, String... params) { - String message = robot.getParamsValue(params, 0, ""); - int index = robot.getParamsValue(params, 1, 0); + int index = robot.getParamsValue(params, 0, 0); + String message = robot.getParamsValue(params, 1, ""); List elements = elementFind(xpath, false, false); if (elements.isEmpty()) { if (message.isEmpty()) { From 9b83f269c7a08ce7b0896a92b8e418d7ea848fe5 Mon Sep 17 00:00:00 2001 From: YauheniPo Date: Sun, 28 Jul 2019 22:17:42 +0300 Subject: [PATCH 16/23] Corrected by review comments --- .../seleniumlibrary/keywords/Cookie.java | 2 +- .../keywords/SelectElement.java | 5 +- .../seleniumlibrary/keywords/Waiting.java | 119 ++++++++++++------ .../locators/ElementFinder.java | 60 ++++----- .../locators/TableElementFinder.java | 3 +- .../locators/WindowManager.java | 19 ++- 6 files changed, 133 insertions(+), 75 deletions(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Cookie.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Cookie.java index 4fd1939..7f4d0bd 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Cookie.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Cookie.java @@ -47,7 +47,7 @@ public String getCookies() { ArrayList cookies = new ArrayList<>(browserManagement .getCurrentWebDriver().manage().getCookies()); for (int i = 0; i < cookies.size(); i++) { - ret.append(cookies.get(i).getName()).append("=").append(cookies.get(i).getValue()); + ret.append(cookies.get(i).getName()).append('=').append(cookies.get(i).getValue()); if (i != cookies.size() - 1) { ret.append("; "); } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java index 8f4c3ab..8ba69cb 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/SelectElement.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.openqa.selenium.NoSuchElementException; @@ -222,6 +223,7 @@ public void selectFromList(String locator, String... items) { } catch (NoSuchElementException e2) { nonExistingItems.add(item); lastItemFound = false; + continue; } } } @@ -256,7 +258,8 @@ public void selectFromListByIndex(String locator, String... indexes) { throw new SeleniumLibraryNonFatalException("No index given."); } - List tmp = new ArrayList<>(Arrays.asList(indexes)); + List tmp = new ArrayList<>(); + Collections.addAll(tmp, indexes); String items = String.format("index(es) '%s'", Python.join(", ", tmp)); logging.info(String.format("Selecting %s from list '%s'.", items, locator)); diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Waiting.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Waiting.java index 7a8c0e1..e8a735c 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Waiting.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Waiting.java @@ -1,5 +1,8 @@ package com.github.markusbernhardt.seleniumlibrary.keywords; +import com.github.markusbernhardt.seleniumlibrary.RunOnFailureKeywordsAdapter; +import com.github.markusbernhardt.seleniumlibrary.SeleniumLibraryNonFatalException; +import com.github.markusbernhardt.seleniumlibrary.utils.Robotframework; import org.apache.commons.lang3.exception.ExceptionUtils; import org.openqa.selenium.JavascriptExecutor; import org.robotframework.javalib.annotation.ArgumentNames; @@ -7,10 +10,6 @@ import org.robotframework.javalib.annotation.RobotKeyword; import org.robotframework.javalib.annotation.RobotKeywords; -import com.github.markusbernhardt.seleniumlibrary.RunOnFailureKeywordsAdapter; -import com.github.markusbernhardt.seleniumlibrary.SeleniumLibraryNonFatalException; -import com.github.markusbernhardt.seleniumlibrary.utils.Robotframework; - @RobotKeywords public class Waiting extends RunOnFailureKeywordsAdapter { @@ -52,8 +51,10 @@ public void waitForCondition(final String condition, String...params) { if (message == null) { message = String.format("Condition '%s' did not become true in ", condition); } - waitUntil(timeout, message, () -> Boolean.TRUE.equals(((JavascriptExecutor) browserManagement.getCurrentWebDriver()) - .executeScript(condition))); + waitUntil( + timeout, + message, + () -> Boolean.TRUE.equals(((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeScript(condition))); } @RobotKeyword("Waits until the current page contains ``text``.\r\n" + @@ -68,7 +69,10 @@ public void waitUntilPageContains(final String text, String...params) { if (message == null) { message = String.format("Text '%s' did not appear in ", text); } - waitUntil(timeout, message, () -> element.isTextPresent(text)); + waitUntil( + timeout, + message, + () -> element.isTextPresent(text)); } @RobotKeyword("Waits until the current page does not contain ``text``.\r\n" + @@ -83,7 +87,10 @@ public void waitUntilPageNotContains(final String text, String...params) { if (message == null) { message = String.format("Text '%s' did not disappear in ", text); } - waitUntil(timeout, message, () -> !element.isTextPresent(text)); + waitUntil( + timeout, + message, + () -> !element.isTextPresent(text)); } @RobotKeyword("Waits until the current page does not contain ``text``.\r\n" + @@ -110,7 +117,10 @@ public void waitUntilPageContainsElement(final String locator, String...params) if (message == null) { message = String.format("Element '%s' did not appear in ", locator); } - waitUntil(timeout, message, () -> element.isElementPresent(locator)); + waitUntil( + timeout, + message, + () -> element.isElementPresent(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not found on the current page.\r\n" + @@ -125,7 +135,10 @@ public void waitUntilPageNotContainsElement(final String locator, String...param if (message == null) { message = String.format("Element '%s' did not disappear in ", locator); } - waitUntil(timeout, message, () -> !element.isElementPresent(locator)); + waitUntil( + timeout, + message, + () -> !element.isElementPresent(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not found on the current page.\r\n" + @@ -152,7 +165,10 @@ public void waitUntilElementIsVisible(final String locator, String...params) { if (message == null) { message = String.format("Element '%s' not visible in ", locator); } - waitUntil(timeout, message, () -> element.isVisible(locator)); + waitUntil( + timeout, + message, + () -> element.isVisible(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not visible.\r\n" + @@ -167,7 +183,10 @@ public void waitUntilElementIsNotVisible(final String locator, String...params) if (message == null) { message = String.format("Element '%s' still visible in ", locator); } - waitUntil(timeout, message, () -> !element.isVisible(locator)); + waitUntil( + timeout, + message, + () -> !element.isVisible(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is clickable.\r\n" + @@ -182,7 +201,10 @@ public void waitUntilElementIsClickable(final String locator, String...params) { if (message == null) { message = String.format("Element '%s' not clickable in ", locator); } - waitUntil(timeout, message, () -> element.isClickable(locator)); + waitUntil( + timeout, + message, + () -> element.isClickable(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not clickable.\r\n" + @@ -197,7 +219,10 @@ public void waitUntilElementIsNotClickable(final String locator, String...params if (message == null) { message = String.format("Element '%s' still clickable in ", locator); } - waitUntil(timeout, message, () -> !element.isClickable(locator)); + waitUntil( + timeout, + message, + () -> !element.isClickable(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is succesfully clicked on.\r\n" + @@ -212,10 +237,13 @@ public void waitUntilElementIsSuccessfullyClicked(final String locator, String.. if (message == null) { message = String.format("Element '%s' not successfully clicked in ", locator); } - waitUntil(timeout, message, () -> { - element.clickElement(locator); - return true; - }); + waitUntil( + timeout, + message, + () -> { + element.clickElement(locator); + return true; + }); } @RobotKeyword("Waits until the element identified by ``locator`` is selected.\r\n" + @@ -230,7 +258,10 @@ public void waitUntilElementIsSelected(final String locator, String...params) { if (message == null) { message = String.format("Element '%s' not selected in ", locator); } - waitUntil(timeout, message, () -> element.isSelected(locator)); + waitUntil( + timeout, + message, + () -> element.isSelected(locator)); } @RobotKeyword("Waits until the element identified by ``locator`` is not selected.\r\n" + @@ -245,7 +276,10 @@ public void waitUntilElementIsNotSelected(final String locator, String...params) if (message == null) { message = String.format("Element '%s' still selected in ", locator); } - waitUntil(timeout, message, () -> !element.isSelected(locator)); + waitUntil( + timeout, + message, + () -> !element.isSelected(locator)); } @RobotKeyword("Waits until the current page title contains ``title``.\r\n" + @@ -260,10 +294,13 @@ public void waitUntilTitleContains(final String title, String...params) { if (message == null) { message = String.format("Title '%s' did not appear in ", title); } - waitUntil(timeout, message, () -> { - String currentTitle = browserManagement.getTitle(); - return currentTitle != null && currentTitle.contains(title); - }); + waitUntil( + timeout, + message, + () -> { + String currentTitle = browserManagement.getTitle(); + return currentTitle != null && currentTitle.contains(title); + }); } @RobotKeyword("Waits until the current page title does not contain ``title``.\r\n" + @@ -278,10 +315,13 @@ public void waitUntilTitleNotContains(final String title, String...params) { if (message == null) { message = String.format("Title '%s' did not appear in ", title); } - waitUntil(timeout, message, () -> { - String currentTitle = browserManagement.getTitle(); - return currentTitle == null || !currentTitle.contains(title); - }); + waitUntil( + timeout, + message, + () -> { + String currentTitle = browserManagement.getTitle(); + return currentTitle == null || !currentTitle.contains(title); + }); } @RobotKeyword("Waits until the current page title is exactly ``title``.\r\n" + @@ -296,10 +336,13 @@ public void waitUntilTitleIs(final String title, String...params) { if (message == null) { message = String.format("Title '%s' did not appear in ", title); } - waitUntil(timeout, message, () -> { - String currentTitle = browserManagement.getTitle(); - return currentTitle != null && currentTitle.equals(title); - }); + waitUntil( + timeout, + message, + () -> { + String currentTitle = browserManagement.getTitle(); + return currentTitle != null && currentTitle.equals(title); + }); } @RobotKeyword("Waits until the current page title is not exactly ``title``.\r\n" + @@ -314,10 +357,13 @@ public void waitUntilTitleIsNot(final String title, String...params) { if (message == null) { message = String.format("Title '%s' did not appear in ", title); } - waitUntil(timeout, message, () -> { - String currentTitle = browserManagement.getTitle(); - return currentTitle == null || !currentTitle.equals(title); - }); + waitUntil( + timeout, + message, + () -> { + String currentTitle = browserManagement.getTitle(); + return currentTitle == null || !currentTitle.equals(title); + }); } // ############################## @@ -348,6 +394,7 @@ protected void waitUntil(String timestr, String message, WaitUntilFunction funct } } + @FunctionalInterface protected interface WaitUntilFunction { boolean isFinished(); diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/ElementFinder.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/ElementFinder.java index f7f0fb0..347886a 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/ElementFinder.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/ElementFinder.java @@ -296,36 +296,36 @@ protected static void parseTag(FindByCoordinates findByCoordinates, String tag) tag = tag.toLowerCase(); Map constraints = new TreeMap<>(); - switch (tag) { - case "link": - tag = "a"; - break; - case "image": - tag = "img"; - break; - case "list": - tag = "select"; - break; - case "text area": - tag = "textarea"; - break; - case "radio button": - tag = "input"; - constraints.put("type", "radio"); - break; - case "checkbox": - tag = "input"; - constraints.put("type", "checkbox"); - break; - case "text field": - tag = "input"; - constraints.put("type", "text"); - break; - case "file upload": - tag = "input"; - constraints.put("type", "file"); - break; - } + switch(tag) { + case "link": + tag = "a"; + break; + case "image": + tag = "img"; + break; + case "list": + tag = "select"; + break; + case "text area": + tag = "textarea"; + break; + case "radio button": + tag = "input"; + constraints.put("type", "radio"); + break; + case "checkbox": + tag = "input"; + constraints.put("type", "checkbox"); + break; + case "text field": + tag = "input"; + constraints.put("type", "text"); + break; + case "file upload": + tag = "input"; + constraints.put("type", "file"); + break; + } findByCoordinates.tag = tag; findByCoordinates.constraints = constraints; } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/TableElementFinder.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/TableElementFinder.java index 82ca493..02ec4ed 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/TableElementFinder.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/TableElementFinder.java @@ -72,7 +72,8 @@ public static WebElement findByCol(WebDriver webDriver, String tableLocator, int } protected static void addLocatorSuffix(Map> locatorSuffixesMap, String key, String... values) { - List list = new ArrayList<>(Arrays.asList(values)); + List list = new ArrayList<>(); + Collections.addAll(list, values); locatorSuffixesMap.put(key, list); } diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/WindowManager.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/WindowManager.java index 787464e..2d59c3a 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/WindowManager.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/locators/WindowManager.java @@ -45,24 +45,31 @@ public void select(WebDriver webDriver, SelectCoordinates selectCoordinates) { @Override public void select(WebDriver webDriver, final SelectCoordinates selectCoordinates) { - selectMatching(webDriver, currentWindowInfo -> currentWindowInfo.get(WINDOW_INFO_INDEX_DOCUMENT_TITLE).trim().toLowerCase() - .equals(selectCoordinates.criteria.toLowerCase()), "Unable to locate window with title '" + selectCoordinates.criteria + "'"); + String selectionCriteria = selectCoordinates.criteria; + selectMatching(webDriver, + currentWindowInfo -> currentWindowInfo.get(WINDOW_INFO_INDEX_DOCUMENT_TITLE).trim() + .equalsIgnoreCase(selectionCriteria), + String.format("Unable to locate window with title '%s'", selectionCriteria)); } }, NAME { @Override public void select(WebDriver webDriver, final SelectCoordinates selectCoordinates) { - selectMatching(webDriver, currentWindowInfo -> currentWindowInfo.get(WINDOW_INFO_INDEX_WINDOW_NAME).trim().toLowerCase() - .equals(selectCoordinates.criteria.toLowerCase()), "Unable to locate window with name '" + selectCoordinates.criteria + "'"); + String selectionCriteria = selectCoordinates.criteria; + selectMatching(webDriver, + currentWindowInfo -> currentWindowInfo.get(WINDOW_INFO_INDEX_WINDOW_NAME).trim().equalsIgnoreCase(selectionCriteria), + String.format("Unable to locate window with name '%s'", selectionCriteria)); } }, URL { @Override public void select(WebDriver webDriver, final SelectCoordinates selectCoordinates) { - selectMatching(webDriver, currentWindowInfo -> currentWindowInfo.get(WINDOW_INFO_INDEX_DOCUMENT_URL).trim().toLowerCase() - .equals(selectCoordinates.criteria.toLowerCase()), "Unable to locate window with URL '" + selectCoordinates.criteria + "'"); + String selectionCriteria = selectCoordinates.criteria; + selectMatching(webDriver, + currentWindowInfo -> currentWindowInfo.get(WINDOW_INFO_INDEX_DOCUMENT_URL).trim().equalsIgnoreCase(selectionCriteria), + String.format("Unable to locate window with URL '%s'", selectionCriteria)); } }; From 6293b92cce3937ad12e793000c038b8e9d9b3c4c Mon Sep 17 00:00:00 2001 From: YauheniPo Date: Mon, 29 Jul 2019 00:01:39 +0300 Subject: [PATCH 17/23] Corrected by review comments --- .../seleniumlibrary/keywords/DataUtils.java | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/DataUtils.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/DataUtils.java index 912ccbb..e47f2fc 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/DataUtils.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/DataUtils.java @@ -9,8 +9,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.Locale; @RobotKeywords public class DataUtils extends RunOnFailureKeywordsAdapter { @@ -31,10 +30,17 @@ public class DataUtils extends RunOnFailureKeywordsAdapter { // Keywords // ############################## - @RobotKeyword + /** + * Sort list of strings. + * + * @param jsonStringOfList json string of list strings + * @param params sorting order + * @return sorting list of strings + */ + @RobotKeyword("Returns sorting list of strings by ``order``.") @ArgumentNames({"list", "order=ascending"}) - public List sortStringList(String listToString, String... params) { - List listOfStrings = robot.parseRobotList(listToString); + public List sortStrings(String jsonStringOfList, String... params) { + List listOfStrings = robot.parseRobotList(jsonStringOfList); String order = robot.getParamsValue(params, 0, ASCENDING); List sortedList = new ArrayList<>(listOfStrings); if (order.equalsIgnoreCase(DESCENDING)) { @@ -42,23 +48,7 @@ public List sortStringList(String listToString, String... params) { } else { Collections.sort(listOfStrings); } - logging.info(String.format("Sorted list '%s' by %s", sortedList, order.toUpperCase())); + logging.info(String.format("Sorted list '%s' by %s", sortedList, order.toUpperCase(Locale.ENGLISH))); return sortedList; } - - @RobotKeyword - @ArgumentNames({"text", "regExpPattern", "groupIndex"}) - public String getStringByRegexpGroup(String text, String regExpPattern, int groupIndex) { - Matcher matcher = Pattern.compile(regExpPattern).matcher(text); - matcher.find(); - String matchedText = matcher.group(groupIndex); - logging.info(String.format("Matched text '%s' by pattern '%s' and group index '%d' from the text '%s'", matchedText, regExpPattern, groupIndex, text)); - return matchedText; - } - - @RobotKeyword - @ArgumentNames({"text", "regExpPattern"}) - public boolean isTextMatchPattern(String text, String regExpPattern) { - return Pattern.compile(regExpPattern).matcher(text).matches(); - } } From d7a23e45cef7f855ace242b81a047490e1c49d00 Mon Sep 17 00:00:00 2001 From: schrm01 Date: Tue, 30 Jul 2019 15:56:51 +0200 Subject: [PATCH 18/23] Added the missing @RobotKeywordOverload. This annotation is needed to enable the overloading of the getElementByKeyword method in Robot Framework. --- .../seleniumlibrary/keywords/Element.java | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java index 1c0a2b6..654cc24 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java @@ -13,10 +13,7 @@ import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; -import org.robotframework.javalib.annotation.ArgumentNames; -import org.robotframework.javalib.annotation.Autowired; -import org.robotframework.javalib.annotation.RobotKeyword; -import org.robotframework.javalib.annotation.RobotKeywords; +import org.robotframework.javalib.annotation.*; import com.github.markusbernhardt.seleniumlibrary.RunOnFailureKeywordsAdapter; import com.github.markusbernhardt.seleniumlibrary.SeleniumLibraryNonFatalException; @@ -423,17 +420,9 @@ public void elementTextShouldNotBe(String locator, String text, String...params) } } - @RobotKeyword("Returns the value of an element attribute.\r\n" + - "\r\n" + - "The ``attribute_locator`` consists of element locator followed by an @ sign and attribute name. Example: element_id@class\r\n" + - "\r\n" + - "Key attributes for arbitrary elements are id and name. See `Introduction` for details about locators.\r\n" + - "\r\n" + - "Passing attribute name as part of the locator was removed in SeleniumLibrary 3.2. The explicit attribute argument should be used instead.") - @ArgumentNames({ "attributeLocator" }) - @Deprecated - public String getElementAttribute(String attributeLocator) { - String[] parts = parseAttributeLocator(attributeLocator); + @RobotKeywordOverload + public String getElementAttribute(String locator) { + String[] parts = parseAttributeLocator(locator); return getElementAttribute(parts[0], parts[1]); } @@ -444,7 +433,7 @@ public String getElementAttribute(String attributeLocator) { "Example: ${id}= Get Element Attribute css:h1 id\r\n" + "\r\n" + "Passing attribute name as part of the locator was removed in SeleniumLibrary 3.2. The explicit attribute argument should be used instead.") - @ArgumentNames({ "locator", "attribute" }) + @ArgumentNames({ "locator", "attribute=None" }) public String getElementAttribute(String locator, String attribute) { List elements = elementFind(locator, true, false); From 9e2f4f0d5873720a105153e94e62266ce40a3566 Mon Sep 17 00:00:00 2001 From: schrm01 Date: Mon, 5 Aug 2019 08:52:07 +0200 Subject: [PATCH 19/23] The attribute name is now determined dynamically, as per the comment from @YauheniPo. --- .../markusbernhardt/seleniumlibrary/keywords/Element.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java index 654cc24..334dc49 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java @@ -434,13 +434,14 @@ public String getElementAttribute(String locator) { "\r\n" + "Passing attribute name as part of the locator was removed in SeleniumLibrary 3.2. The explicit attribute argument should be used instead.") @ArgumentNames({ "locator", "attribute=None" }) - public String getElementAttribute(String locator, String attribute) { + public String getElementAttribute(String locator, String... attribute) { + String attributeName= robot.getParamsValue(attribute, 0, "None"); List elements = elementFind(locator, true, false); if (elements.size() == 0) { throw new SeleniumLibraryNonFatalException(String.format("Element '%s' not found.", locator)); } - return elements.get(0).getAttribute(attribute); + return elements.get(0).getAttribute(attributeName); } @RobotKeyword("Clears the text from element identified by ``locator``.\r\n" + From 786a4eb43d2b23387c43cf7266f0b2b34c41ed2e Mon Sep 17 00:00:00 2001 From: schrm01 Date: Mon, 5 Aug 2019 15:54:35 +0200 Subject: [PATCH 20/23] Formatting fix --- .../markusbernhardt/seleniumlibrary/keywords/Element.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java index 334dc49..01538f5 100644 --- a/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java +++ b/src/main/java/com/github/markusbernhardt/seleniumlibrary/keywords/Element.java @@ -435,7 +435,7 @@ public String getElementAttribute(String locator) { "Passing attribute name as part of the locator was removed in SeleniumLibrary 3.2. The explicit attribute argument should be used instead.") @ArgumentNames({ "locator", "attribute=None" }) public String getElementAttribute(String locator, String... attribute) { - String attributeName= robot.getParamsValue(attribute, 0, "None"); + String attributeName = robot.getParamsValue(attribute, 0, "None"); List elements = elementFind(locator, true, false); if (elements.size() == 0) { From 8e4cc942f627faef278fb98a449102bd52e365cf Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Mon, 26 Aug 2019 17:04:40 +0300 Subject: [PATCH 21/23] Release 3.141.59.2653 --- pom.xml | 2 +- .../robotframework/testsuites/UnitTests/WhatAreCookies.robot | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8f7a6b4..b9cc497 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.github.hi-fi robotframework-seleniumlibrary - 3.141.59.2653-SNAPSHOT + 3.141.59.2653 jar Robot Framework :: SeleniumLibrary diff --git a/src/test/robotframework/testsuites/UnitTests/WhatAreCookies.robot b/src/test/robotframework/testsuites/UnitTests/WhatAreCookies.robot index b589265..bfec181 100644 --- a/src/test/robotframework/testsuites/UnitTests/WhatAreCookies.robot +++ b/src/test/robotframework/testsuites/UnitTests/WhatAreCookies.robot @@ -5,5 +5,5 @@ Resource ../../settings/Settings.robot Cookies Open Browser http://www.whatarecookies.com/cookietest.asp ${browser} mainbrowser ${all_cookies}= Get Cookies - ${test}= Get Cookie Value __atuvc + ${test}= Get Cookie Value _ga Close Browser \ No newline at end of file From fed6f0e95b5cf5a365f8357a9976ec9ed7ff7e1e Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Mon, 26 Aug 2019 18:32:16 +0300 Subject: [PATCH 22/23] Bumb up --- README.md | 10 +++++----- pom.xml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e05745c..7d9a525 100644 --- a/README.md +++ b/README.md @@ -45,18 +45,18 @@ your pom.xml: com.github.hi-fi robotframework-seleniumlibrary - 3.141.59.265 + 3.141.59.2653 test If you cannot use the robotframework-maven-plugin you can use the -[jar-with-dependencies](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.265/robotframework-seleniumlibrary-3.141.59.265-jar-with-dependencies.jar), -which contains all required libraries. Running of tests with this can be done with command `java -jar robotframework-seleniumlibrary-3.141.59.265-jar-with-dependencies.jar `. +[jar-with-dependencies](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.2653/robotframework-seleniumlibrary-3.141.59.2653-jar-with-dependencies.jar), +which contains all required libraries. Running of tests with this can be done with command `java -jar robotframework-seleniumlibrary-3.141.59.2653-jar-with-dependencies.jar `. * More information about this library can be found in the - [Keyword Documentation](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.265/robotframework-seleniumlibrary-3.141.59.265.html). + [Keyword Documentation](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.2653/robotframework-seleniumlibrary-3.141.59.2653.html). * For keyword completion in RIDE you can download this - [Library Specs](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.265/robotframework-seleniumlibrary-3.141.59.265.xml) + [Library Specs](http://central.maven.org/maven2/com/github/hi-fi/robotframework-seleniumlibrary/3.141.59.2653/robotframework-seleniumlibrary-3.141.59.2653.xml) and place it in your PYTHONPATH. Differences diff --git a/pom.xml b/pom.xml index b9cc497..5a399c9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.github.hi-fi robotframework-seleniumlibrary - 3.141.59.2653 + 3.141.59.26535-SNAPSHOT jar Robot Framework :: SeleniumLibrary From 245c8fdd6c8aab351beddd42dbaa425e1e59240b Mon Sep 17 00:00:00 2001 From: Hi-Fi Date: Mon, 26 Aug 2019 21:12:10 +0300 Subject: [PATCH 23/23] Updated dependencies Exclusions to make dependencies to work with Selenium 4 --- README.md | 4 ---- pom.xml | 44 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1ab0833..97a61f0 100644 --- a/README.md +++ b/README.md @@ -116,11 +116,7 @@ to know when to update drivers you use. Drivers can also be fetched with [https://github.com/Ardesco/selenium-standalone-server-plugin|Selenium Driver Binary Downloader plugin]. -<<<<<<< HEAD -With Selenium 4 [https://github.com/bonigarcia/webdrivermanager|WebdriverManager] is taken to use, so handling of drivers can also be done with standalone JAR from tests itself. -======= With At 3.141.59.265 [https://github.com/bonigarcia/webdrivermanager|WebdriverManager] is taken to use, so handling of drivers can also be done with standalone JAR from tests itself. ->>>>>>> 6b856261db4247ab771ecfafe4912c36a508aef1 __ https://seleniumhq.github.io/selenium/docs/api/py/index.html#drivers __ https://en.wikipedia.org/wiki/PATH_(variable) diff --git a/pom.xml b/pom.xml index 3671d88..97ea92b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.github.hi-fi robotframework-seleniumlibrary - 4.0.0-alpha-1.0-SNAPSHOT + 4.0.0-alpha-2.0-SNAPSHOT jar Robot Framework :: SeleniumLibrary @@ -71,7 +71,7 @@ 1.8 1.5.1 3.1.2 - 4.0.0-alpha-1 + 4.0.0-alpha-2 SeleniumLibrary jbrowser False @@ -118,7 +118,7 @@ io.appium java-client - 7.0.0 + 7.2.0 org.seleniumhq.selenium @@ -139,12 +139,36 @@ com.machinepublishers jbrowserdriver - 1.1.0-RC1 + 1.1.0-RC2 + + + org.seleniumhq.selenium + selenium-remote-driver + + + org.seleniumhq.selenium + selenium-api + + org.seleniumhq.selenium htmlunit-driver - 2.35.1 + 2.36.0 + + + org.seleniumhq.selenium + selenium-remote-driver + + + org.seleniumhq.selenium + selenium-api + + + org.seleniumhq.selenium + selenium-support + + org.mockito @@ -155,7 +179,7 @@ io.github.bonigarcia webdrivermanager - 3.4.0 + 3.6.2 @@ -295,7 +319,7 @@ org.codehaus.mojo aspectj-maven-plugin - 1.10 + 1.11 @@ -325,7 +349,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.8.0 ${java.version} ${java.version} @@ -353,7 +377,7 @@ org.apache.maven.plugins maven-assembly-plugin - 2.6 + 3.1.0 @@ -446,7 +470,7 @@ org.codehaus.mojo build-helper-maven-plugin - 1.10 + 3.0.0 attach-artifacts