diff options
author | Anna Koskinen <Ansku@users.noreply.github.com> | 2018-01-30 11:53:10 +0200 |
---|---|---|
committer | Ilia Motornyi <elmot@vaadin.com> | 2018-01-30 11:53:10 +0200 |
commit | 5b9d0b9175f9ce2f20d728db844b6fd03fea1461 (patch) | |
tree | 8d876b620e6d741fec8c76976f2dd96388561135 /uitest | |
parent | 9999cef04290eb3f025e2fad885905b5c34e62e1 (diff) | |
download | vaadin-framework-5b9d0b9175f9ce2f20d728db844b6fd03fea1461.tar.gz vaadin-framework-5b9d0b9175f9ce2f20d728db844b6fd03fea1461.zip |
Selection handling fix when adding new item to ComboBox. (#10445)
Fixes #10284
Diffstat (limited to 'uitest')
2 files changed, 369 insertions, 0 deletions
diff --git a/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSelectingNewItemValueChange.java b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSelectingNewItemValueChange.java new file mode 100644 index 0000000000..a65e34be63 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSelectingNewItemValueChange.java @@ -0,0 +1,138 @@ +package com.vaadin.tests.components.combobox; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.ContentMode; +import com.vaadin.shared.ui.combobox.ComboBoxClientRpc; +import com.vaadin.ui.Button; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; + +public class ComboBoxSelectingNewItemValueChange extends ComboBoxSelecting { + + private final class CustomComboBox extends ComboBox<String> { + private CustomComboBox(String caption, Collection<String> options) { + super(caption, options); + } + + public ComboBoxClientRpc getComboBoxClientRpc() { + return getRpcProxy(ComboBoxClientRpc.class); + } + } + + CustomComboBox comboBox; + List<String> items = new ArrayList<>(); + int valueChangeEventCount = 0; + int selectionChangeEventCount = 0; + Label valueLabel = new Label(); + Label valueChangeLabel = new Label(null, ContentMode.HTML); + CheckBox delay = new CheckBox("Slow adding process", false); + CheckBox reject = new CheckBox("Reject new values", false); + CheckBox noSelection = new CheckBox("Don't select new values", false); + + @Override + protected void setup(VaadinRequest request) { + initItems(); + comboBox = new CustomComboBox(null, items); + comboBox.setTextInputAllowed(true); + comboBox.setEmptySelectionAllowed(true); + + comboBox.addValueChangeListener(event -> { + String value = event.getValue(); + if (value != null) { + valueLabel.setValue(value); + } else { + valueLabel.setValue("null"); + } + }); + + comboBox.setNewItemHandler(text -> { + if (Boolean.TRUE.equals(delay.getValue())) { + try { + Thread.sleep(2000); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + if (Boolean.TRUE.equals(reject.getValue())) { + valueChangeLabel.setValue("item " + text + " discarded"); + comboBox.getComboBoxClientRpc().newItemNotAdded(text); + } else { + items.add(text); + Collections.sort(items); + valueChangeLabel + .setValue("adding new item... count: " + items.size()); + if (Boolean.TRUE.equals(noSelection.getValue())) { + comboBox.getComboBoxClientRpc().newItemNotAdded(text); + } + comboBox.getDataProvider().refreshAll(); + } + }); + + comboBox.addValueChangeListener(e -> { + ++valueChangeEventCount; + updateLabel(e.isUserOriginated()); + }); + + comboBox.addSelectionListener(e -> { + ++selectionChangeEventCount; + updateLabel(e.isUserOriginated()); + }); + + Button checkButton = new Button("Check ComboBox value", e -> { + Notification.show("selected: " + comboBox.getValue()); + }); + + Button resetButton = new Button("Reset options", e -> { + comboBox.setValue(null); + initItems(); + comboBox.getDataProvider().refreshAll(); + valueLabel.setValue(""); + valueChangeLabel.setValue("Reset"); + valueChangeEventCount = 0; + selectionChangeEventCount = 0; + }); + + valueLabel.setId("value"); + valueChangeLabel.setId("change"); + delay.setId("delay"); + reject.setId("reject"); + noSelection.setId("noSelection"); + resetButton.setId("reset"); + + addComponents(comboBox, valueLabel, valueChangeLabel, checkButton, + resetButton, delay, reject, noSelection); + } + + private void initItems() { + items.clear(); + for (char c = 'a'; c <= 'z'; c++) { + for (int i = 0; i < 100; i++) { + items.add("" + c + i); + } + } + } + + private void updateLabel(boolean userOriginated) { + valueChangeLabel.setValue("Value change count: " + valueChangeEventCount + + "\nSelection change count: " + selectionChangeEventCount + + "\nuser originated: " + userOriginated); + } + + @Override + protected String getTestDescription() { + return "New item should trigger value change when accepted " + + "and restore the field to previous value when rejected."; + } + + @Override + protected Integer getTicketNumber() { + return 10284; + } +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSelectingNewItemValueChangeTest.java b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSelectingNewItemValueChangeTest.java new file mode 100644 index 0000000000..581d546397 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSelectingNewItemValueChangeTest.java @@ -0,0 +1,231 @@ +package com.vaadin.tests.components.combobox; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.CheckBoxElement; +import com.vaadin.testbench.elements.ComboBoxElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.parallel.BrowserUtil; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ComboBoxSelectingNewItemValueChangeTest extends MultiBrowserTest { + + private enum SelectionType { + ENTER, TAB, CLICK_OUT; + } + + private ComboBoxElement comboBoxElement; + private LabelElement valueLabelElement; + private LabelElement changeLabelElement; + private String[] defaultInputs = new String[] { "foo", "bar", "baz", + "fie" }; + private String[] shortInputs = new String[] { "a", "b", "c", "d" }; + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + waitForElementPresent(By.className("v-filterselect")); + comboBoxElement = $(ComboBoxElement.class).first(); + valueLabelElement = $(LabelElement.class).id("value"); + changeLabelElement = $(LabelElement.class).id("change"); + } + + @Test + public void newItemHandlingWithEnter() { + itemHandling(SelectionType.ENTER, defaultInputs); + } + + @Test + public void newItemHandlingWithTab() { + itemHandling(SelectionType.TAB, defaultInputs); + } + + @Test + public void newItemHandlingWithClickingOut() { + itemHandling(SelectionType.CLICK_OUT, defaultInputs); + } + + @Test + public void slowNewItemHandlingWithEnter() { + delay(true); + itemHandling(SelectionType.ENTER, defaultInputs); + } + + @Test + public void slowNewItemHandlingWithTab() { + delay(true); + itemHandling(SelectionType.TAB, defaultInputs); + } + + @Test + public void slowNewItemHandlingWithClickingOut() { + delay(true); + itemHandling(SelectionType.CLICK_OUT, defaultInputs); + } + + @Test + public void shortNewItemHandlingWithEnter() { + itemHandling(SelectionType.ENTER, shortInputs); + } + + @Test + public void shortNewItemHandlingWithTab() { + itemHandling(SelectionType.TAB, shortInputs); + } + + @Test + public void shortNewItemHandlingWithClickingOut() { + itemHandling(SelectionType.CLICK_OUT, shortInputs); + } + + public void itemHandling(SelectionType selectionType, String[] inputs) { + assertThatSelectedValueIs(""); + + // new item, no existing selection + typeInputAndSelect(inputs[0], selectionType); + assertThatSelectedValueIs(inputs[0]); + assertValueChange(1); + + // new item, existing selection + typeInputAndSelect(inputs[1], selectionType); + assertThatSelectedValueIs(inputs[1]); + assertValueChange(2); + + reject(true); + + // item adding blocked, existing selection + typeInputAndSelect(inputs[2], selectionType); + assertThatSelectedValueIs(inputs[1]); + assertRejected(inputs[2]); + + reset(); + + // item adding blocked, no existing selection + typeInputAndSelect(inputs[2], selectionType); + assertThatSelectedValueIs(""); + assertRejected(inputs[2]); + + reject(false); + blockSelection(true); + + // item adding allowed, selection blocked, no existing selection + typeInputAndSelect(inputs[2], selectionType); + assertThatSelectedValueIs(""); + assertItemCount(2601); + + // second attempt selects + typeInputAndSelect(inputs[2], selectionType); + assertThatSelectedValueIs(inputs[2]); + assertValueChange(1); + + // item adding allowed, selection blocked, existing selection + typeInputAndSelect(inputs[3], selectionType); + assertThatSelectedValueIs(inputs[2]); + assertItemCount(2602); + } + + private void typeInputAndSelect(String input, SelectionType selectionType) { + comboBoxElement.clear(); + sendKeysToInput(input); + switch (selectionType) { + case ENTER: + sendKeysToInput(getReturn()); + break; + case TAB: + sendKeysToInput(Keys.TAB); + break; + case CLICK_OUT: + new Actions(getDriver()).moveToElement(comboBoxElement, 10, 10) + .moveByOffset(comboBoxElement.getSize().getWidth(), 0) + .click().perform(); + break; + } + } + + private void sendKeysToInput(CharSequence... keys) { + comboBoxElement.sendKeys(keys); + } + + private Keys getReturn() { + if (BrowserUtil.isPhantomJS(getDesiredCapabilities())) { + return Keys.ENTER; + } else { + return Keys.RETURN; + } + } + + private void assertThatSelectedValueIs(final String value) { + waitUntil(new ExpectedCondition<Boolean>() { + private String actualComboBoxValue; + private String actualLabelValue; + + @Override + public Boolean apply(WebDriver input) { + actualLabelValue = valueLabelElement.getText(); + actualComboBoxValue = comboBoxElement.getText(); + return actualComboBoxValue.equals(value) + && actualLabelValue.equals(value); + } + + @Override + public String toString() { + // Timed out after 10 seconds waiting for ... + return String.format( + "combobox and label value to match '%s' (was: '%s' and '%s')", + value, actualComboBoxValue, actualLabelValue); + } + }); + } + + private void assertValueChange(int count) { + assertTrue(changeLabelElement.getText().equals(String.format( + "Value change count: %s Selection change count: %s user originated: true", + count, count))); + } + + private void assertRejected(String value) { + assertTrue(changeLabelElement.getText() + .equals(String.format("item %s discarded", value))); + } + + private void assertItemCount(int count) { + assertTrue(changeLabelElement.getText() + .equals(String.format("adding new item... count: %s", count))); + } + + private void reject(boolean reject) { + CheckBoxElement checkBox = $(CheckBoxElement.class).id("reject"); + if (reject != checkBox.isChecked()) { + checkBox.click(); + } + } + + private void delay(boolean delay) { + CheckBoxElement checkBox = $(CheckBoxElement.class).id("delay"); + if (delay != checkBox.isChecked()) { + checkBox.click(); + } + } + + private void blockSelection(boolean noSelection) { + CheckBoxElement checkBox = $(CheckBoxElement.class).id("noSelection"); + if (noSelection != checkBox.isChecked()) { + checkBox.click(); + } + } + + private void reset() { + $(ButtonElement.class).id("reset").click(); + } + +} |