Skip to content

Commit

Permalink
Merge pull request #105 from aquality-automation/Feature/Add-Multicho…
Browse files Browse the repository at this point in the history
…ice-Combobox

Feature/add multichoice combobox
closes #65
  • Loading branch information
aqualityAutomation authored Feb 15, 2024
2 parents aff8e90 + 3a4bf4f commit 9751590
Show file tree
Hide file tree
Showing 17 changed files with 461 additions and 13 deletions.
8 changes: 4 additions & 4 deletions src/main/java/aquality/selenium/elements/ComboBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,20 @@ public void clickAndSelectByText(String value) {
@Override
public void selectByContainingText(String text) {
logElementAction("loc.combobox.select.by.text", text);
selectOptionThatContains(WebElement::getText,
applyFunctionToOptionsThatContain(WebElement::getText,
Select::selectByVisibleText,
text);
}

@Override
public void selectByContainingValue(String value) {
logElementAction(LOG_SELECTING_VALUE, value);
selectOptionThatContains(element -> element.getAttribute(Attributes.VALUE.toString()),
applyFunctionToOptionsThatContain(element -> element.getAttribute(Attributes.VALUE.toString()),
Select::selectByValue,
value);
}

private void selectOptionThatContains(Function<WebElement, String> getValueFunc, BiConsumer<Select, String> selectFunc, String value){
protected void applyFunctionToOptionsThatContain(Function<WebElement, String> getValueFunc, BiConsumer<Select, String> selectFunc, String value){
doWithRetry(() -> {
Select select = new Select(getElement());
List<WebElement> elements = select.getOptions();
Expand All @@ -77,7 +77,7 @@ private void selectOptionThatContains(Function<WebElement, String> getValueFunc,
}
if (!isSelected){
throw new InvalidElementStateException(String.format(getLocalizationManager().getLocalizedMessage(
"loc.combobox.impossible.to.select.contain.value.or.text"), value, getName()));
"loc.combobox.impossible.to.find.option.contain.value.or.text"), value, getName()));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ protected Map<Class<? extends aquality.selenium.core.elements.interfaces.IElemen
typesMap.put(IButton.class, Button.class);
typesMap.put(ICheckBox.class, CheckBox.class);
typesMap.put(IComboBox.class, ComboBox.class);
typesMap.put(IMultiChoiceBox.class, MultiChoiceBox.class);
typesMap.put(ILabel.class, Label.class);
typesMap.put(ILink.class, Link.class);
typesMap.put(IRadioButton.class, RadioButton.class);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/aquality/selenium/elements/ElementType.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public enum ElementType {
BUTTON(IButton.class),
CHECKBOX(ICheckBox.class),
COMBOBOX(IComboBox.class),
MULTICHOICEBOX(IMultiChoiceBox.class),
LABEL(ILabel.class),
LINK(ILink.class),
RADIOBUTTON(IRadioButton.class),
Expand Down
99 changes: 99 additions & 0 deletions src/main/java/aquality/selenium/elements/MultiChoiceBox.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package aquality.selenium.elements;

import aquality.selenium.core.elements.ElementState;
import aquality.selenium.elements.interfaces.IMultiChoiceBox;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* Class describing the Multi-choice ComboBox (dropdown list), i.e. the one having attribute {@code multiple} set to {@code true}
*/
public class MultiChoiceBox extends ComboBox implements IMultiChoiceBox {

private static final String LOG_DESELECTING_VALUE = "loc.deselecting.value";

protected MultiChoiceBox(By locator, String name, ElementState state) {
super(locator, name, state);
}

protected String getElementType() {
return getLocalizationManager().getLocalizedMessage("loc.multichoicebox");
}

@Override
public List<String> getSelectedValues() {
logElementAction("loc.combobox.getting.selected.value");
return collectSelectedOptions(option -> option.getAttribute(Attributes.VALUE.toString()), "value");
}

@Override
public List<String> getSelectedTexts() {
logElementAction("loc.combobox.getting.selected.text");
return collectSelectedOptions(WebElement::getText, "text");
}

private List<String> collectSelectedOptions(Function<WebElement, String> valueGetter, String valueType) {
List<String> texts = doWithRetry(() ->
new Select(getElement()).getAllSelectedOptions()
.stream()
.map(valueGetter)
.collect(Collectors.toList()));
String logValue = texts.stream().map(value -> String.format("'%s'", value)).collect(Collectors.joining(", "));
logElementAction(String.format("loc.combobox.selected.%s", valueType), logValue);
return texts;
}

@Override
public void selectAll() {
logElementAction("loc.multichoicebox.select.all");
applyFunctionToOptionsThatContain(element -> element.getAttribute(Attributes.VALUE.toString()),
Select::selectByValue,
StringUtils.EMPTY);
}

@Override
public void deselectAll() {
logElementAction("loc.multichoicebox.deselect.all");
doWithRetry(() -> new Select(getElement()).deselectAll());
}

@Override
public void deselectByIndex(int index) {
logElementAction(LOG_DESELECTING_VALUE, String.format("#%s", index));
doWithRetry(() -> new Select(getElement()).deselectByIndex(index));
}

@Override
public void deselectByValue(String value) {
logElementAction(LOG_DESELECTING_VALUE, value);
doWithRetry(() -> new Select(getElement()).deselectByValue(value));
}

@Override
public void deselectByContainingValue(String value) {
logElementAction(LOG_DESELECTING_VALUE, value);
applyFunctionToOptionsThatContain(element -> element.getAttribute(Attributes.VALUE.toString()),
Select::deselectByValue,
value);
}

@Override
public void deselectByText(String text) {
logElementAction("loc.multichoicebox.deselect.by.text", text);
doWithRetry(() -> new Select(getElement()).deselectByVisibleText(text));
}

@Override
public void deselectByContainingText(String text) {
logElementAction("loc.multichoicebox.deselect.by.text", text);
applyFunctionToOptionsThatContain(WebElement::getText,
Select::deselectByVisibleText,
text);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,29 @@ default IComboBox getComboBox(By locator, String name, ElementState state) {
return get(ElementType.COMBOBOX, locator, name, state);
}

/**
* Creates element that implements IMultiChoiceBox interface.
*
* @param locator Element locator
* @param name Element name
* @return Instance of element that implements IMultiChoiceBox interface
*/
default IMultiChoiceBox getMultiChoiceBox(By locator, String name) {
return getMultiChoiceBox(locator, name, ElementState.DISPLAYED);
}

/**
* Creates element that implements IMultiChoiceBox interface.
*
* @param locator Element locator
* @param name Element name
* @param state Element state
* @return Instance of element that implements IMultiChoiceBox interface
*/
default IMultiChoiceBox getMultiChoiceBox(By locator, String name, ElementState state) {
return get(ElementType.MULTICHOICEBOX, locator, name, state);
}

/**
* Creates element that implements ILabel interface.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package aquality.selenium.elements.interfaces;

import java.util.List;

public interface IMultiChoiceBox extends IComboBox {

/**
* Gets value of all selected options
*
* @return selected values
*/
List<String> getSelectedValues();

/**
* Gets text of all selected options
*
* @return selected text
*/
List<String> getSelectedTexts();

/**
* Select all options
*/
void selectAll();

/**
* Deselect all selected options
*/
void deselectAll();

/**
* Deselect selected option by index
*
* @param index number of selected option
*/
void deselectByIndex(int index);

/**
* Deselect selected option by value
*
* @param value argument value
*/
void deselectByValue(String value);

/**
* Deselect selected option by containing value
*
* @param value partial option's value
*/
void deselectByContainingValue(String value);

/**
* Deselect selected option by visible text
*
* @param text text to be deselected
*/
void deselectByText(String text);

/**
* Deselect selected option by containing visible text
*
* @param text visible text
*/
void deselectByContainingText(String text);
}
7 changes: 6 additions & 1 deletion src/main/resources/localization/be.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@
"loc.combobox.get.text.js": "Атрымліваем выбраны тэкст праз JavaScript",
"loc.combobox.texts": "Спіс тэкстаў опцыяў: [%s]",
"loc.combobox.values": "Спіс значэнняў: [%s]",
"loc.combobox.impossible.to.select.contain.value.or.text": "Немагчыма выбраць опцыю, якая змяшчае значэнне/тэкст '%1$s' у камбабоксе '%2$s'",
"loc.combobox.impossible.to.find.option.contain.value.or.text": "Немагчыма знайсці опцыю, якая змяшчае значэнне/тэкст '%1$s' у камбабоксе '%2$s'",
"loc.multichoicebox": "Камбабокс з мульцівыбарам",
"loc.multichoicebox.select.all": "Выбіраем усе значэнні",
"loc.multichoicebox.deselect.all": "Адмяняем выбар усіх значэнняў",
"loc.multichoicebox.deselect.by.text": "Адмяняем выбар значэння з тэкстам '%s'",
"loc.el.getattr": "Атрымліваем атрыбут '%1$s'",
"loc.el.attr.value": "Значэнне атрыбута '%1$s': [%2$s]",
"loc.el.attr.set": "Задаем значэнне атрыбута '%1$s': [%2$s]",
Expand All @@ -68,6 +72,7 @@
"loc.scrolling.center.js": "Пракручваем старонку да цэнтра элемента праз JavaScript",
"loc.scrolling.js": "Пракручваем старонку праз JavaScript",
"loc.selecting.value": "Выбіраем значэнне - '%s'",
"loc.deselecting.value": "Адмяняем выбар значэння - '%s'",
"loc.send.text": "Задаем тэкст - '%s'",
"loc.setting.value": "Задаем значэнне - '%s'",
"loc.text.clearing": "Ачышчаем",
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/localization/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@
"loc.combobox.get.text.js": "Getting selected text via JavaScript",
"loc.combobox.texts": "Option texts: [%s]",
"loc.combobox.values": "Option values: [%s]",
"loc.combobox.impossible.to.select.contain.value.or.text": "It is impossible to select option that contains value/text '%1$s' from combobox '%2$s'",
"loc.combobox.impossible.to.find.option.contain.value.or.text": "It is impossible to find an option that contains value/text '%1$s' from combobox '%2$s'",
"loc.multichoicebox": "Multi-choice ComboBox",
"loc.multichoicebox.select.all": "Select all",
"loc.multichoicebox.deselect.all": "Deselect all",
"loc.multichoicebox.deselect.by.text": "Deselecting value by text '%s'",
"loc.el.getattr": "Getting attribute '%1$s'",
"loc.el.attr.value": "Value of attribute '%1$s': [%2$s]",
"loc.el.attr.set": "Setting value of attribute '%1$s': [%2$s]",
Expand All @@ -68,6 +72,7 @@
"loc.scrolling.center.js": "Scrolling to the center via JavaScript",
"loc.scrolling.js": "Scrolling via JavaScript",
"loc.selecting.value": "Selecting value - '%s'",
"loc.deselecting.value": "Deselecting value - '%s'",
"loc.send.text": "Setting text - '%s'",
"loc.setting.value": "Setting value - '%s'",
"loc.text.clearing": "Clearing",
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/localization/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@
"loc.combobox.get.text.js": "Pobieranie wybranego tekstu przez JavaScript",
"loc.combobox.texts": "Lista tekstów opcji: [%s]",
"loc.combobox.values": "Lista wartości: [%s]",
"loc.combobox.impossible.to.select.contain.value.or.text": "Wybieranie wartości ze znaczeniem/tekstem '%1$s' w polu kombi '%2$s' nie jest możliwe",
"loc.combobox.impossible.to.find.option.contain.value.or.text": "Znalezienie wartości ze znaczeniem/tekstem '%1$s' w polu kombi '%2$s' nie jest możliwe",
"loc.multichoicebox": "Pole kombi z multiwyborem",
"loc.multichoicebox.select.all": "Wybieranie wszystkich wartości",
"loc.multichoicebox.deselect.all": "Anulowanie wybierania wszystkich wartości",
"loc.multichoicebox.deselect.by.text": "Anulowanie wybierania wartości z tekstem '%s'",
"loc.el.getattr": "Pobieranie atrybutu '%1$s'",
"loc.el.attr.value": "Wartość atrybutu '%1$s': [%2$s]",
"loc.el.attr.set": "Ustawianie wartości atrybutu '%1$s': [%2$s]",
Expand All @@ -68,6 +72,7 @@
"loc.scrolling.center.js": "Przewijanie do centrum przez JavaScript",
"loc.scrolling.js": "Przewijanie przez JavaScript",
"loc.selecting.value": "Wybieranie wartości - '%s'",
"loc.deselecting.value": "Anulowanie wybierania wartości - '%s'",
"loc.send.text": "Ustawianie tekstu - '%s'",
"loc.setting.value": "Ustawienie wartości - '%s'",
"loc.text.clearing": "Oczyszczenie",
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/localization/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@
"loc.combobox.get.text.js": "Получение текста выбранного значения посредством JavaScript",
"loc.combobox.texts": "Список текстов опций: [%s]",
"loc.combobox.values": "Список значений: [%s]",
"loc.combobox.impossible.to.select.contain.value.or.text": "Не удаётся выбрать значение которое содержит значение/текст '%1$s' в выпадающем списке '%2$s'",
"loc.combobox.impossible.to.find.option.contain.value.or.text": "Не удаётся найти опцию, которая содержит значение/текст '%1$s' в выпадающем списке '%2$s'",
"loc.multichoicebox": "Комбобокс с мультивыбором",
"loc.multichoicebox.select.all": "Выбор всех значений",
"loc.multichoicebox.deselect.all": "Отмена выбора всех значений",
"loc.multichoicebox.deselect.by.text": "Отмена выбора значения с текстом '%s'",
"loc.el.getattr": "Получение аттрибута '%1$s'",
"loc.el.attr.value": "Значение аттрибута '%1$s'': [%2$s]",
"loc.el.attr.set": "Установка значения атрибута '%1$s': [%2$s]",
Expand All @@ -68,6 +72,7 @@
"loc.scrolling.center.js": "Скроллинг в центр (посредством JavaScript)",
"loc.scrolling.js": "Скроллинг посредством JavaScript",
"loc.selecting.value": "Выбор значения - '%s'",
"loc.deselecting.value": "Отмена выбора значения - '%s'",
"loc.send.text": "Ввод текста - '%s'",
"loc.setting.value": "Установка значения - '%s'",
"loc.text.clearing": "Очистка",
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/localization/uk.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@
"loc.combobox.get.text.js": "Отримання вибраного тексту за допомогою JavaScript",
"loc.combobox.texts": "Тексти опцій: [%s]",
"loc.combobox.values": "Значення опцій: [%s]",
"loc.combobox.impossible.to.select.contain.value.or.text": "Неможливо вибрати опцію, що зміщує значення/текст '%1$s' у комбобоксі '%2$s'",
"loc.combobox.impossible.to.find.option.contain.value.or.text": "Неможливо знайти опцію, що містіть значення/текст '%1$s' у комбобоксі '%2$s'",
"loc.multichoicebox": "Комбобокс з мультівибором",
"loc.multichoicebox.select.all": "Вибір всіх значень",
"loc.multichoicebox.deselect.all": "Скасування вибору всіх значень",
"loc.multichoicebox.deselect.by.text": "Скасування вибору значення за текстом '%s'",
"loc.el.getattr": "Отримання атрибута '%1$s'",
"loc.el.attr.value": "Значення атрибута '%1$s': [%2$s]",
"loc.el.attr.set": "Встановлення значення атрибута '%1$s': [%2$s]",
Expand All @@ -68,6 +72,7 @@
"loc.scrolling.center.js": "Прокрутка до центру за допомогою JavaScript",
"loc.scrolling.js": "Прокрутка за допомогою JavaScript",
"loc.selecting.value": "Вибір значення - '%s'",
"loc.deselecting.value": "Скасування выбору значення - '%s'",
"loc.send.text": "Встановлення тексту - '%s'",
"loc.setting.value": "Встановлення значення - '%s'",
"loc.text.clearing": "Очищення",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.integration;
package tests.integration.elements;

import aquality.selenium.browser.AqualityServices;
import aquality.selenium.core.elements.ElementState;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.integration;
package tests.integration.elements;

import aquality.selenium.core.elements.ElementState;
import aquality.selenium.core.elements.ElementsCount;
Expand Down
Loading

0 comments on commit 9751590

Please sign in to comment.