From 0e9b16f572fd66e8acb00d389bad771d62bf610a Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Thu, 5 Mar 2020 15:54:18 +0300 Subject: [PATCH 1/3] Form: add possibility to extend form with custom elements There can be custom html elements in html form in some applications (for example, custom autocomplete fields). User is able fill forms with custom html elements, by extending Form class and providing operations for custom elements in constructor. --- .../htmlelements/element/CheckBox.java | 7 +- .../htmlelements/element/FileInput.java | 7 +- .../htmlelements/element/Fillable.java | 5 + .../qatools/htmlelements/element/Form.java | 157 ++++++------------ .../htmlelements/element/FormBase.java | 102 ++++++++++++ .../qatools/htmlelements/element/Radio.java | 7 +- .../qatools/htmlelements/element/Select.java | 7 +- .../htmlelements/element/TextInput.java | 7 +- 8 files changed, 188 insertions(+), 111 deletions(-) create mode 100644 htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Fillable.java create mode 100644 htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/FormBase.java diff --git a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/CheckBox.java b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/CheckBox.java index a08eacd0..9f73706e 100644 --- a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/CheckBox.java +++ b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/CheckBox.java @@ -10,7 +10,7 @@ * @author Artem Koshelev artkoshelev@yandex-team.ru * @author Alexander Tolmachev starlight@yandex-team.ru */ -public class CheckBox extends TypifiedElement { +public class CheckBox extends TypifiedElement implements Fillable { /** * Specifies wrapped {@link WebElement}. * @@ -80,4 +80,9 @@ public void set(boolean value) { deselect(); } } + + @Override + public void fill(String value) { + set(Boolean.parseBoolean(value)); + } } diff --git a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/FileInput.java b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/FileInput.java index e29e4761..3c6d8b4f 100644 --- a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/FileInput.java +++ b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/FileInput.java @@ -15,7 +15,7 @@ * @author Alexander Tolmachev starlight@yandex-team.ru * Date: 11.04.13 */ -public class FileInput extends TypifiedElement { +public class FileInput extends TypifiedElement implements Fillable { /** * Specifies wrapped {@link WebElement}. * @@ -74,4 +74,9 @@ private String getPathForSystemFile(final String fileName) { File file = new File(fileName); return file.getPath(); } + + @Override + public void fill(String value) { + setFileToUpload(value); + } } diff --git a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Fillable.java b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Fillable.java new file mode 100644 index 00000000..23f0d880 --- /dev/null +++ b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Fillable.java @@ -0,0 +1,5 @@ +package ru.yandex.qatools.htmlelements.element; + +public interface Fillable { + void fill(String value); +} diff --git a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Form.java b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Form.java index a903d898..272b2030 100644 --- a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Form.java +++ b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Form.java @@ -1,122 +1,67 @@ package ru.yandex.qatools.htmlelements.element; -import org.openqa.selenium.By; import org.openqa.selenium.WebElement; -import java.util.AbstractMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static java.util.Objects.isNull; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** - * Represents web page form tag. - * Provides handy way of filling form with data and submitting it. + * Represents default web page form tag. * * @author Artem Eroshenko eroshenkoam@yandex-team.ru - * 3/14/13, 4:38 PM + * 3/14/13, 4:38 PM * @author Alexander Tolmachev starlight@yandex-team.ru - * Date: 26.03.13 + * Date: 26.03.13 + * @author Dzmitry Sankouski sankouski.dzmitry@gmail.com + * Date: 05.03.2020 */ -public class Form extends TypifiedElement { - private static final String CHECKBOX_FIELD = "checkbox"; - private static final String RADIO_FIELD = "radio"; - private static final String SELECT_FIELD = "select"; - private static final String INPUT_FIELD = "input"; - private static final String FILE_FIELD = "file"; - +public class Form extends FormBase { /** - * Specifies {@link org.openqa.selenium.WebElement} representing form tag. - * - * @param wrappedElement {@code WebElement} to wrap. - */ - public Form(WebElement wrappedElement) { - super(wrappedElement); - } + * Fillable operations definition + * */ + private static List fillableOpsList = Arrays.asList( + new FillableOps( + CheckBox::new, + element -> { + String tagName = element.getTagName(); + String type = element.getAttribute("type"); + return "input".equals(tagName) && "checkbox".equals(type); + }), + new FillableOps( + Radio::new, + element -> { + String tagName = element.getTagName(); + String type = element.getAttribute("type"); + return "input".equals(tagName) && "radio".equals(type); + }), + new FillableOps( + FileInput::new, + element -> { + String tagName = element.getTagName(); + String type = element.getAttribute("type"); + return "input".equals(tagName) && "file".equals(type); + }), + new FillableOps( + Select::new, + element -> { + String tagName = element.getTagName(); + return "select".equals(tagName); + }), + new FillableOps( + TextInput::new, + element -> { + String tagName = element.getTagName(); + return "input".equals(tagName) || "textarea".equals(tagName); + }) + ); - /** - * Fills form with data contained in passed map. - * For each map entry if an input with a name coincident with entry key exists - * it is filled with string representation of entry value. - * If an input with such a name is not found the corresponding entry is skipped. - * - * @param data Map containing data to fill form inputs with. - */ - public void fill(Map data) { - data.entrySet().stream() - .map(e -> new AbstractMap.SimpleEntry<>( - findElementByKey(e.getKey()), - Objects.toString(e.getValue(), ""))) - .filter(e -> !isNull(e.getKey())) - .forEach(e -> fillElement(e.getKey(), e.getValue())); - } - - protected WebElement findElementByKey(String key) { - List elements = getWrappedElement().findElements(By.name(key)); - if (elements.isEmpty()) { - return null; - } else { - return elements.get(0); - } - } - - protected void fillElement(WebElement element, String value) { - String elementType = getElementType(element); - - if (CHECKBOX_FIELD.equals(elementType)) { - fillCheckBox(element, value); - } else if (RADIO_FIELD.equals(elementType)) { - fillRadio(element, value); - } else if (INPUT_FIELD.equals(elementType)) { - fillInput(element, value); - } else if (SELECT_FIELD.equals(elementType)) { - fillSelect(element, value); - } else if (FILE_FIELD.equals(elementType)) { - fillFile(element, value); - } - } - - protected String getElementType(WebElement element) { - String tagName = element.getTagName(); - if ("input".equals(tagName)) { - String type = element.getAttribute("type"); - if ("checkbox".equals(type)) { - return CHECKBOX_FIELD; - } else if ("radio".equals(type)) { - return RADIO_FIELD; - } else if ("file".equals(type)) { - return FILE_FIELD; - } else { - return INPUT_FIELD; - } - } else if ("select".equals(tagName)) { - return SELECT_FIELD; - } else if ("textarea".equals(tagName)) { - return INPUT_FIELD; - } else { - return null; - } - } - - protected void fillCheckBox(WebElement element, String value) { - new CheckBox(element).set(Boolean.parseBoolean(value)); - } - - protected void fillRadio(WebElement element, String value) { - new Radio(element).selectByValue(value); - } - - protected void fillInput(WebElement element, String value) { - TextInput input = new TextInput(element); - input.sendKeys(input.getClearCharSequence() + value); - } - - protected void fillSelect(WebElement element, String value) { - new Select(element).selectByValue(value); + public Form(WebElement wrappedElement) { + super(wrappedElement, fillableOpsList); } - protected void fillFile(WebElement element, String value) { - new FileInput(element).setFileToUpload(value); + public Form(WebElement wrappedElement, List additionalElements) { + super(wrappedElement, Stream.concat( + additionalElements.stream(), fillableOpsList.stream()).collect(Collectors.toList())); } } diff --git a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/FormBase.java b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/FormBase.java new file mode 100644 index 00000000..05cb7c09 --- /dev/null +++ b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/FormBase.java @@ -0,0 +1,102 @@ +package ru.yandex.qatools.htmlelements.element; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; + +import static java.util.Objects.isNull; + +/** + * Represents web page form tag. + * Provides handy way of filling form with data and submitting it. + *

+ * Form use {@link Fillable} elements, to perform filling. + * You should extend this class and define operations for {@link Fillable} you want to use. + * + * @author Artem Eroshenko eroshenkoam@yandex-team.ru + * 3/14/13, 4:38 PM + * @author Alexander Tolmachev starlight@yandex-team.ru + * Date: 26.03.13 + * @author Dzmitry Sankouski sankouski.dzmitry@gmail.com + * Date: 05.03.2020 + */ +public abstract class FormBase extends TypifiedElement { + /** + * Operations for supported fillable types + */ + private List fillableOpsList; + + /** + * Specifies {@link org.openqa.selenium.WebElement} representing form tag. + * + * @param wrappedElement {@code WebElement} to wrap. + * @param fillableOpsList Fillable operations to register. See {@link FillableOps#FillableOps(Function, Predicate)} + * Order is important, because {@link #fill(Map)} finds first fillable it can fill. + */ + public FormBase(WebElement wrappedElement, List fillableOpsList) { + super(wrappedElement); + this.fillableOpsList = fillableOpsList; + } + + /** + * Fills form with data contained in passed map. + * For each map entry if an input with a name coincident with entry key exists + * it is filled with string representation of entry value. + * If an input with such a name is not found the corresponding entry is skipped. + * + * @param data Map containing data to fill form inputs with. + */ + public void fill(Map data) { + data.entrySet().stream() + .map(e -> new AbstractMap.SimpleEntry<>( + findElementByKey(e.getKey()), + Objects.toString(e.getValue(), ""))) + .filter(e -> !isNull(e.getKey())) + /* Convert WebElement to supported Fillable */ + .map(elementEntry -> new AbstractMap.SimpleEntry<>( + fillableOpsList.stream() + .filter(supportedFillable -> supportedFillable.getCanFill().test(elementEntry.getKey())) + .map(supportedFillable -> supportedFillable.getWrapIntoFillable().apply(elementEntry.getKey())) + .findFirst() + .orElse(null), + elementEntry.getValue() + )) + .filter(e -> !isNull(e.getKey())) + .forEach(e -> e.getKey().fill(e.getValue())); + } + + protected WebElement findElementByKey(String key) { + List elements = getWrappedElement().findElements(By.name(key)); + if (elements.isEmpty()) { + return null; + } else { + return elements.get(0); + } + } + + protected static class FillableOps { + private Function wrapIntoFillable; + private Predicate canFill; + + /** + * To add custom {@link Fillable} element support, add entry with + * @param wrapIntoFillable Function to create Fillable from instance of {@link WebElement} + * @param canFill Predicate to test, if instance of {@link WebElement} can be represented by this Fillable + * */ + public FillableOps(Function wrapIntoFillable, Predicate canFill) { + this.wrapIntoFillable = wrapIntoFillable; + this.canFill = canFill; + } + + public Function getWrapIntoFillable() { + return wrapIntoFillable; + } + + public Predicate getCanFill() { + return canFill; + } + } +} diff --git a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Radio.java b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Radio.java index c36326c6..ec496531 100644 --- a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Radio.java +++ b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Radio.java @@ -12,7 +12,7 @@ * @author Alexander Tolmachev starlight@yandex-team.ru * Date: 14.08.12 */ -public class Radio extends TypifiedElement { +public class Radio extends TypifiedElement implements Fillable { /** * Specifies a radio button of a radio button group that will be used to find all other buttons of this group. * @@ -106,4 +106,9 @@ private void selectButton(WebElement button) { button.click(); } } + + @Override + public void fill(String value) { + selectByValue(value); + } } diff --git a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Select.java b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Select.java index 77ea56fb..10ec7a98 100644 --- a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Select.java +++ b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Select.java @@ -14,7 +14,7 @@ * @author Artem Koshelev artkoshelev@yandex-team.ru * @author Alexander Tolmachev starlight@yandex-team.ru */ -public class Select extends TypifiedElement { +public class Select extends TypifiedElement implements Fillable { /** * Specifies wrapped {@link WebElement}. * Performs no checks unlike {@link org.openqa.selenium.support.ui.Select}. All checks are made later @@ -157,4 +157,9 @@ public void deselectByIndex(int index) { public void deselectByVisibleText(String text) { getSelect().deselectByVisibleText(text); } + + @Override + public void fill(String value) { + selectByValue(value); + } } diff --git a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/TextInput.java b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/TextInput.java index dc60eb9a..465b9845 100644 --- a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/TextInput.java +++ b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/TextInput.java @@ -12,7 +12,7 @@ * @author Alexander Tolmachev starlight@yandex-team.ru * Date: 13.08.12 */ -public class TextInput extends TypifiedElement { +public class TextInput extends TypifiedElement implements Fillable { /** * Specifies wrapped {@link WebElement}. * @@ -55,4 +55,9 @@ public String getText() { public String getClearCharSequence() { return StringUtils.repeat(Keys.DELETE.toString() + Keys.BACK_SPACE, getText().length()); } + + @Override + public void fill(String value) { + sendKeys(getClearCharSequence() + value); + } } From 653fc85c19ba33bafd0beb9551afab00732aa70c Mon Sep 17 00:00:00 2001 From: dzmitry Date: Wed, 1 Apr 2020 15:08:55 +0300 Subject: [PATCH 2/3] Add javadoc for Fillable inteface --- .../ru/yandex/qatools/htmlelements/element/Fillable.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Fillable.java b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Fillable.java index 23f0d880..462fc65c 100644 --- a/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Fillable.java +++ b/htmlelements-java/src/main/java/ru/yandex/qatools/htmlelements/element/Fillable.java @@ -1,5 +1,14 @@ package ru.yandex.qatools.htmlelements.element; +import java.util.Map; + +/** + * Implement this interface in blocks, that may be used inside html forms. + * */ public interface Fillable { + /** + * Performs filling of the block. + * Used by {@link FormBase#fill(Map)} to fill all blocks with corresponding map values + * */ void fill(String value); } From 680efd926de49000b1dc124b7e87bffcb0218700 Mon Sep 17 00:00:00 2001 From: dzmitry Date: Wed, 1 Apr 2020 15:10:05 +0300 Subject: [PATCH 3/3] Add test for form with custom html element --- .../qatools/htmlelements/FormFillingTest.java | 35 ++++++-- .../htmlelements/testelements/FormCustom.java | 20 +++++ .../testelements/FormMockSetup.java | 82 +++++++++++++++++++ .../htmlelements/testelements/MockedForm.java | 70 +--------------- .../testelements/MockedFormCustom.java | 67 +++++++++++++++ .../testelements/TextInputCustom.java | 27 ++++++ 6 files changed, 226 insertions(+), 75 deletions(-) create mode 100644 htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/FormCustom.java create mode 100644 htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/FormMockSetup.java create mode 100644 htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/MockedFormCustom.java create mode 100644 htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/TextInputCustom.java diff --git a/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/FormFillingTest.java b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/FormFillingTest.java index 8c6eebc6..4665577a 100644 --- a/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/FormFillingTest.java +++ b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/FormFillingTest.java @@ -3,6 +3,7 @@ import org.junit.Test; import org.openqa.selenium.Keys; import ru.yandex.qatools.htmlelements.testelements.MockedForm; +import ru.yandex.qatools.htmlelements.testelements.MockedFormCustom; import java.util.HashMap; import java.util.Map; @@ -19,9 +20,9 @@ public class FormFillingTest { private static final boolean CHECKBOX_VALUE_TO_SET = true; private final MockedForm form = new MockedForm(); + private final MockedFormCustom formCustom = new MockedFormCustom(); - public void fillForm() { - // Prepare data to fill form with + public Map prepareDefaultData() { Map data = new HashMap<>(); data.put(MockedForm.TEXT_INPUT_NAME, INPUT_TEXT_TO_SEND); data.put(MockedForm.TEXT_INPUT_WITH_TEXT_NAME, INPUT_TEXT_TO_SEND); @@ -31,20 +32,40 @@ public void fillForm() { data.put(MockedForm.TEXT_AREA_NAME, INPUT_TEXT_TO_SEND); data.put(MockedForm.TEXT_AREA_WITH_TEXT_NAME, INPUT_TEXT_TO_SEND); - // Fill form - form.fill(data); + return data; + } + + public Map prepareTextInputCustomData() { + Map data = prepareDefaultData(); + data.put(MockedFormCustom.TEXT_INPUT_CUSTOM, INPUT_TEXT_TO_SEND); + + return data; } @Test public void formFieldsShouldBeFilledCorrectly() { - fillForm(); - verify(form.getTextInput()).sendKeys(INPUT_TEXT_TO_SEND); - verify(form.getTextInputWithText()).sendKeys(INPUT_WITH_TEXT_KEYS_TO_SEND); + form.fill(prepareDefaultData()); verify(form.getCheckBox()).click(); verify(form.getRadioButton()).click(); verify(form.getSelectOption()).click(); verify(form.getTextArea()).sendKeys(INPUT_TEXT_TO_SEND); verify(form.getTextAreaWithText()).sendKeys(INPUT_WITH_TEXT_KEYS_TO_SEND); + verify(form.getTextInput()).sendKeys(INPUT_TEXT_TO_SEND); + verify(form.getTextInputWithText()).sendKeys(INPUT_WITH_TEXT_KEYS_TO_SEND); + } + + @Test + public void customFormFieldsShouldBeFilledCorrectly() { + formCustom.fill(prepareTextInputCustomData()); + verify(formCustom.getTextInputCustomText()).click(); + verify(formCustom.getTextInputCustomText()).sendKeys(INPUT_TEXT_TO_SEND); + verify(formCustom.getTextInput()).sendKeys(INPUT_TEXT_TO_SEND); + verify(formCustom.getTextInputWithText()).sendKeys(INPUT_WITH_TEXT_KEYS_TO_SEND); + verify(formCustom.getCheckBox()).click(); + verify(formCustom.getRadioButton()).click(); + verify(formCustom.getSelectOption()).click(); + verify(formCustom.getTextArea()).sendKeys(INPUT_TEXT_TO_SEND); + verify(formCustom.getTextAreaWithText()).sendKeys(INPUT_WITH_TEXT_KEYS_TO_SEND); } @Test diff --git a/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/FormCustom.java b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/FormCustom.java new file mode 100644 index 00000000..44f1a196 --- /dev/null +++ b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/FormCustom.java @@ -0,0 +1,20 @@ +package ru.yandex.qatools.htmlelements.testelements; + +import org.openqa.selenium.WebElement; +import ru.yandex.qatools.htmlelements.element.Form; + +import java.util.Collections; + +/** + * Represents user's custom form with ability to fill {@link TextInputCustom} elements + * */ +public class FormCustom extends Form { + public FormCustom(WebElement wrappedElement) { + super(wrappedElement, Collections.singletonList( + new FillableOps( + TextInputCustom::new, + (WebElement e) -> "input".equals(e.getTagName()) + && TextInputCustom.TYPE_ATTRIBUTE_VALUE.equals(e.getAttribute("type"))) + )); + } +} diff --git a/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/FormMockSetup.java b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/FormMockSetup.java new file mode 100644 index 00000000..87e347c3 --- /dev/null +++ b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/FormMockSetup.java @@ -0,0 +1,82 @@ +package ru.yandex.qatools.htmlelements.testelements; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.WrapsElement; + +import static java.util.Collections.singletonList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public interface FormMockSetup extends WrapsElement { + String TEXT_INPUT_NAME = "textinput"; + String TEXT_INPUT_WITH_TEXT_NAME = "textinput_with_text"; + String TEXT_INPUT_CUSTOM = "custom-input"; + String CHECKBOX_NAME = "checkbox"; + String SELECT_NAME = "select"; + String RADIO_NAME = "radio"; + String TEXT_AREA_NAME = "textarea"; + String TEXT_AREA_WITH_TEXT_NAME = "textarea_with_text"; + + String RADIO_BUTTON_VALUE = "value"; + String SELECT_OPTION_VALUE = "value"; + + default WebElement mockInputWithNameAndType(String name, String type) { + WebElement element = mock(WebElement.class); + when(element.getTagName()).thenReturn("input"); + when(element.getAttribute("name")).thenReturn(name); + when(element.getAttribute("type")).thenReturn(type); + return element; + } + + default WebElement mockTextInput(String name, String text) { + WebElement textInput = mockInputWithNameAndType(name, "text"); + when(getWrappedElement().findElements(By.name(name))).thenReturn(singletonList(textInput)); + when(textInput.getAttribute("value")).thenReturn(text); + return textInput; + } + + default WebElement mockTextInputCustom(String name, String text) { + WebElement customBlockInForm = mockInputWithNameAndType(name, TextInputCustom.TYPE_ATTRIBUTE_VALUE); + when(getWrappedElement().findElements(By.name(name))).thenReturn(singletonList(customBlockInForm)); + when(customBlockInForm.getAttribute("value")).thenReturn(text); + return customBlockInForm; + } + + default WebElement mockCheckBox() { + WebElement checkBox = mockInputWithNameAndType(CHECKBOX_NAME, "checkbox"); + when(getWrappedElement().findElements(By.name(CHECKBOX_NAME))).thenReturn(singletonList(checkBox)); + when(checkBox.isSelected()).thenReturn(false); + return checkBox; + } + + default WebElement mockRadioButton() { + WebElement radioButton = mockInputWithNameAndType(RADIO_NAME, "radio"); + when(getWrappedElement().findElements(By.name(RADIO_NAME))).thenReturn(singletonList(radioButton)); + when(radioButton.findElements(By.xpath(String.format("self::* | following::input[@type = 'radio' " + + "and @name = '%s'] | preceding::input[@type = 'radio' and @name = '%s']", + RADIO_NAME, RADIO_NAME)))).thenReturn(singletonList(radioButton)); + when(radioButton.getAttribute("value")).thenReturn(RADIO_BUTTON_VALUE); + return radioButton; + } + + default WebElement mockSelectOption() { + WebElement select = mock(WebElement.class); + WebElement selectOption = mock(WebElement.class); + when(select.getTagName()).thenReturn("select"); + when(select.getAttribute("name")).thenReturn(SELECT_NAME); + when(getWrappedElement().findElements(By.name(SELECT_NAME))).thenReturn(singletonList(select)); + when(select.findElements(By.xpath(String.format(".//option[@value = \"%s\"]", SELECT_OPTION_VALUE)))). + thenReturn(singletonList(selectOption)); + return selectOption; + } + + default WebElement mockTextArea(String name, String text) { + WebElement textArea = mock(WebElement.class); + when(getWrappedElement().findElements(By.name(name))).thenReturn(singletonList(textArea)); + when(textArea.getTagName()).thenReturn("textarea"); + when(textArea.getAttribute("name")).thenReturn(name); + when(textArea.getText()).thenReturn(text); + return textArea; + } +} diff --git a/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/MockedForm.java b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/MockedForm.java index 06d1d39f..d4e311ec 100644 --- a/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/MockedForm.java +++ b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/MockedForm.java @@ -1,29 +1,15 @@ package ru.yandex.qatools.htmlelements.testelements; -import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import ru.yandex.qatools.htmlelements.element.Form; -import static java.util.Collections.singletonList; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * @author Alexander Tolmachev starlight@yandex-team.ru * Date: 30.03.13 */ -public class MockedForm extends Form { - public static final String TEXT_INPUT_NAME = "textinput"; - public static final String TEXT_INPUT_WITH_TEXT_NAME = "textinput_with_text"; - public static final String CHECKBOX_NAME = "checkbox"; - public static final String SELECT_NAME = "select"; - public static final String RADIO_NAME = "radio"; - public static final String TEXT_AREA_NAME = "textarea"; - public static final String TEXT_AREA_WITH_TEXT_NAME = "textarea_with_text"; - - public static final String RADIO_BUTTON_VALUE = "value"; - public static final String SELECT_OPTION_VALUE = "value"; - +public class MockedForm extends Form implements FormMockSetup { private final WebElement textInput; private final WebElement textInputWithText; private final WebElement checkBox; @@ -36,7 +22,7 @@ public MockedForm() { this(mock(WebElement.class)); } - private MockedForm(WebElement wrappedElement) { + MockedForm(WebElement wrappedElement) { super(wrappedElement); textInput = mockTextInput(TEXT_INPUT_NAME, ""); textInputWithText = mockTextInput(TEXT_INPUT_WITH_TEXT_NAME, "a"); @@ -47,58 +33,6 @@ private MockedForm(WebElement wrappedElement) { textAreaWithText = mockTextArea(TEXT_AREA_WITH_TEXT_NAME, "a"); } - private WebElement mockInputWithNameAndType(String name, String type) { - WebElement element = mock(WebElement.class); - when(element.getTagName()).thenReturn("input"); - when(element.getAttribute("name")).thenReturn(name); - when(element.getAttribute("type")).thenReturn(type); - return element; - } - - private WebElement mockTextInput(String name, String text) { - WebElement textInput = mockInputWithNameAndType(name, "text"); - when(getWrappedElement().findElements(By.name(name))).thenReturn(singletonList(textInput)); - when(textInput.getAttribute("value")).thenReturn(text); - return textInput; - } - - private WebElement mockCheckBox() { - WebElement checkBox = mockInputWithNameAndType(CHECKBOX_NAME, "checkbox"); - when(getWrappedElement().findElements(By.name(CHECKBOX_NAME))).thenReturn(singletonList(checkBox)); - when(checkBox.isSelected()).thenReturn(false); - return checkBox; - } - - private WebElement mockRadioButton() { - WebElement radioButton = mockInputWithNameAndType(RADIO_NAME, "radio"); - when(getWrappedElement().findElements(By.name(RADIO_NAME))).thenReturn(singletonList(radioButton)); - when(radioButton.findElements(By.xpath(String.format("self::* | following::input[@type = 'radio' " + - "and @name = '%s'] | preceding::input[@type = 'radio' and @name = '%s']", - RADIO_NAME, RADIO_NAME)))).thenReturn(singletonList(radioButton)); - when(radioButton.getAttribute("value")).thenReturn(RADIO_BUTTON_VALUE); - return radioButton; - } - - private WebElement mockSelectOption() { - WebElement select = mock(WebElement.class); - WebElement selectOption = mock(WebElement.class); - when(select.getTagName()).thenReturn("select"); - when(select.getAttribute("name")).thenReturn(SELECT_NAME); - when(getWrappedElement().findElements(By.name(SELECT_NAME))).thenReturn(singletonList(select)); - when(select.findElements(By.xpath(String.format(".//option[@value = \"%s\"]", SELECT_OPTION_VALUE)))). - thenReturn(singletonList(selectOption)); - return selectOption; - } - - private WebElement mockTextArea(String name, String text) { - WebElement textArea = mock(WebElement.class); - when(getWrappedElement().findElements(By.name(name))).thenReturn(singletonList(textArea)); - when(textArea.getTagName()).thenReturn("textarea"); - when(textArea.getAttribute("name")).thenReturn(name); - when(textArea.getText()).thenReturn(text); - return textArea; - } - public WebElement getTextInput() { return textInput; } diff --git a/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/MockedFormCustom.java b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/MockedFormCustom.java new file mode 100644 index 00000000..2ecd9865 --- /dev/null +++ b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/MockedFormCustom.java @@ -0,0 +1,67 @@ +package ru.yandex.qatools.htmlelements.testelements; + +import org.openqa.selenium.WebElement; + +import static org.mockito.Mockito.mock; + +/** + * Based on {@link MockedForm} + */ +public class MockedFormCustom extends FormCustom implements FormMockSetup { + private final WebElement textInput; + private final WebElement textInputWithText; + private final WebElement textInputCustom; + private final WebElement checkBox; + private final WebElement selectOption; + private final WebElement radioButton; + private final WebElement textArea; + private final WebElement textAreaWithText; + + public MockedFormCustom() { + this(mock(WebElement.class)); + } + + private MockedFormCustom(WebElement wrappedElement) { + super(wrappedElement); + textInput = mockTextInput(TEXT_INPUT_NAME, ""); + textInputWithText = mockTextInput(TEXT_INPUT_WITH_TEXT_NAME, "a"); + textInputCustom = mockTextInputCustom(TEXT_INPUT_CUSTOM, "1"); + checkBox = mockCheckBox(); + selectOption = mockSelectOption(); + radioButton = mockRadioButton(); + textArea = mockTextArea(TEXT_AREA_NAME, ""); + textAreaWithText = mockTextArea(TEXT_AREA_WITH_TEXT_NAME, "a"); + } + + public WebElement getTextInput() { + return textInput; + } + + public WebElement getTextInputWithText() { + return textInputWithText; + } + + public WebElement getCheckBox() { + return checkBox; + } + + public WebElement getSelectOption() { + return selectOption; + } + + public WebElement getRadioButton() { + return radioButton; + } + + public WebElement getTextArea() { + return textArea; + } + + public WebElement getTextAreaWithText() { + return textAreaWithText; + } + + public WebElement getTextInputCustomText() { + return textInputCustom; + } +} diff --git a/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/TextInputCustom.java b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/TextInputCustom.java new file mode 100644 index 00000000..0c89dca4 --- /dev/null +++ b/htmlelements-java/src/test/java/ru/yandex/qatools/htmlelements/testelements/TextInputCustom.java @@ -0,0 +1,27 @@ +package ru.yandex.qatools.htmlelements.testelements; + +import org.openqa.selenium.WebElement; +import ru.yandex.qatools.htmlelements.element.Fillable; +import ru.yandex.qatools.htmlelements.element.TextInput; + +/** + * Text input, that for some reasons has custom filling logic. + * */ +public class TextInputCustom extends TextInput implements Fillable { + public static final String TYPE_ATTRIBUTE_VALUE ="its_a_custom_input_block_in_form"; + + /** + * Specifies wrapped {@link WebElement}. + * + * @param wrappedElement {@code WebElement} to wrap. + */ + public TextInputCustom(WebElement wrappedElement) { + super(wrappedElement); + } + + @Override + public void fill(String value) { + getWrappedElement().click(); + getWrappedElement().sendKeys(value); + } +}