diff --git a/java/client/src/org/openqa/selenium/support/ui/Select.java b/java/client/src/org/openqa/selenium/support/ui/Select.java index c0e88c2ca97be..63f903d702a0e 100644 --- a/java/client/src/org/openqa/selenium/support/ui/Select.java +++ b/java/client/src/org/openqa/selenium/support/ui/Select.java @@ -21,9 +21,9 @@ import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebElement; -import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import java.util.stream.Collectors; /** * Models a SELECT tag, providing helper methods to select and deselect options. @@ -59,6 +59,7 @@ public Select(WebElement element) { * @return Whether this select element support selecting multiple options at the same time? This * is done by checking the value of the "multiple" attribute. */ + @Override public boolean isMultiple() { return isMulti; } @@ -66,6 +67,7 @@ public boolean isMultiple() { /** * @return All options belonging to this select tag */ + @Override public List getOptions() { return element.findElements(By.tagName("option")); } @@ -73,16 +75,9 @@ public List getOptions() { /** * @return All selected options belonging to this select tag */ + @Override public List getAllSelectedOptions() { - List toReturn = new ArrayList<>(); - - for (WebElement option : getOptions()) { - if (option.isSelected()) { - toReturn.add(option); - } - } - - return toReturn; + return getOptions().stream().filter(WebElement::isSelected).collect(Collectors.toList()); } /** @@ -90,14 +85,10 @@ public List getAllSelectedOptions() { * normal select) * @throws NoSuchElementException If no option is selected */ + @Override public WebElement getFirstSelectedOption() { - for (WebElement option : getOptions()) { - if (option.isSelected()) { - return option; - } - } - - throw new NoSuchElementException("No options are selected"); + return getOptions().stream().filter(WebElement::isSelected).findFirst() + .orElseThrow(() -> new NoSuchElementException("No options are selected")); } /** @@ -115,16 +106,15 @@ public void selectByVisibleText(String text) { List options = element.findElements(By.xpath(".//option[normalize-space(.) = " + Quotes.escape(text) + "]")); - boolean matched = false; for (WebElement option : options) { setSelected(option, true); if (!isMultiple()) { return; } - matched = true; } - if (options.isEmpty() && text.contains(" ")) { + boolean matched = !options.isEmpty(); + if (!matched && text.contains(" ")) { String subStringWithoutSpace = getLongestSubstringWithoutSpace(text); List candidates; if ("".equals(subStringWithoutSpace)) { @@ -171,16 +161,9 @@ private String getLongestSubstringWithoutSpace(String s) { * @param index The option at this index will be selected * @throws NoSuchElementException If no matching option elements are found */ + @Override public void selectByIndex(int index) { - String match = String.valueOf(index); - - for (WebElement option : getOptions()) { - if (match.equals(option.getAttribute("index"))) { - setSelected(option, true); - return; - } - } - throw new NoSuchElementException("Cannot locate option with index: " + index); + setSelectedByIndex(index, true); } /** @@ -192,21 +175,13 @@ public void selectByIndex(int index) { * @param value The value to match against * @throws NoSuchElementException If no matching option elements are found */ + @Override public void selectByValue(String value) { - List options = element.findElements(By.xpath( - ".//option[@value = " + Quotes.escape(value) + "]")); - - boolean matched = false; - for (WebElement option : options) { + for (WebElement option : findOptionsByValue(value)) { setSelected(option, true); if (!isMultiple()) { return; } - matched = true; - } - - if (!matched) { - throw new NoSuchElementException("Cannot locate option with value: " + value); } } @@ -215,6 +190,7 @@ public void selectByValue(String value) { * * @throws UnsupportedOperationException If the SELECT does not support multiple selections */ + @Override public void deselectAll() { if (!isMultiple()) { throw new UnsupportedOperationException( @@ -236,21 +212,15 @@ public void deselectAll() { * @throws NoSuchElementException If no matching option elements are found * @throws UnsupportedOperationException If the SELECT does not support multiple selections */ + @Override public void deselectByValue(String value) { if (!isMultiple()) { throw new UnsupportedOperationException( "You may only deselect options of a multi-select"); } - List options = element.findElements(By.xpath( - ".//option[@value = " + Quotes.escape(value) + "]")); - boolean matched = false; - for (WebElement option : options) { + for (WebElement option : findOptionsByValue(value)) { setSelected(option, false); - matched = true; - } - if (!matched) { - throw new NoSuchElementException("Cannot locate option with value: " + value); } } @@ -262,21 +232,14 @@ public void deselectByValue(String value) { * @throws NoSuchElementException If no matching option elements are found * @throws UnsupportedOperationException If the SELECT does not support multiple selections */ + @Override public void deselectByIndex(int index) { if (!isMultiple()) { throw new UnsupportedOperationException( "You may only deselect options of a multi-select"); } - String match = String.valueOf(index); - - for (WebElement option : getOptions()) { - if (match.equals(option.getAttribute("index"))) { - setSelected(option, false); - return; - } - } - throw new NoSuchElementException("Cannot locate option with index: " + index); + setSelectedByIndex(index, false); } /** @@ -289,6 +252,7 @@ public void deselectByIndex(int index) { * @throws NoSuchElementException If no matching option elements are found * @throws UnsupportedOperationException If the SELECT does not support multiple selections */ + @Override public void deselectByVisibleText(String text) { if (!isMultiple()) { throw new UnsupportedOperationException( @@ -297,16 +261,34 @@ public void deselectByVisibleText(String text) { List options = element.findElements(By.xpath( ".//option[normalize-space(.) = " + Quotes.escape(text) + "]")); + if (options.isEmpty()) { + throw new NoSuchElementException("Cannot locate element with text: " + text); + } - boolean matched = false; for (WebElement option : options) { setSelected(option, false); - matched = true; } + } - if (!matched) { - throw new NoSuchElementException("Cannot locate element with text: " + text); + private List findOptionsByValue(String value) { + List options = element.findElements(By.xpath( + ".//option[@value = " + Quotes.escape(value) + "]")); + if (options.isEmpty()) { + throw new NoSuchElementException("Cannot locate option with value: " + value); + } + return options; + } + + private void setSelectedByIndex(int index, boolean select) { + String match = String.valueOf(index); + + for (WebElement option : getOptions()) { + if (match.equals(option.getAttribute("index"))) { + setSelected(option, select); + return; + } } + throw new NoSuchElementException("Cannot locate option with index: " + index); } /** @@ -319,8 +301,7 @@ public void deselectByVisibleText(String text) { * deselected (false) */ private void setSelected(WebElement option, boolean select) { - boolean isSelected=option.isSelected(); - if ((!isSelected && select) || (isSelected && !select)) { + if (option.isSelected() != select) { option.click(); } }