", link, link));
}
// ##############################
// Internal Methods
// ##############################
- private int screenshotIndex = 0;
+ protected int screenshotIndex = 0;
- private void writeScreenshot(File path, byte[] png) {
+ protected void writeScreenshot(File path, byte[] png) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(path);
fos.write(png);
fos.flush();
} catch (IOException e) {
- warn(String.format("Can't write screenshot '%s'",
- path.getAbsolutePath()));
+ logging.warn(String.format("Can't write screenshot '%s'", path.getAbsolutePath()));
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
- warn("Can't even close stream");
+ logging.warn("Can't even close stream");
}
}
}
}
- private String normalizeFilename(String filename) {
+ protected String normalizeFilename(String filename) {
if (filename == null) {
screenshotIndex++;
- filename = String.format("selenium-screenshot-%d.png",
- screenshotIndex);
+ filename = String.format("selenium-screenshot-%d.png", screenshotIndex);
} else {
filename = filename.replace('/', File.separatorChar);
}
diff --git a/src/main/java/com/github/markusbernhardt/selenium2library/keywords/SelectElement.java b/src/main/java/com/github/markusbernhardt/selenium2library/keywords/SelectElement.java
index 250dc92..41aaefb 100644
--- a/src/main/java/com/github/markusbernhardt/selenium2library/keywords/SelectElement.java
+++ b/src/main/java/com/github/markusbernhardt/selenium2library/keywords/SelectElement.java
@@ -6,130 +6,293 @@
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;
+import org.robotframework.javalib.annotation.ArgumentNames;
+import org.robotframework.javalib.annotation.Autowired;
+import org.robotframework.javalib.annotation.RobotKeyword;
+import org.robotframework.javalib.annotation.RobotKeywordOverload;
+import org.robotframework.javalib.annotation.RobotKeywords;
+import com.github.markusbernhardt.selenium2library.RunOnFailureKeywordsAdapter;
import com.github.markusbernhardt.selenium2library.Selenium2LibraryNonFatalException;
import com.github.markusbernhardt.selenium2library.utils.Python;
-public abstract class SelectElement extends Screenshot {
+@RobotKeywords
+public class SelectElement extends RunOnFailureKeywordsAdapter {
+
+ /**
+ * Instantiated Element keyword bean
+ */
+ @Autowired
+ protected Element element;
+
+ /**
+ * Instantiated Logging keyword bean
+ */
+ @Autowired
+ protected Logging logging;
// ##############################
// Keywords
// ##############################
+ /**
+ * Returns the values in the select list identified by locator.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the select list.
+ * @return The select list values
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator" })
public List getListItems(String locator) {
- List options = this.getSelectListOptions(locator);
+ List options = getSelectListOptions(locator);
return getLabelsForOptions(options);
}
+ /**
+ * Returns the visible label of the first selected element from the select
+ * list identified by locator.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the select list.
+ * @return The first visible select list label
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator" })
public String getSelectedListLabel(String locator) {
Select select = getSelectList(locator);
return select.getFirstSelectedOption().getText();
}
+ /**
+ * Returns the visible labels of the first selected elements as a list from
+ * the select list identified by locator.
+ *
+ * Fails if there is no selection.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the select list.
+ * @return The list of visible select list labels
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator" })
public List getSelectedListLabels(String locator) {
List options = getSelectListOptionsSelected(locator);
if (options.size() == 0) {
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "Select list with locator '%s' does not have any selected values.",
- locator));
+ throw new Selenium2LibraryNonFatalException(String.format(
+ "Select list with locator '%s' does not have any selected values.", locator));
}
return getLabelsForOptions(options);
}
+ /**
+ * Returns the value of the first selected element from the select list
+ * identified by locator.
+ *
+ * The return value is read from the value attribute of the selected
+ * element.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the select list.
+ * @return The first select list value
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator" })
public String getSelectedListValue(String locator) {
Select select = getSelectList(locator);
return select.getFirstSelectedOption().getAttribute("value");
}
+ /**
+ * Returns the values of the first selected elements as a list from the
+ * select list identified by locator.
+ *
+ * Fails if there is no selection. The return values are read from the value
+ * attribute of the selected element.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the select list.
+ * @return The list of select list values
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator" })
public List getSelectedListValues(String locator) {
List options = getSelectListOptionsSelected(locator);
if (options.size() == 0) {
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "Select list with locator '%s' does not have any selected values.",
- locator));
+ throw new Selenium2LibraryNonFatalException(String.format(
+ "Select list with locator '%s' does not have any selected values.", locator));
}
return getValuesForOptions(options);
}
+ /**
+ * Verify the selection of the select list identified by locatoris
+ * exactly *items.
+ *
+ * If you want to verify no option is selected, simply give no 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.
+ *
+ * @param locator
+ * The locator to locate the select list.
+ * @param items
+ * The list of items to verify
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "*items" })
public void listSelectionShouldBe(String locator, String... items) {
- String itemList = items.length != 0 ? String.format("option(s) [ %s ]",
- Python.join(" | ", items)) : "no options";
- info(String.format("Verifying list '%s' has %s selected.", locator,
- itemList));
+ String itemList = items.length != 0 ? String.format("option(s) [ %s ]", Python.join(" | ", items))
+ : "no options";
+ logging.info(String.format("Verifying list '%s' has %s selected.", locator, itemList));
- this.pageShouldContainList(locator);
+ pageShouldContainList(locator);
List options = getSelectListOptionsSelected(locator);
List selectedLabels = getLabelsForOptions(options);
- String message = String
- .format("List '%s' should have had selection [ %s ] but it was [ %s ].",
- locator, Python.join(" | ", items),
- Python.join(" | ", selectedLabels));
+ String message = String.format("List '%s' should have had selection [ %s ] but it was [ %s ].", locator,
+ Python.join(" | ", items), Python.join(" | ", selectedLabels));
if (items.length != options.size()) {
throw new Selenium2LibraryNonFatalException(message);
} else {
List selectedValues = getValuesForOptions(options);
for (String item : items) {
- if (!selectedValues.contains(item)
- && !selectedLabels.contains(item)) {
+ if (!selectedValues.contains(item) && !selectedLabels.contains(item)) {
throw new Selenium2LibraryNonFatalException(message);
}
}
}
}
+ /**
+ * Verify the select list identified by locatorhas no selections.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the select list.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator" })
public void listShouldHaveNoSelections(String locator) {
- info(String.format("Verifying list '%s' has no selection.", locator));
+ logging.info(String.format("Verifying list '%s' has no selection.", locator));
List options = getSelectListOptionsSelected(locator);
if (!options.equals(null)) {
List selectedLabels = getLabelsForOptions(options);
String items = Python.join(" | ", selectedLabels);
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "List '%s' should have had no selection (selection was [ %s ]).",
- locator, items.toString()));
+ throw new Selenium2LibraryNonFatalException(String.format(
+ "List '%s' should have had no selection (selection was [ %s ]).", locator, items.toString()));
}
}
+ @RobotKeywordOverload
public void pageShouldContainList(String locator) {
pageShouldContainList(locator, "");
}
+ @RobotKeywordOverload
public void pageShouldContainList(String locator, String message) {
pageShouldContainList(locator, message, "INFO");
}
- public void pageShouldContainList(String locator, String message,
- String logLevel) {
- this.pageShouldContainElement(locator, "list", message, logLevel);
+ /**
+ * Verify the select list identified by locator is found on the
+ * current page.
+ *
+ * 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 and log levels.
+ *
+ * @param locator
+ * The locator to locate the select list.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ * @param logLevel
+ * Default=INFO. Optional log level.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" })
+ public void pageShouldContainList(String locator, String message, String logLevel) {
+ element.pageShouldContainElement(locator, "list", message, logLevel);
}
+ @RobotKeywordOverload
public void pageShouldNotContainList(String locator) {
pageShouldNotContainList(locator, "");
}
+ @RobotKeywordOverload
public void pageShouldNotContainList(String locator, String message) {
pageShouldNotContainList(locator, message, "INFO");
}
- public void pageShouldNotContainList(String locator, String message,
- String logLevel) {
- this.pageShouldNotContainElement(locator, "list", message, logLevel);
+ /**
+ * Verify the select list identified by locator is not found on the
+ * current page.
+ *
+ * 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 and log levels.
+ *
+ * @param locator
+ * The locator to locate the select list.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ * @param logLevel
+ * Default=INFO. Optional log level.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "message=NONE", "logLevel=INFO" })
+ public void pageShouldNotContainList(String locator, String message, String logLevel) {
+ element.pageShouldNotContainElement(locator, "list", message, logLevel);
}
+ /**
+ * Select all values of the multi-select list identified by locator.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the multi-select list.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator" })
public void selectAllFromList(String locator) {
- info(String.format("Selecting all options from list '%s'.", locator));
+ logging.info(String.format("Selecting all options from list '%s'.", locator));
Select select = getSelectList(locator);
if (!isMultiselectList(select)) {
@@ -142,10 +305,30 @@ public void selectAllFromList(String locator) {
}
}
+ /**
+ * Select the given *items of the multi-select list identified by
+ * locator.
+ *
+ * An exception is raised for a single-selection list if the last value does
+ * not exist in the list and a warning for all other non-existing items. For
+ * a multi-selection list, an exception is raised for any and all
+ * non-existing 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.
+ *
+ * @param locator
+ * The locator to locate the multi-select list.
+ * @param items
+ * The list of items to select
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "*items" })
public void selectFromList(String locator, String... items) {
- String itemList = items.length != 0 ? String.format("option(s) [ %s ]",
- Python.join(" | ", items)) : "all options";
- info(String.format("Selecting %s from list '%s'.", itemList, locator));
+ String itemList = items.length != 0 ? String.format("option(s) [ %s ]", Python.join(" | ", items))
+ : "all options";
+ logging.info(String.format("Selecting %s from list '%s'.", itemList, locator));
Select select = getSelectList(locator);
@@ -155,21 +338,63 @@ public void selectFromList(String locator, String... items) {
for (int i = 0; i < select.getOptions().size(); i++) {
select.selectByIndex(i);
}
+ return;
}
+ boolean lastItemFound = false;
+ List nonExistingItems = new ArrayList();
for (String item : items) {
+ lastItemFound = true;
try {
select.selectByValue(item);
} catch (NoSuchElementException e1) {
try {
select.selectByVisibleText(item);
} catch (NoSuchElementException e2) {
+ nonExistingItems.add(item);
+ lastItemFound = false;
continue;
}
}
}
+
+ if (nonExistingItems.size() != 0) {
+ // multi-selection list => throw immediately
+ if (select.isMultiple()) {
+ throw new Selenium2LibraryNonFatalException(String.format("Options '%s' not in list '%s'.",
+ Python.join(", ", nonExistingItems), locator));
+ }
+
+ // single-selection list => log warning with not found items
+ logging.warn(String.format("Option%s '%s' not found within list '%s'.", nonExistingItems.size() == 0 ? ""
+ : "s", Python.join(", ", nonExistingItems), locator));
+
+ // single-selection list => throw if last item was not found
+ if (!lastItemFound) {
+ throw new Selenium2LibraryNonFatalException(String.format("Option '%s' not in list '%s'.",
+ nonExistingItems.get(nonExistingItems.size() - 1), locator));
+ }
+ }
}
+ /**
+ * Select the given *indexes of the multi-select list identified by
+ * locator.
+ *
+ * Tries to select by value AND by label. It's generally faster to use 'by
+ * index/value/label' keywords.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the multi-select list.
+ * @param indexes
+ * The list of indexes to select
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "*indexes" })
public void selectFromListByIndex(String locator, String... indexes) {
if (indexes.length == 0) {
throw new Selenium2LibraryNonFatalException("No index given.");
@@ -180,7 +405,7 @@ public void selectFromListByIndex(String locator, String... indexes) {
tmp.add(index);
}
String items = String.format("index(es) '%s'", Python.join(", ", tmp));
- info(String.format("Selecting %s from list '%s'.", items, locator));
+ logging.info(String.format("Selecting %s from list '%s'.", items, locator));
Select select = getSelectList(locator);
for (String index : indexes) {
@@ -188,14 +413,28 @@ public void selectFromListByIndex(String locator, String... indexes) {
}
}
+ /**
+ * Select the given *values of the multi-select list identified by
+ * locator.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the multi-select list.
+ * @param values
+ * The list of values to select
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "*values" })
public void selectFromListByValue(String locator, String... values) {
if (values.length == 0) {
throw new Selenium2LibraryNonFatalException("No value given.");
}
- String items = String
- .format("value(s) '%s'", Python.join(", ", values));
- info(String.format("Selecting %s from list '%s'.", items, locator));
+ String items = String.format("value(s) '%s'", Python.join(", ", values));
+ logging.info(String.format("Selecting %s from list '%s'.", items, locator));
Select select = getSelectList(locator);
for (String value : values) {
@@ -203,14 +442,28 @@ public void selectFromListByValue(String locator, String... values) {
}
}
+ /**
+ * Select the given *labels of the multi-select list identified by
+ * locator.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the multi-select list.
+ * @param labels
+ * The list of labels to select
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "*labels" })
public void selectFromListByLabel(String locator, String... labels) {
if (labels.length == 0) {
throw new Selenium2LibraryNonFatalException("No value given.");
}
- String items = String
- .format("label(s) '%s'", Python.join(", ", labels));
- info(String.format("Selecting %s from list '%s'.", items, locator));
+ String items = String.format("label(s) '%s'", Python.join(", ", labels));
+ logging.info(String.format("Selecting %s from list '%s'.", items, locator));
Select select = getSelectList(locator);
for (String label : labels) {
@@ -218,10 +471,31 @@ public void selectFromListByLabel(String locator, String... labels) {
}
}
+ /**
+ * Unselect the given *items of the multi-select list identified by
+ * locator.
+ *
+ * As a special case, giving an empty *items list will remove all
+ * selections.
+ *
+ * Tries to unselect by value AND by label. It's generally faster to use 'by
+ * index/value/label' keywords.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the multi-select list.
+ * @param items
+ * The list of items to select
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "*items" })
public void unselectFromList(String locator, String... items) {
- String itemList = items.length != 0 ? String.format("option(s) [ %s ]",
- Python.join(" | ", items)) : "all options";
- info(String.format("Unselecting %s from list '%s'.", itemList, locator));
+ String itemList = items.length != 0 ? String.format("option(s) [ %s ]", Python.join(" | ", items))
+ : "all options";
+ logging.info(String.format("Unselecting %s from list '%s'.", itemList, locator));
Select select = getSelectList(locator);
@@ -242,6 +516,21 @@ public void unselectFromList(String locator, String... items) {
}
}
+ /**
+ * Unselect the given *indexes of the multi-select list identified by
+ * locator.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the multi-select list.
+ * @param indexes
+ * The list of indexes to select
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "*indexes" })
public void unselectFromListByIndex(String locator, Integer... indexes) {
if (indexes.equals(null)) {
throw new Selenium2LibraryNonFatalException("No index given.");
@@ -252,7 +541,7 @@ public void unselectFromListByIndex(String locator, Integer... indexes) {
tmp.add(index.toString());
}
String items = String.format("index(es) '%s'", Python.join(", ", tmp));
- info(String.format("Unselecting %s from list '%s'.", items, locator));
+ logging.info(String.format("Unselecting %s from list '%s'.", items, locator));
Select select = getSelectList(locator);
@@ -266,14 +555,28 @@ public void unselectFromListByIndex(String locator, Integer... indexes) {
}
}
+ /**
+ * Unselect the given *values of the multi-select list identified by
+ * locator.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the multi-select list.
+ * @param values
+ * The list of values to select
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "*values" })
public void unselectFromListByValue(String locator, String... values) {
if (values.equals(null)) {
throw new Selenium2LibraryNonFatalException("No value given.");
}
- String items = String
- .format("value(s) '%s'", Python.join(", ", values));
- info(String.format("Unselecting %s from list '%s'.", items, locator));
+ String items = String.format("value(s) '%s'", Python.join(", ", values));
+ logging.info(String.format("Unselecting %s from list '%s'.", items, locator));
Select select = getSelectList(locator);
@@ -287,14 +590,28 @@ public void unselectFromListByValue(String locator, String... values) {
}
}
+ /**
+ * Unselect the given *labels of the multi-select list identified by
+ * locator.
+ *
+ * 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.
+ *
+ * @param locator
+ * The locator to locate the multi-select list.
+ * @param labels
+ * The list of labels to select
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "*labels" })
public void unselectFromListByLabel(String locator, String... labels) {
if (labels.equals(null)) {
throw new Selenium2LibraryNonFatalException("No value given.");
}
- String items = String
- .format("label(s) '%s'", Python.join(", ", labels));
- info(String.format("Unselecting %s from list '%s'.", items, locator));
+ String items = String.format("label(s) '%s'", Python.join(", ", labels));
+ logging.info(String.format("Unselecting %s from list '%s'.", items, locator));
Select select = getSelectList(locator);
@@ -312,7 +629,7 @@ public void unselectFromListByLabel(String locator, String... labels) {
// Internal Methods
// ##############################
- private List getLabelsForOptions(List options) {
+ protected List getLabelsForOptions(List options) {
List labels = new ArrayList();
for (WebElement option : options) {
@@ -322,29 +639,29 @@ private List getLabelsForOptions(List options) {
return labels;
}
- private Select getSelectList(String locator) {
- List elements = elementFind(locator, true, true, "select");
+ protected Select getSelectList(String locator) {
+ List webElements = element.elementFind(locator, true, true, "select");
- return new Select(elements.get(0));
+ return new Select(webElements.get(0));
}
- private List getSelectListOptions(Select select) {
+ protected List getSelectListOptions(Select select) {
return new ArrayList(select.getOptions());
}
- private List getSelectListOptions(String locator) {
+ protected List getSelectListOptions(String locator) {
Select select = getSelectList(locator);
return getSelectListOptions(select);
}
- private List getSelectListOptionsSelected(String locator) {
+ protected List getSelectListOptionsSelected(String locator) {
Select select = getSelectList(locator);
return new ArrayList(select.getAllSelectedOptions());
}
- private List getValuesForOptions(List options) {
+ protected List getValuesForOptions(List options) {
ArrayList labels = new ArrayList();
for (WebElement option : options) {
@@ -354,8 +671,8 @@ private List getValuesForOptions(List options) {
return labels;
}
- private boolean isMultiselectList(Select select) {
+ protected boolean isMultiselectList(Select select) {
return select.isMultiple();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/github/markusbernhardt/selenium2library/keywords/Selenium2LibraryEnhancement.java b/src/main/java/com/github/markusbernhardt/selenium2library/keywords/Selenium2LibraryEnhancement.java
deleted file mode 100644
index abd7a40..0000000
--- a/src/main/java/com/github/markusbernhardt/selenium2library/keywords/Selenium2LibraryEnhancement.java
+++ /dev/null
@@ -1,517 +0,0 @@
-package com.github.markusbernhardt.selenium2library.keywords;
-
-import java.util.List;
-
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.remote.RemoteWebDriver;
-
-import com.github.markusbernhardt.selenium2library.Selenium2LibraryNonFatalException;
-import com.github.markusbernhardt.selenium2library.locators.ElementFinder;
-
-public class Selenium2LibraryEnhancement extends Waiting {
-
- // ##############################
- // Keywords
- // ##############################
-
- public String getSystemInfo() {
- return String
- .format(" os.name: '%s'\n os.arch: '%s'\n os.version: '%s'\n java.version: '%s'",
- System.getProperty("os.name"),
- System.getProperty("os.arch"),
- System.getProperty("os.version"),
- System.getProperty("java.version"));
- }
-
- public String logSystemInfo() {
- String actual = getSystemInfo();
- info(actual);
- return actual;
- }
-
- public String getRemoteCapabilities() {
- if (webDriverCache.getCurrent() instanceof RemoteWebDriver) {
- return ((RemoteWebDriver) webDriverCache.getCurrent())
- .getCapabilities().toString();
- } else {
- return "No remote session id";
- }
- }
-
- public String logRemoteCapabilities() {
- String actual = getRemoteCapabilities();
- info(actual);
- return actual;
- }
-
- public String getRemoteSessionId() {
- if (webDriverCache.getCurrent() instanceof RemoteWebDriver) {
- return ((RemoteWebDriver) webDriverCache.getCurrent())
- .getSessionId().toString();
- } else {
- return "No remote session id";
- }
- }
-
- public String logRemoteSessionId() {
- String actual = getRemoteSessionId();
- info(actual);
- return actual;
- }
-
- public void addLocationStrategy(String strategyName,
- String functionDefinition) {
- addLocationStrategy(strategyName, functionDefinition, null);
- }
-
- public void addLocationStrategy(String strategyName,
- String functionDefinition, String delimiter) {
- ElementFinder.addLocationStrategy(strategyName, functionDefinition,
- delimiter);
- }
-
- public void waitUntilPageNotContains(String condition) {
- waitUntilPageNotContains(condition, null);
- }
-
- public void waitUntilPageNotContains(String condition, String timestr) {
- waitUntilPageNotContains(condition, timestr, null);
- }
-
- public void waitUntilPageNotContains(final String text, String timestr,
- String error) {
- if (error == null) {
- error = String.format("Text '%s' did not disappear in ",
- text);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- return !isTextPresent(text);
- }
- });
- }
-
- public void waitUntilPageNotContainsElement(String locator) {
- waitUntilPageNotContainsElement(locator, null);
- }
-
- public void waitUntilPageNotContainsElement(String locator, String timestr) {
- waitUntilPageNotContainsElement(locator, timestr, null);
- }
-
- public void waitUntilPageNotContainsElement(final String locator,
- String timestr, String error) {
- if (error == null) {
- error = String.format(
- "Element '%s' did not disappear in ", locator);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- return !isElementPresent(locator);
- }
- });
- }
-
- public void waitUntilElementIsVisible(String locator) {
- waitUntilElementIsVisible(locator, null);
- }
-
- public void waitUntilElementIsVisible(String locator, String timestr) {
- waitUntilElementIsVisible(locator, timestr, null);
- }
-
- public void waitUntilElementIsVisible(final String locator, String timestr,
- String error) {
- if (error == null) {
- error = String.format("Element '%s' not visible in ",
- locator);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- return isVisible(locator);
- }
- });
- }
-
- public void waitUntilElementIsNotVisible(String locator) {
- waitUntilElementIsNotVisible(locator, null);
- }
-
- public void waitUntilElementIsNotVisible(String locator, String timestr) {
- waitUntilElementIsNotVisible(locator, timestr, null);
- }
-
- public void waitUntilElementIsNotVisible(final String locator,
- String timestr, String error) {
- if (error == null) {
- error = String.format("Element '%s' still visible in ",
- locator);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- return !isVisible(locator);
- }
- });
- }
-
- public void waitUntilTitleContains(String title) {
- waitUntilTitleContains(title, null);
- }
-
- public void waitUntilTitleContains(String title, String timestr) {
- waitUntilTitleContains(title, timestr, null);
- }
-
- public void waitUntilTitleContains(final String title, String timestr,
- String error) {
- if (error == null) {
- error = String.format("Title '%s' did not appear in ",
- title);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- String currentTitle = getTitle();
- return currentTitle != null && currentTitle.contains(title);
- }
- });
- }
-
- public void waitUntilTitleNotContains(String title) {
- waitUntilTitleNotContains(title, null);
- }
-
- public void waitUntilTitleNotContains(String title, String timestr) {
- waitUntilTitleNotContains(title, timestr, null);
- }
-
- public void waitUntilTitleNotContains(final String title, String timestr,
- String error) {
- if (error == null) {
- error = String.format("Title '%s' did not appear in ",
- title);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- String currentTitle = getTitle();
- return currentTitle == null || !currentTitle.contains(title);
- }
- });
- }
-
- public void waitUntilTitleIs(String title) {
- waitUntilTitleIs(title, null);
- }
-
- public void waitUntilTitleIs(String title, String timestr) {
- waitUntilTitleIs(title, timestr, null);
- }
-
- public void waitUntilTitleIs(final String title, String timestr,
- String error) {
- if (error == null) {
- error = String.format("Title '%s' did not appear in ",
- title);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- String currentTitle = getTitle();
- return currentTitle != null && currentTitle.equals(title);
- }
- });
- }
-
- public void waitUntilTitleIsNot(String title) {
- waitUntilTitleIsNot(title, null);
- }
-
- public void waitUntilTitleIsNot(String title, String timestr) {
- waitUntilTitleIsNot(title, timestr, null);
- }
-
- public void waitUntilTitleIsNot(final String title, String timestr,
- String error) {
- if (error == null) {
- error = String.format("Title '%s' did not appear in ",
- title);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- String currentTitle = getTitle();
- return currentTitle == null || !currentTitle.equals(title);
- }
- });
- }
-
- public void elementShouldBeSelected(String locator) {
- this.elementShouldBeSelected(locator, "");
- }
-
- public void elementShouldBeSelected(String locator, String message) {
- 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 Selenium2LibraryNonFatalException(message);
- }
- }
-
- public void elementShouldNotBeSelected(String locator) {
- this.elementShouldNotBeSelected(locator, "");
- }
-
- public void elementShouldNotBeSelected(String locator, String message) {
- 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 Selenium2LibraryNonFatalException(message);
- }
- }
-
- public void waitUntilElementIsSelected(String locator) {
- waitUntilElementIsSelected(locator, null);
- }
-
- public void waitUntilElementIsSelected(String locator, String timestr) {
- waitUntilElementIsSelected(locator, timestr, null);
- }
-
- public void waitUntilElementIsSelected(final String locator,
- String timestr, String error) {
- if (error == null) {
- error = String.format("Element '%s' not selected in ",
- locator);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- return isSelected(locator);
- }
- });
- }
-
- public void waitUntilElementIsNotSelected(String locator) {
- waitUntilElementIsNotSelected(locator, null);
- }
-
- public void waitUntilElementIsNotSelected(String locator, String timestr) {
- waitUntilElementIsNotSelected(locator, timestr, null);
- }
-
- public void waitUntilElementIsNotSelected(final String locator,
- String timestr, String error) {
- if (error == null) {
- error = String.format("Element '%s' still selected in ",
- locator);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- return !isSelected(locator);
- }
- });
- }
-
- public void elementShouldBeClickable(String locator) {
- this.elementShouldBeClickable(locator, "");
- }
-
- public void elementShouldBeClickable(String locator, String message) {
- 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 Selenium2LibraryNonFatalException(message);
- }
- }
-
- public void elementShouldNotBeClickable(String locator) {
- this.elementShouldNotBeClickable(locator, "");
- }
-
- public void elementShouldNotBeClickable(String locator, String message) {
- 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 Selenium2LibraryNonFatalException(message);
- }
- }
-
- public void waitUntilElementIsClickable(String locator) {
- waitUntilElementIsClickable(locator, null);
- }
-
- public void waitUntilElementIsClickable(String locator, String timestr) {
- waitUntilElementIsClickable(locator, timestr, null);
- }
-
- public void waitUntilElementIsClickable(final String locator,
- String timestr, String error) {
- if (error == null) {
- error = String.format("Element '%s' not clickable in ",
- locator);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- return isClickable(locator);
- }
- });
- }
-
- public void waitUntilElementIsSuccessfullyClicked(String locator) {
- waitUntilElementIsSuccessfullyClicked(locator, null);
- }
-
- public void waitUntilElementIsSuccessfullyClicked(String locator,
- String timestr) {
- waitUntilElementIsSuccessfullyClicked(locator, timestr, null);
- }
-
- public void waitUntilElementIsSuccessfullyClicked(final String locator,
- String timestr, String error) {
- if (error == null) {
- error = String.format(
- "Element '%s' not successfully clicked in ",
- locator);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- clickElement(locator);
- return true;
- }
- });
- }
-
- public void waitUntilElementIsNotClickable(String locator) {
- waitUntilElementIsNotClickable(locator, null);
- }
-
- public void waitUntilElementIsNotClickable(String locator, String timestr) {
- waitUntilElementIsNotClickable(locator, timestr, null);
- }
-
- public void waitUntilElementIsNotClickable(final String locator,
- String timestr, String error) {
- if (error == null) {
- error = String.format("Element '%s' still clickable in ",
- locator);
- }
- waitUntil(timestr, error, new WaitUntilFunction() {
-
- @Override
- public boolean isFinished() {
- return !isClickable(locator);
- }
- });
- }
-
- public void elementShouldNotContain(String locator, String expected) {
- this.elementShouldNotContain(locator, expected, "");
- }
-
- public void elementShouldNotContain(String locator, String expected,
- String message) {
- String actual = fetchText(locator);
-
- if (actual.toLowerCase().contains(expected.toLowerCase())) {
- info(String.format("Element Should Not Contain: %s => FAILED",
- expected));
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "Element should not have contained text '%s' but its text was %s.",
- expected, actual));
- } else {
- info(String
- .format("Element Should Not Contain: %s => OK", expected));
- }
- }
-
- public void elementTextShouldNotBe(String locator, String expected) {
- this.elementTextShouldNotBe(locator, expected, "");
- }
-
- public void elementTextShouldNotBe(String locator, String expected,
- String message) {
- info(String.format(
- "Verifying element '%s' contains exactly text '%s'.", locator,
- expected));
-
- List elements = elementFind(locator, true, true);
- String actual = elements.get(0).getText();
-
- if (expected.equals(actual)) {
- if (message == null || message.equals("")) {
- message = String
- .format("The text of element '%s' should have been '%s', but it was '%s'.",
- locator, expected, actual);
- }
- throw new Selenium2LibraryNonFatalException(message);
- }
- }
-
- // ##############################
- // Internal Methods
- // ##############################
-
- protected boolean isClickable(String locator) {
- List elements = elementFind(locator, true, false);
- if (elements.size() == 0) {
- return false;
- }
- WebElement element = elements.get(0);
- return element.isDisplayed() && element.isEnabled();
- }
-
- protected boolean isSelected(String locator) {
- List elements = elementFind(locator, true, false);
- if (elements.size() == 0) {
- return false;
- }
- WebElement element = elements.get(0);
- return element.isSelected();
- }
-
-}
diff --git a/src/main/java/com/github/markusbernhardt/selenium2library/keywords/TableElement.java b/src/main/java/com/github/markusbernhardt/selenium2library/keywords/TableElement.java
index a3ffbce..74db4b5 100644
--- a/src/main/java/com/github/markusbernhardt/selenium2library/keywords/TableElement.java
+++ b/src/main/java/com/github/markusbernhardt/selenium2library/keywords/TableElement.java
@@ -4,26 +4,67 @@
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
+import org.robotframework.javalib.annotation.ArgumentNames;
+import org.robotframework.javalib.annotation.Autowired;
+import org.robotframework.javalib.annotation.RobotKeyword;
+import org.robotframework.javalib.annotation.RobotKeywordOverload;
+import org.robotframework.javalib.annotation.RobotKeywords;
+import com.github.markusbernhardt.selenium2library.RunOnFailureKeywordsAdapter;
import com.github.markusbernhardt.selenium2library.Selenium2LibraryNonFatalException;
import com.github.markusbernhardt.selenium2library.locators.TableElementFinder;
-public abstract class TableElement extends SelectElement {
+@RobotKeywords
+public class TableElement extends RunOnFailureKeywordsAdapter {
+
+ /**
+ * Instantiated BrowserManagement keyword bean
+ */
+ @Autowired
+ protected BrowserManagement browserManagement;
+
+ /**
+ * Instantiated Logging keyword bean
+ */
+ @Autowired
+ protected Logging logging;
// ##############################
// Keywords
// ##############################
+ @RobotKeywordOverload
public String getTableCell(String tableLocator, int row, int column) {
return getTableCell(tableLocator, row, column, "INFO");
}
- public String getTableCell(String tableLocator, int row, int column,
- String loglevel) {
+ /**
+ * Returns the content of the table cell at the coordinates row and
+ * column of the table identified by tableLocator.
+ *
+ * Row and column number start from 1. Header and footer rows are included
+ * in the count. That way also cell content from header or footer rows can
+ * be obtained with this keyword.
+ *
+ * Key attributes for tables are id and name. See `Introduction` for details
+ * about locators and log levels.
+ *
+ * @param tableLocator
+ * The locator to locate the table.
+ * @param row
+ * The table row.
+ * @param column
+ * The table column.
+ * @param logLevel
+ * Default=INFO. Optional log level.
+ * @return The table cell content.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "tableLocator", "row", "column", "logLevel=INFO" })
+ public String getTableCell(String tableLocator, int row, int column, String logLevel) {
int rowIndex = row - 1;
int columnIndex = column - 1;
- WebElement table = TableElementFinder.find(webDriverCache.getCurrent(),
- tableLocator);
+ WebElement table = TableElementFinder.find(browserManagement.getCurrentWebDriver(), tableLocator);
if (table != null) {
List rows = table.findElements(By.xpath("./thead/tr"));
if (rowIndex >= rows.size()) {
@@ -33,134 +74,254 @@ public String getTableCell(String tableLocator, int row, int column,
rows.addAll(table.findElements(By.xpath("./tfoot/tr")));
}
if (rowIndex < rows.size()) {
- List columns = rows.get(rowIndex).findElements(
- By.tagName("th"));
+ List columns = rows.get(rowIndex).findElements(By.tagName("th"));
if (columnIndex >= columns.size()) {
- columns.addAll(rows.get(rowIndex).findElements(
- By.tagName("td")));
+ columns.addAll(rows.get(rowIndex).findElements(By.tagName("td")));
}
if (columnIndex < columns.size()) {
return columns.get(columnIndex).getText();
}
}
}
- logSource(loglevel);
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "Cell in table %s in row #%d and column #%d could not be found.",
- tableLocator, row, column));
+ logging.logSource(logLevel);
+ throw new Selenium2LibraryNonFatalException(String.format(
+ "Cell in table %s in row #%d and column #%d could not be found.", tableLocator, row, column));
}
- public void tableCellShouldContain(String tableLocator, int row,
- int column, String expected) {
- tableCellShouldContain(tableLocator, row, column, expected, "INFO");
+ @RobotKeywordOverload
+ public void tableCellShouldContain(String tableLocator, int row, int column, String text) {
+ tableCellShouldContain(tableLocator, row, column, text, "INFO");
}
- public void tableCellShouldContain(String tableLocator, int row,
- int column, String expected, String loglevel) {
- String message = String
- .format("Cell in table '%s' in row #%d and column #%d should have contained text '%s'.",
- tableLocator, row, column, expected);
+ /**
+ * Verify the content of the table cell at the coordinates row and
+ * column of the table identified by tableLocator contains
+ * text.
+ *
+ * Row and column number start from 1. Header and footer rows are included
+ * in the count. That way also cell content from header or footer rows can
+ * be obtained with this keyword.
+ *
+ * Key attributes for tables are id and name. See `Introduction` for details
+ * about locators and log levels.
+ *
+ * @param tableLocator
+ * The locator to locate the table.
+ * @param row
+ * The table row.
+ * @param column
+ * The table column.
+ * @param text
+ * The text to verify.
+ * @param logLevel
+ * Default=INFO. Optional log level.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "tableLocator", "row", "column", "text", "logLevel=INFO" })
+ public void tableCellShouldContain(String tableLocator, int row, int column, String text, String logLevel) {
+ 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 = "";
try {
- content = getTableCell(tableLocator, row, column, loglevel);
- } catch (AssertionError err) {
- info(err.getMessage());
+ content = getTableCell(tableLocator, row, column, logLevel);
+ } catch (Selenium2LibraryNonFatalException e) {
+ logging.info(e.getMessage());
throw new Selenium2LibraryNonFatalException(message);
}
- info(String.format("Cell contains %s.", content));
- if (!content.contains(expected)) {
- logSource(loglevel);
+ logging.info(String.format("Cell contains %s.", content));
+ if (!content.contains(text)) {
+ logging.logSource(logLevel);
throw new Selenium2LibraryNonFatalException(message);
}
}
- public void tableColumnShouldContain(String tableLocator, int col,
- String expected) {
- tableColumnShouldContain(tableLocator, col, expected, "INFO");
+ @RobotKeywordOverload
+ public void tableColumnShouldContain(String tableLocator, int col, String text) {
+ tableColumnShouldContain(tableLocator, col, text, "INFO");
}
- public void tableColumnShouldContain(String tableLocator, int col,
- String expected, String loglevel) {
- WebElement element = TableElementFinder.findByCol(
- webDriverCache.getCurrent(), tableLocator, col, expected);
+ /**
+ * Verify the content of any table cells of the table column of the
+ * table identified by tableLocator contains text.
+ *
+ * Key attributes for tables are id and name. See `Introduction` for details
+ * about locators and log levels.
+ *
+ * The first leftmost column is column number 1. If the table contains cells
+ * that span multiple columns, those merged cells count as a single column.
+ * For example both tests below work, if in one row columns A and B are
+ * merged with colspan="2", and the logical third column contains "C".
+ *
+ * Example:
+ *
+ *
+ * Table Column Should Contain |
+ * tableId |
+ * 3 |
+ * C |
+ *
+ *
+ * Table Column Should Contain |
+ * tableId |
+ * 2 |
+ * C |
+ *
+ *
+ *
+ * @param tableLocator
+ * The locator to locate the table.
+ * @param col
+ * The table column.
+ * @param text
+ * The text to verify.
+ * @param logLevel
+ * Default=INFO. Optional log level.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "tableLocator", "col", "text", "logLevel=INFO" })
+ public void tableColumnShouldContain(String tableLocator, int col, String text, String logLevel) {
+ WebElement element = TableElementFinder.findByCol(browserManagement.getCurrentWebDriver(), tableLocator, col,
+ text);
if (element == null) {
- logSource(loglevel);
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "Column #%d in table identified by '%s' should have contained text '%s'.",
- col, tableLocator, expected));
+ logging.logSource(logLevel);
+ throw new Selenium2LibraryNonFatalException(String.format(
+ "Column #%d in table identified by '%s' should have contained text '%s'.", col, tableLocator, text));
}
}
- public void tableFooterShouldContain(String tableLocator, String expected) {
- tableFooterShouldContain(tableLocator, expected, "INFO");
+ @RobotKeywordOverload
+ public void tableFooterShouldContain(String tableLocator, String text) {
+ tableFooterShouldContain(tableLocator, text, "INFO");
}
- public void tableFooterShouldContain(String tableLocator, String expected,
- String loglevel) {
- WebElement element = TableElementFinder.findByFooter(
- webDriverCache.getCurrent(), tableLocator, expected);
+ /**
+ * Verify the content of any table footer cells of the table identified by
+ * tableLocator contains text.
+ *
+ * Key attributes for tables are id and name. See `Introduction` for details
+ * about locators and log levels.
+ *
+ * @param tableLocator
+ * The locator to locate the table.
+ * @param text
+ * The text to verify.
+ * @param logLevel
+ * Default=INFO. Optional log level.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "tableLocator", "text", "logLevel=INFO" })
+ public void tableFooterShouldContain(String tableLocator, String text, String logLevel) {
+ WebElement element = TableElementFinder.findByFooter(browserManagement.getCurrentWebDriver(), tableLocator,
+ text);
if (element == null) {
- logSource(loglevel);
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "Footer in table identified by '%s' should have contained text '%s'.",
- tableLocator, expected));
+ logging.logSource(logLevel);
+ throw new Selenium2LibraryNonFatalException(String.format(
+ "Footer in table identified by '%s' should have contained text '%s'.", tableLocator, text));
}
}
- public void tableHeaderShouldContain(String tableLocator, String expected) {
- tableHeaderShouldContain(tableLocator, expected, "INFO");
+ @RobotKeywordOverload
+ public void tableHeaderShouldContain(String tableLocator, String text) {
+ tableHeaderShouldContain(tableLocator, text, "INFO");
}
- public void tableHeaderShouldContain(String tableLocator, String expected,
- String loglevel) {
- WebElement element = TableElementFinder.findByHeader(
- webDriverCache.getCurrent(), tableLocator, expected);
+ /**
+ * Verify the content of any table header cells of the table identified by
+ * tableLocator contains text.
+ *
+ * Key attributes for tables are id and name. See `Introduction` for details
+ * about locators and log levels.
+ *
+ * @param tableLocator
+ * The locator to locate the table.
+ * @param text
+ * The text to verify.
+ * @param logLevel
+ * Default=INFO. Optional log level.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "tableLocator", "text", "logLevel=INFO" })
+ public void tableHeaderShouldContain(String tableLocator, String text, String logLevel) {
+ WebElement element = TableElementFinder.findByHeader(browserManagement.getCurrentWebDriver(), tableLocator,
+ text);
if (element == null) {
- logSource(loglevel);
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "Header in table identified by '%s' should have contained text '%s'.",
- tableLocator, expected));
+ logging.logSource(logLevel);
+ throw new Selenium2LibraryNonFatalException(String.format(
+ "Header in table identified by '%s' should have contained text '%s'.", tableLocator, text));
}
}
- public void tableRowShouldContain(String tableLocator, int row,
- String expected) {
- tableRowShouldContain(tableLocator, row, expected, "INFO");
+ @RobotKeywordOverload
+ public void tableRowShouldContain(String tableLocator, int row, String text) {
+ tableRowShouldContain(tableLocator, row, text, "INFO");
}
- public void tableRowShouldContain(String tableLocator, int row,
- String expected, String loglevel) {
- WebElement element = TableElementFinder.findByRow(
- webDriverCache.getCurrent(), tableLocator, row, expected);
+ /**
+ * Verify the content of any table cells of the table row of the
+ * table identified by tableLocator contains text.
+ *
+ * Key attributes for tables are id and name. See `Introduction` for details
+ * about locators and log levels.
+ *
+ * The uppermost row is row number 1. For tables that are structured with
+ * thead, tbody and tfoot, only the tbody section is searched. Please use
+ * Table Header Should Contain or Table Footer Should Contain for tests
+ * against the header or footer content.
+ *
+ * If the table contains cells that span multiple rows, a match only occurs
+ * for the uppermost row of those merged cells.
+ *
+ * @param tableLocator
+ * The locator to locate the table.
+ * @param row
+ * The table row.
+ * @param text
+ * The text to verify.
+ * @param logLevel
+ * Default=INFO. Optional log level.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "tableLocator", "row", "text", "logLevel=INFO" })
+ public void tableRowShouldContain(String tableLocator, int row, String text, String logLevel) {
+ WebElement element = TableElementFinder.findByRow(browserManagement.getCurrentWebDriver(), tableLocator, row,
+ text);
if (element == null) {
- logSource(loglevel);
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "Row #%d in table identified by '%s' should have contained text '%s'.",
- row, tableLocator, expected));
+ logging.logSource(logLevel);
+ throw new Selenium2LibraryNonFatalException(String.format(
+ "Row #%d in table identified by '%s' should have contained text '%s'.", row, tableLocator, text));
}
}
- public void tableShouldContain(String tableLocator, String expected) {
- tableShouldContain(tableLocator, expected, "INFO");
+ @RobotKeywordOverload
+ public void tableShouldContain(String tableLocator, String text) {
+ tableShouldContain(tableLocator, text, "INFO");
}
- public void tableShouldContain(String tableLocator, String expected,
- String loglevel) {
- WebElement element = TableElementFinder.findByContent(
- webDriverCache.getCurrent(), tableLocator, expected);
+ /**
+ * Verify the content of any table cells of the table identified by
+ * tableLocator contains text.
+ *
+ * Key attributes for tables are id and name. See `Introduction` for details
+ * about locators and log levels.
+ *
+ * @param tableLocator
+ * The locator to locate the table.
+ * @param text
+ * The text to verify.
+ * @param logLevel
+ * Default=INFO. Optional log level.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "tableLocator", "text", "logLevel=INFO" })
+ public void tableShouldContain(String tableLocator, String text, String logLevel) {
+ WebElement element = TableElementFinder.findByContent(browserManagement.getCurrentWebDriver(), tableLocator,
+ text);
if (element == null) {
- logSource(loglevel);
- throw new Selenium2LibraryNonFatalException(
- String.format(
- "Table identified by '%s' should have contained text '%s'.",
- tableLocator, expected));
+ logging.logSource(logLevel);
+ throw new Selenium2LibraryNonFatalException(String.format(
+ "Table identified by '%s' should have contained text '%s'.", tableLocator, text));
}
}
diff --git a/src/main/java/com/github/markusbernhardt/selenium2library/keywords/Waiting.java b/src/main/java/com/github/markusbernhardt/selenium2library/keywords/Waiting.java
index fe64f51..411b95a 100644
--- a/src/main/java/com/github/markusbernhardt/selenium2library/keywords/Waiting.java
+++ b/src/main/java/com/github/markusbernhardt/selenium2library/keywords/Waiting.java
@@ -1,83 +1,669 @@
package com.github.markusbernhardt.selenium2library.keywords;
import org.openqa.selenium.JavascriptExecutor;
+import org.robotframework.javalib.annotation.ArgumentNames;
+import org.robotframework.javalib.annotation.Autowired;
+import org.robotframework.javalib.annotation.RobotKeyword;
+import org.robotframework.javalib.annotation.RobotKeywordOverload;
+import org.robotframework.javalib.annotation.RobotKeywords;
+import com.github.markusbernhardt.selenium2library.RunOnFailureKeywordsAdapter;
import com.github.markusbernhardt.selenium2library.Selenium2LibraryNonFatalException;
import com.github.markusbernhardt.selenium2library.utils.Robotframework;
-public abstract class Waiting extends TableElement {
+@RobotKeywords
+public class Waiting extends RunOnFailureKeywordsAdapter {
+
+ /**
+ * Instantiated BrowserManagement keyword bean
+ */
+ @Autowired
+ protected BrowserManagement browserManagement;
+
+ /**
+ * Instantiated Element keyword bean
+ */
+ @Autowired
+ protected Element element;
// ##############################
// Keywords
// ##############################
+ @RobotKeywordOverload
public void waitForCondition(String condition) {
waitForCondition(condition, null);
}
- public void waitForCondition(String condition, String timestr) {
- waitForCondition(condition, timestr, null);
+ @RobotKeywordOverload
+ public void waitForCondition(String condition, String timeout) {
+ waitForCondition(condition, timeout, null);
}
- public void waitForCondition(final String condition, String timestr,
- String error) {
- if (error == null) {
- error = String.format(
- "Condition '%s' did not become true in ",
- condition);
+ /**
+ * Waits until the given JavaScript condition is true.
+ *
+ * Fails, if the timeout expires, before the condition gets true.
+ *
+ * The condition may contain multiple JavaScript statements, but the last
+ * statement must return a boolean. Otherwise this keyword will always hit
+ * the timeout.
+ *
+ * Note that by default the code will be executed in the context of the
+ * Selenium object itself, so this will refer to the Selenium object.
+ * Use window to refer to the window of your application, e.g.
+ * window.document.getElementById('foo').
+ *
+ * See `Introduction` for details about timeouts.
+ *
+ * @param condition
+ * The JavaScript condition returning a boolean.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "condition", "timeout=NONE", "message=NONE" })
+ public void waitForCondition(final String condition, String timeout, String message) {
+ if (message == null) {
+ message = String.format("Condition '%s' did not become true in ", condition);
}
- waitUntil(timestr, error, new WaitUntilFunction() {
+ waitUntil(timeout, message, new WaitUntilFunction() {
@Override
public boolean isFinished() {
- return Boolean.TRUE.equals(((JavascriptExecutor) webDriverCache
- .getCurrent()).executeScript(condition));
+ return Boolean.TRUE.equals(((JavascriptExecutor) browserManagement.getCurrentWebDriver())
+ .executeScript(condition));
}
});
}
+ @RobotKeywordOverload
public void waitUntilPageContains(String condition) {
waitUntilPageContains(condition, null);
}
- public void waitUntilPageContains(String condition, String timestr) {
- waitUntilPageContains(condition, timestr, null);
+ @RobotKeywordOverload
+ public void waitUntilPageContains(String condition, String timeout) {
+ waitUntilPageContains(condition, timeout, null);
+ }
+
+ /**
+ * Waits until the current page contains text.
+ *
+ * Fails, if the timeout expires, before the text appears.
+ *
+ * See `Introduction` for details about timeouts.
+ *
+ * @param text
+ * The text to verify.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "condition", "timeout=NONE", "message=NONE" })
+ public void waitUntilPageContains(final String text, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilPageNotContains(String condition, String timeout) {
+ waitUntilPageNotContains(condition, timeout, null);
}
- public void waitUntilPageContains(final String text, String timestr,
- String error) {
- if (error == null) {
- error = String
- .format("Text '%s' did not appear in ", text);
+ @RobotKeywordOverload
+ public void waitUntilPageNotContains(String condition) {
+ waitUntilPageNotContains(condition, null);
+ }
+
+ /**
+ * Waits until the current page does not contain text.
+ *
+ * Fails, if the timeout expires, before the text disappears.
+ *
+ * See `Introduction` for details about timeouts.
+ *
+ * @param text
+ * The text to verify.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "text", "timeout=NONE", "message=NONE" })
+ public void waitUntilPageNotContains(final String text, String timeout, String message) {
+ if (message == null) {
+ message = String.format("Text '%s' did not disappear in ", text);
}
- waitUntil(timestr, error, new WaitUntilFunction() {
+ waitUntil(timeout, message, new WaitUntilFunction() {
@Override
public boolean isFinished() {
- return isTextPresent(text);
+ return !element.isTextPresent(text);
}
});
}
+ @RobotKeywordOverload
public void waitUntilPageContainsElement(String condition) {
waitUntilPageContainsElement(condition, null);
}
- public void waitUntilPageContainsElement(String condition, String timestr) {
- waitUntilPageContainsElement(condition, timestr, null);
+ @RobotKeywordOverload
+ public void waitUntilPageContainsElement(String condition, String timeout) {
+ waitUntilPageContainsElement(condition, timeout, null);
+ }
+
+ /**
+ * Waits until the element identified by locator is found on the
+ * current page.
+ *
+ * Fails, if the timeout expires, before the element appears.
+ *
+ * See `Introduction` for details about locators and timeouts.
+ *
+ * @param locator
+ * The locator to locate the element.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "timeout=NONE", "message=NONE" })
+ public void waitUntilPageContainsElement(final String locator, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilPageNotContainsElement(String locator) {
+ waitUntilPageNotContainsElement(locator, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilPageNotContainsElement(String locator, String timeout) {
+ waitUntilPageNotContainsElement(locator, timeout, null);
+ }
+
+ /**
+ * Waits until the element identified by locator is not found on the
+ * current page.
+ *
+ * Fails, if the timeout expires, before the element disappears.
+ *
+ * See `Introduction` for details about locators and timeouts.
+ *
+ * @param locator
+ * The locator to locate the element.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "timeout=NONE", "message=NONE" })
+ public void waitUntilPageNotContainsElement(final String locator, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsVisible(String locator, String timeout) {
+ waitUntilElementIsVisible(locator, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsVisible(String locator) {
+ waitUntilElementIsVisible(locator, null);
+ }
+
+ /**
+ * Waits until the element identified by locator is visible.
+ *
+ * Fails, if the timeout expires, before the element gets visible.
+ *
+ * See `Introduction` for details about locators and timeouts.
+ *
+ * @param locator
+ * The locator to locate the element.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "timeout=NONE", "message=NONE" })
+ public void waitUntilElementIsVisible(final String locator, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsNotVisible(String locator, String timeout) {
+ waitUntilElementIsNotVisible(locator, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsNotVisible(String locator) {
+ waitUntilElementIsNotVisible(locator, null);
+ }
+
+ /**
+ * Waits until the element identified by locator is not visible.
+ *
+ * Fails, if the timeout expires, before the element gets invisible.
+ *
+ * See `Introduction` for details about locators and timeouts.
+ *
+ * @param locator
+ * The locator to locate the element.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "timeout=NONE", "message=NONE" })
+ public void waitUntilElementIsNotVisible(final String locator, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsClickable(String locator) {
+ waitUntilElementIsClickable(locator, null, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsClickable(String locator, String timeout) {
+ waitUntilElementIsClickable(locator, timeout, null);
+ }
+
+ /**
+ * Waits until the element identified by locator is clickable.
+ *
+ * Fails, if the timeout expires, before the element gets clickable.
+ *
+ * See `Introduction` for details about locators and timeouts.
+ *
+ * @param locator
+ * The locator to locate the element.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "timeout=NONE", "message=NONE" })
+ public void waitUntilElementIsClickable(final String locator, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsNotClickable(String locator, String timeout) {
+ waitUntilElementIsNotClickable(locator, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsNotClickable(String locator) {
+ waitUntilElementIsNotClickable(locator, null);
+ }
+
+ /**
+ * Waits until the element identified by locator is not clickable.
+ *
+ * Fails, if the timeout expires, before the element gets unclickable.
+ *
+ * See `Introduction` for details about locators and timeouts.
+ *
+ * @param locator
+ * The locator to locate the element.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "timeout=NONE", "message=NONE" })
+ public void waitUntilElementIsNotClickable(final String locator, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsSuccessfullyClicked(String locator, String timeout) {
+ waitUntilElementIsSuccessfullyClicked(locator, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsSuccessfullyClicked(String locator) {
+ waitUntilElementIsSuccessfullyClicked(locator, null);
+ }
+
+ /**
+ * Waits until the element identified by locator is sucessfully
+ * clicked on.
+ *
+ * Fails, if the timeout expires, before the element gets clicked on.
+ *
+ * See `Introduction` for details about locators and timeouts.
+ *
+ * @param locator
+ * The locator to locate the element.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "timeout=NONE", "message=NONE" })
+ public void waitUntilElementIsSuccessfullyClicked(final String locator, String timeout, String message) {
+ 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;
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsSelected(String locator, String timeout) {
+ waitUntilElementIsSelected(locator, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsSelected(String locator) {
+ waitUntilElementIsSelected(locator, null);
+ }
+
+ /**
+ * Waits until the element identified by locator is selected.
+ *
+ * Fails, if the timeout expires, before the element gets selected.
+ *
+ * See `Introduction` for details about locators and timeouts.
+ *
+ * @param locator
+ * The locator to locate the element.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "timeout=NONE", "message=NONE" })
+ public void waitUntilElementIsSelected(final String locator, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsNotSelected(String locator, String timeout) {
+ waitUntilElementIsNotSelected(locator, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilElementIsNotSelected(String locator) {
+ waitUntilElementIsNotSelected(locator, null);
+ }
+
+ /**
+ * Waits until the element identified by locator is not selected.
+ *
+ * Fails, if the timeout expires, before the element gets unselected.
+ *
+ * See `Introduction` for details about locators and timeouts.
+ *
+ * @param locator
+ * The locator to locate the element.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "locator", "timeout=NONE", "message=NONE" })
+ public void waitUntilElementIsNotSelected(final String locator, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilTitleContains(String title, String timeout) {
+ waitUntilTitleContains(title, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilTitleContains(String title) {
+ waitUntilTitleContains(title, null, null);
+ }
+
+ /**
+ * Waits until the current page title contains title.
+ *
+ * Fails, if the timeout expires, before the page title contains the given
+ * title.
+ *
+ * @param title
+ * The title to verify.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "title", "timeout=NONE", "message=NONE" })
+ public void waitUntilTitleContains(final String title, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilTitleNotContains(String title, String timeout) {
+ waitUntilTitleNotContains(title, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilTitleNotContains(String title) {
+ waitUntilTitleNotContains(title, null, null);
+ }
+
+ /**
+ * Waits until the current page title does not contain title.
+ *
+ * Fails, if the timeout expires, before the page title does not contain the
+ * given title.
+ *
+ * @param title
+ * The title to verify.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "title", "timeout=NONE", "message=NONE" })
+ public void waitUntilTitleNotContains(final String title, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilTitleIs(String title, String timeout) {
+ waitUntilTitleIs(title, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilTitleIs(String title) {
+ waitUntilTitleIs(title, null);
+ }
+
+ /**
+ * Waits until the current page title is exactly title.
+ *
+ * Fails, if the timeout expires, before the page title matches the given
+ * title.
+ *
+ * @param title
+ * The title to verify.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "title", "timeout=NONE", "message=NONE" })
+ public void waitUntilTitleIs(final String title, String timeout, String message) {
+ 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);
+ }
+ });
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilTitleIsNot(String title, String timeout) {
+ waitUntilTitleIsNot(title, timeout, null);
+ }
+
+ @RobotKeywordOverload
+ public void waitUntilTitleIsNot(String title) {
+ waitUntilTitleIsNot(title, null, null);
}
- public void waitUntilPageContainsElement(final String locator,
- String timestr, String error) {
- if (error == null) {
- error = String.format("Element '%s' did not appear in ",
- locator);
+ /**
+ * Waits until the current page title is not exactly title.
+ *
+ * Fails, if the timeout expires, before the page title does not match the
+ * given title.
+ *
+ * @param title
+ * The title to verify.
+ * @param timeout
+ * Default=NONE. Optional timeout interval.
+ * @param message
+ * Default=NONE. Optional custom error message.
+ */
+ @RobotKeyword
+ @ArgumentNames({ "title", "timeout=NONE", "message=NONE" })
+ public void waitUntilTitleIsNot(final String title, String timeout, String message) {
+ if (message == null) {
+ message = String.format("Title '%s' did not appear in ", title);
}
- waitUntil(timestr, error, new WaitUntilFunction() {
+ waitUntil(timeout, message, new WaitUntilFunction() {
@Override
public boolean isFinished() {
- return isElementPresent(locator);
+ String currentTitle = browserManagement.getTitle();
+ return currentTitle == null || !currentTitle.equals(title);
}
});
}
@@ -86,12 +672,9 @@ public boolean isFinished() {
// Internal Methods
// ##############################
- protected void waitUntil(String timestr, String error,
- WaitUntilFunction function) {
- double timeout = timestr != null ? Robotframework
- .timestrToSecs(timestr) : this.timeout;
- error = error.replace("",
- Robotframework.secsToTimestr(timeout));
+ protected void waitUntil(String timestr, String message, WaitUntilFunction function) {
+ double timeout = timestr != null ? Robotframework.timestrToSecs(timestr) : browserManagement.getTimeout();
+ message = message.replace("", Robotframework.secsToTimestr(timeout));
long maxtime = System.currentTimeMillis() + (long) (timeout * 1000);
for (;;) {
try {
@@ -101,7 +684,7 @@ protected void waitUntil(String timestr, String error,
} catch (Throwable t) {
}
if (System.currentTimeMillis() > maxtime) {
- throw new Selenium2LibraryNonFatalException(error);
+ throw new Selenium2LibraryNonFatalException(message);
}
try {
Thread.sleep(200);
diff --git a/src/main/java/com/github/markusbernhardt/selenium2library/locators/ElementFinder.java b/src/main/java/com/github/markusbernhardt/selenium2library/locators/ElementFinder.java
index 56c4cf4..c82b320 100644
--- a/src/main/java/com/github/markusbernhardt/selenium2library/locators/ElementFinder.java
+++ b/src/main/java/com/github/markusbernhardt/selenium2library/locators/ElementFinder.java
@@ -14,21 +14,20 @@
import org.openqa.selenium.WebElement;
import org.python.util.PythonInterpreter;
-import com.github.markusbernhardt.selenium2library.Selenium2Library;
import com.github.markusbernhardt.selenium2library.Selenium2LibraryNonFatalException;
+import com.github.markusbernhardt.selenium2library.keywords.Element;
import com.github.markusbernhardt.selenium2library.utils.Python;
public class ElementFinder {
- private final static Hashtable registeredLocationStrategies = new Hashtable();
+ protected final static Hashtable registeredLocationStrategies = new Hashtable();
- private enum KeyAttrs {
- DEFAULT("@id,@name"), A(
- "@id,@name,@href,normalize-space(descendant-or-self::text())"), IMG(
+ 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())");
- private String[] keyAttrs;
+ protected String[] keyAttrs;
KeyAttrs(String keyAttrs) {
this.keyAttrs = keyAttrs.split(",");
@@ -39,18 +38,16 @@ public String[] getKeyAttrs() {
}
}
- private interface Strategy {
- List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates);
+ protected interface Strategy {
+ List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates);
};
- private enum StrategyEnum implements Strategy {
+ protected enum StrategyEnum implements Strategy {
DEFAULT {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
if (findByCoordinates.criteria.startsWith("//")) {
return XPATH.findBy(webDriver, findByCoordinates);
}
@@ -60,88 +57,69 @@ public List findBy(WebDriver webDriver,
IDENTIFIER {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
- List elements = webDriver.findElements(By
- .id(findByCoordinates.criteria));
- elements.addAll(webDriver.findElements(By
- .name(findByCoordinates.criteria)));
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
+ List elements = webDriver.findElements(By.id(findByCoordinates.criteria));
+ elements.addAll(webDriver.findElements(By.name(findByCoordinates.criteria)));
return filterElements(elements, findByCoordinates);
}
},
ID {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
- return filterElements(webDriver.findElements(By
- .id(findByCoordinates.criteria)), findByCoordinates);
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
+ return filterElements(webDriver.findElements(By.id(findByCoordinates.criteria)), findByCoordinates);
}
},
NAME {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
- return filterElements(webDriver.findElements(By
- .name(findByCoordinates.criteria)), findByCoordinates);
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
+ return filterElements(webDriver.findElements(By.name(findByCoordinates.criteria)), findByCoordinates);
}
},
XPATH {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
- return filterElements(webDriver.findElements(By
- .xpath(findByCoordinates.criteria)), findByCoordinates);
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
+ return filterElements(webDriver.findElements(By.xpath(findByCoordinates.criteria)), findByCoordinates);
}
},
DOM {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
- Object result = ((JavascriptExecutor) webDriver)
- .executeScript(String.format("return %s;",
- findByCoordinates.criteria));
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
+ Object result = ((JavascriptExecutor) webDriver).executeScript(String.format("return %s;",
+ findByCoordinates.criteria));
return filterElements(toList(result), findByCoordinates);
}
},
LINK {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
- return filterElements(webDriver.findElements(By
- .linkText(findByCoordinates.criteria)),
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
+ return filterElements(webDriver.findElements(By.linkText(findByCoordinates.criteria)),
findByCoordinates);
}
},
CSS {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
- return filterElements(webDriver.findElements(By
- .cssSelector(findByCoordinates.criteria)),
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
+ return filterElements(webDriver.findElements(By.cssSelector(findByCoordinates.criteria)),
findByCoordinates);
}
},
TAG {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
- return filterElements(webDriver.findElements(By
- .tagName(findByCoordinates.criteria)),
- findByCoordinates);
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
+ return filterElements(webDriver.findElements(By.tagName(findByCoordinates.criteria)), findByCoordinates);
}
},
JQUERY {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
return findByJQuerySizzle(webDriver, findByCoordinates);
}
@@ -150,8 +128,7 @@ public List findBy(WebDriver webDriver,
SIZZLE {
@Override
- public List findBy(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
+ public List findBy(WebDriver webDriver, FindByCoordinates findByCoordinates) {
return findByJQuerySizzle(webDriver, findByCoordinates);
}
@@ -160,18 +137,15 @@ public List findBy(WebDriver webDriver,
}
- private static List findByJQuerySizzle(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
- String js = String.format("return jQuery('%s').get();",
- findByCoordinates.criteria.replace("'", "\\'"));
+ protected static List findByJQuerySizzle(WebDriver webDriver, FindByCoordinates findByCoordinates) {
+ String js = String.format("return jQuery('%s').get();", findByCoordinates.criteria.replace("'", "\\'"));
Object o = ((JavascriptExecutor) webDriver).executeScript(js);
List list = toList(o);
return filterElements(list, findByCoordinates);
}
- private static List filterElements(List elements,
- FindByCoordinates findByCoordinates) {
+ protected static List filterElements(List elements, FindByCoordinates findByCoordinates) {
if (findByCoordinates.tag == null) {
return elements;
}
@@ -185,16 +159,14 @@ private static List filterElements(List elements,
return result;
}
- private static boolean elementMatches(WebElement element,
- FindByCoordinates findByCoordinates) {
+ protected static boolean elementMatches(WebElement element, FindByCoordinates findByCoordinates) {
if (!element.getTagName().toLowerCase().equals(findByCoordinates.tag)) {
return false;
}
if (findByCoordinates.constraints != null) {
for (String name : findByCoordinates.constraints.keySet()) {
- if (!element.getAttribute(name).equals(
- findByCoordinates.constraints.get(name))) {
+ if (!element.getAttribute(name).equals(findByCoordinates.constraints.get(name))) {
return false;
}
}
@@ -203,49 +175,38 @@ private static boolean elementMatches(WebElement element,
return true;
}
- private static List findByKeyAttrs(WebDriver webDriver,
- FindByCoordinates findByCoordinates) {
+ protected static List findByKeyAttrs(WebDriver webDriver, FindByCoordinates findByCoordinates) {
KeyAttrs keyAttrs = KeyAttrs.DEFAULT;
if (findByCoordinates.tag != null) {
try {
- keyAttrs = KeyAttrs.valueOf(findByCoordinates.tag.trim()
- .toUpperCase());
+ keyAttrs = KeyAttrs.valueOf(findByCoordinates.tag.trim().toUpperCase());
} catch (IllegalArgumentException e) {
// No special keyAttrs available for this tag
}
}
- String xpathCriteria = Selenium2Library
- .escapeXpathValue(findByCoordinates.criteria);
+ String xpathCriteria = Element.escapeXpathValue(findByCoordinates.criteria);
String xpathTag = findByCoordinates.tag;
if (findByCoordinates.tag == null) {
xpathTag = "*";
}
List xpathConstraints = new ArrayList();
if (findByCoordinates.constraints != null) {
- for (Entry entry : findByCoordinates.constraints
- .entrySet()) {
- xpathConstraints.add(String.format("@%s='%s'", entry.getKey(),
- entry.getValue()));
+ for (Entry entry : findByCoordinates.constraints.entrySet()) {
+ xpathConstraints.add(String.format("@%s='%s'", entry.getKey(), entry.getValue()));
}
}
List xpathSearchers = new ArrayList();
for (String attr : keyAttrs.getKeyAttrs()) {
xpathSearchers.add(String.format("%s=%s", attr, xpathCriteria));
}
- xpathSearchers.addAll(getAttrsWithUrl(webDriver, keyAttrs,
- findByCoordinates.criteria));
- String xpath = String.format(
- "//%s[%s(%s)]",
- xpathTag,
- Python.join(" and ", xpathConstraints)
- + (xpathConstraints.size() > 0 ? " and " : ""),
- Python.join(" or ", xpathSearchers));
+ xpathSearchers.addAll(getAttrsWithUrl(webDriver, keyAttrs, findByCoordinates.criteria));
+ String xpath = String.format("//%s[%s(%s)]", xpathTag, Python.join(" and ", xpathConstraints)
+ + (xpathConstraints.size() > 0 ? " and " : ""), Python.join(" or ", xpathSearchers));
return webDriver.findElements(By.xpath(xpath));
}
- private static List getAttrsWithUrl(WebDriver webDriver,
- KeyAttrs keyAttrs, String criteria) {
+ protected static List getAttrsWithUrl(WebDriver webDriver, KeyAttrs keyAttrs, String criteria) {
List attrs = new ArrayList();
String url = null;
String xpathUrl = null;
@@ -255,7 +216,7 @@ private static List getAttrsWithUrl(WebDriver webDriver,
if (attr.equals(keyAttr)) {
if (url == null || xpathUrl == null) {
url = getBaseUrl(webDriver) + "/" + criteria;
- xpathUrl = Selenium2Library.escapeXpathValue(url);
+ xpathUrl = Element.escapeXpathValue(url);
}
attrs.add(String.format("%s=%s", attr, xpathUrl));
}
@@ -264,7 +225,7 @@ private static List getAttrsWithUrl(WebDriver webDriver,
return attrs;
}
- private static String getBaseUrl(WebDriver webDriver) {
+ protected static String getBaseUrl(WebDriver webDriver) {
String url = webDriver.getCurrentUrl();
int lastIndex = url.lastIndexOf('/');
if (lastIndex != -1) {
@@ -273,25 +234,20 @@ private static String getBaseUrl(WebDriver webDriver) {
return url;
}
- public static void addLocationStrategy(String strategyName,
- String functionDefinition, String delimiter) {
- registeredLocationStrategies.put(strategyName.toUpperCase(),
- new CustomStrategy(functionDefinition, delimiter));
+ public static void addLocationStrategy(String strategyName, String functionDefinition, String delimiter) {
+ registeredLocationStrategies.put(strategyName.toUpperCase(), new CustomStrategy(functionDefinition, delimiter));
}
public static List find(WebDriver webDriver, String locator) {
return find(webDriver, locator, null);
}
- public static List find(WebDriver webDriver, String locator,
- String tag) {
+ public static List find(WebDriver webDriver, String locator, String tag) {
if (webDriver == null) {
- throw new Selenium2LibraryNonFatalException(
- "ElementFinder.find: webDriver is null.");
+ throw new Selenium2LibraryNonFatalException("ElementFinder.find: webDriver is null.");
}
if (locator == null) {
- throw new Selenium2LibraryNonFatalException(
- "ElementFinder.find: locator is null.");
+ throw new Selenium2LibraryNonFatalException("ElementFinder.find: locator is null.");
}
FindByCoordinates findByCoordinates = new FindByCoordinates();
@@ -305,20 +261,17 @@ public static List find(WebDriver webDriver, String locator,
@Override
protected PythonInterpreter initialValue() {
PythonInterpreter pythonInterpreter = new PythonInterpreter();
- pythonInterpreter
- .exec("from robot.variables import GLOBAL_VARIABLES; from robot.api import logger;");
+ pythonInterpreter.exec("from robot.variables import GLOBAL_VARIABLES; from robot.api import logger;");
return pythonInterpreter;
}
};
protected static void warn(String msg) {
loggingPythonInterpreter.get().exec(
- String.format("logger.warn('%s');", msg.replace("'", "\\'")
- .replace("\n", "\\n")));
+ String.format("logger.warn('%s');", msg.replace("'", "\\'").replace("\n", "\\n")));
}
- private static Strategy parseLocator(FindByCoordinates findByCoordinates,
- String locator) {
+ protected static Strategy parseLocator(FindByCoordinates findByCoordinates, String locator) {
String prefix = null;
String criteria = locator;
if (!locator.startsWith("//")) {
@@ -335,8 +288,7 @@ private static Strategy parseLocator(FindByCoordinates findByCoordinates,
strategy = StrategyEnum.valueOf(prefix);
} catch (IllegalArgumentException e) {
// No standard locator type. Look for custom strategy
- CustomStrategy customStrategy = registeredLocationStrategies
- .get(prefix);
+ CustomStrategy customStrategy = registeredLocationStrategies.get(prefix);
if (customStrategy != null) {
strategy = customStrategy;
}
@@ -346,8 +298,7 @@ private static Strategy parseLocator(FindByCoordinates findByCoordinates,
return strategy;
}
- private static void parseTag(FindByCoordinates findByCoordinates,
- Strategy strategy, String tag) {
+ protected static void parseTag(FindByCoordinates findByCoordinates, Strategy strategy, String tag) {
if (tag == null) {
return;
}
@@ -359,6 +310,8 @@ private static void parseTag(FindByCoordinates findByCoordinates,
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");
@@ -377,7 +330,7 @@ private static void parseTag(FindByCoordinates findByCoordinates,
}
@SuppressWarnings("unchecked")
- private static List toList(Object o) {
+ protected static List toList(Object o) {
if (o instanceof List>) {
return (List) o;
}
@@ -389,18 +342,18 @@ private static List toList(Object o) {
return list;
}
- private static class FindByCoordinates {
+ protected static class FindByCoordinates {
String criteria;
String tag;
Map constraints;
}
- private static class CustomStrategy implements Strategy {
+ protected static class CustomStrategy implements Strategy {
- private String functionDefinition;
+ protected String functionDefinition;
- private String delimiter;
+ protected String delimiter;
public CustomStrategy(String functionDefinition, String delimiter) {
this.functionDefinition = functionDefinition;
@@ -408,8 +361,7 @@ public CustomStrategy(String functionDefinition, String delimiter) {
}
@Override
- public List findBy(final WebDriver webDriver,
- final FindByCoordinates findByCoordinates) {
+ public List findBy(final WebDriver webDriver, final FindByCoordinates findByCoordinates) {
return filterElements(webDriver.findElements(new By() {
@Override
@@ -419,15 +371,13 @@ public List findElements(SearchContext context) {
arguments = new Object[1];
arguments[0] = findByCoordinates.criteria;
} else {
- String[] splittedCriteria = findByCoordinates.criteria
- .split(delimiter);
+ String[] splittedCriteria = findByCoordinates.criteria.split(delimiter);
arguments = new Object[splittedCriteria.length];
for (int i = 0; i < splittedCriteria.length; i++) {
arguments[i] = splittedCriteria[i];
}
}
- Object o = ((JavascriptExecutor) webDriver).executeScript(
- functionDefinition, arguments);
+ Object o = ((JavascriptExecutor) webDriver).executeScript(functionDefinition, arguments);
return toList(o);
}
diff --git a/src/main/java/com/github/markusbernhardt/selenium2library/locators/TableElementFinder.java b/src/main/java/com/github/markusbernhardt/selenium2library/locators/TableElementFinder.java
index 0fe738a..a0410fc 100644
--- a/src/main/java/com/github/markusbernhardt/selenium2library/locators/TableElementFinder.java
+++ b/src/main/java/com/github/markusbernhardt/selenium2library/locators/TableElementFinder.java
@@ -10,7 +10,7 @@
public class TableElementFinder {
- private final static TreeMap> locatorSuffixesMap;
+ protected final static TreeMap> locatorSuffixesMap;
static {
locatorSuffixesMap = new TreeMap |