From 52236519d9d3ed0cd7de5ed52c6aa19c514e15d6 Mon Sep 17 00:00:00 2001 From: Sara Seppola Date: Thu, 6 Nov 2014 15:46:17 +0200 Subject: [PATCH] TextField's input prompt is now disabled properly (#15144) Change-Id: I9b5d07ec2d8df78c3f120c2a891cc548da787f38 --- .../ui/textfield/TextFieldConnector.java | 15 +- .../textfield/AlternatingTextFields.java | 106 +++++++++ .../textfield/AlternatingTextFieldsTest.java | 212 ++++++++++++++++++ 3 files changed, 329 insertions(+), 4 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFields.java create mode 100644 uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFieldsTest.java diff --git a/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java b/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java index 1a4b64b0a6..cba827bcef 100644 --- a/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java +++ b/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java @@ -87,10 +87,17 @@ public class TextFieldConnector extends AbstractFieldConnector implements * change in the queue (in which case we count more on the server side * value). */ - if (!(uidl - .getBooleanAttribute(TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS) - && getWidget().valueBeforeEdit != null && text - .equals(getWidget().valueBeforeEdit))) { + + boolean valueChanged = !uidl + .getBooleanAttribute(TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS); + // null check is not enough since the value is sometimes null but + // sometimes empty. Fix for #15144 + boolean valueBeforeEditEmpty = getWidget().valueBeforeEdit == null + || getWidget().valueBeforeEdit.isEmpty(); + boolean textDoesNotEqualOldValue = !text + .equals(getWidget().valueBeforeEdit); + + if (valueChanged || valueBeforeEditEmpty || textDoesNotEqualOldValue) { getWidget().updateFieldContent(text); } diff --git a/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFields.java b/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFields.java new file mode 100644 index 0000000000..3eda11d999 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFields.java @@ -0,0 +1,106 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.textfield; + +import com.vaadin.event.FieldEvents.TextChangeEvent; +import com.vaadin.event.FieldEvents.TextChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; + +/** + * When two TextFields repeatedly disable each other, ensure that also their + * input prompts are removed + * + * @since + * @author Vaadin Ltd + */ +public class AlternatingTextFields extends AbstractTestUI { + + public static final String FIRST_TEXTFIELD_INPUT_PROMPT = "Enter first data here"; + public static final String SECOND_TEXTFIELD_INPUT_PROMPT = "Enter second data here"; + + @Override + protected void setup(final VaadinRequest request) { + + VerticalLayout layout = new VerticalLayout(); + layout.setMargin(true); + layout.setSpacing(true); + + final TextField firstTextField = createTextField("First", + FIRST_TEXTFIELD_INPUT_PROMPT); + + final TextField secondTextField = createTextField("Second", + SECOND_TEXTFIELD_INPUT_PROMPT); + + addTextChangeListener(firstTextField, secondTextField); + addTextChangeListener(secondTextField, firstTextField); + + layout.addComponent(firstTextField); + layout.addComponent(secondTextField); + + addComponent(layout); + } + + private static TextField createTextField(String number, String inputPrompt) { + + String caption = " TextField with TextChangeListener"; + + TextField textField = new TextField(number + caption); + textField.setImmediate(true); + textField.setInputPrompt(inputPrompt); + + return textField; + } + + private void addTextChangeListener(TextField currentTextField, + final TextField otherTextField) { + + final String otherDefaultPrompt = otherTextField.getInputPrompt(); + currentTextField.addTextChangeListener(new TextChangeListener() { + + @Override + public void textChange(TextChangeEvent event) { + + String currentText = event.getText(); + + if (currentText.isEmpty() || currentText == null) { + // change other to default + + otherTextField.setInputPrompt(otherDefaultPrompt); + otherTextField.setEnabled(true); + } else { + // change other to empty + + otherTextField.setInputPrompt(null); + otherTextField.setEnabled(false); + } + + } + }); + } + + @Override + protected String getTestDescription() { + return "When two TextFields repeatedly disable each other, ensure that also their input prompts are removed"; + } + + @Override + protected Integer getTicketNumber() { + return 15144; + } +} diff --git a/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFieldsTest.java b/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFieldsTest.java new file mode 100644 index 0000000000..a7ee3fede2 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFieldsTest.java @@ -0,0 +1,212 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.textfield; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class AlternatingTextFieldsTest extends MultiBrowserTest { + + private String RANDOM_INPUT = "Some input here"; + + private List textfields; + + @Test + public void testInputPrompt() { + openTestURL(); + + /* + * Starting positions + */ + + createTextFields(); + + // test that both input prompts exist in the beginning + ensureTextFieldHasInputPrompt(0); + ensureTextFieldHasInputPrompt(1); + + /* + * Write on and empty the first TextField + */ + + // select first input prompt + ensureSelectionClearsPrompt(0); + + // write on the first TextField + ensureWritingDisablesOther(0); + + // empty the text on the first TextField + ensureEmptyingAddsPromptAndEnablesOther(0); + + /* + * Write on and empty the second TextField + */ + + // now select the second input prompt + ensureSelectionClearsPrompt(1); + + // write on the second TextField + ensureWritingDisablesOther(1); + + // empty the text on the second TextField + ensureEmptyingAddsPromptAndEnablesOther(1); + + } + + private void ensureEmptyingAddsPromptAndEnablesOther(int index) { + // remove the text from the TextField + emptyTextField(index); + + // ensure that the TextField really is empty + ensureTextFieldEmpty(index); + + // ensure that the other TextField has again been enabled and has an + // input prompt + if (index == 0) { + ensureTextFieldIsEnabledAndHasInputPrompt(1); + } else { + ensureTextFieldIsEnabledAndHasInputPrompt(0); + } + } + + private void ensureWritingDisablesOther(int index) { + // write some text to the TextField + writeOnTextField(index); + + // ensure that the other TextField is disabled and has no input prompt + if (index == 0) { + ensureTextFieldDisabledAndEmpty(1); + } else { + ensureTextFieldDisabledAndEmpty(0); + } + } + + private void ensureSelectionClearsPrompt(int index) { + // select the TextField + textfields.get(index).click(); + + // check that the the prompt was removed + ensureTextFieldEmpty(index); + } + + /** + * Check that the TextField has no input prompt + * + * @since + * @param index + * The TextField to be inspected + */ + private void ensureTextFieldEmpty(int index) { + + assertEquals("TextField " + index + " was not empty,", "", textfields + .get(index).getValue()); + } + + /** + * Check that the TextField has been enabled and has correct input prompt + * + * @since + * @param index + * the TextField to be inspected + */ + private void ensureTextFieldIsEnabledAndHasInputPrompt(final int index) { + + waitUntil(new ExpectedCondition() { + + @Override + public Boolean apply(WebDriver input) { + return textfields.get(index).isEnabled(); + } + + @Override + public String toString() { + // Timed out after 10 seconds waiting for ... + return "TextField " + index + " to be enabled"; + } + }); + + ensureTextFieldHasInputPrompt(index); + } + + /** + * Check that the TextField has the correct input prompt + * + * @since + * @param index + * The TextField to be inspected + */ + private void ensureTextFieldHasInputPrompt(final int index) { + + if (index == 0) { + assertEquals("Incorrect or missing prompt,", + AlternatingTextFields.FIRST_TEXTFIELD_INPUT_PROMPT, + textfields.get(index).getValue()); + } else { + assertEquals("Incorrect or missing prompt,", + AlternatingTextFields.SECOND_TEXTFIELD_INPUT_PROMPT, + textfields.get(index).getValue()); + } + } + + /** + * Check that the TextField has been disabled and has no input prompt + * + * @since + * @param index + * The TextField to be inspected + */ + private void ensureTextFieldDisabledAndEmpty(final int index) { + + waitUntil(new ExpectedCondition() { + + @Override + public Boolean apply(WebDriver input) { + return !textfields.get(index).isEnabled(); + } + + @Override + public String toString() { + // Timed out after 10 seconds waiting for ... + return "TextField " + index + " to be disabled"; + } + }); + + ensureTextFieldEmpty(index); + } + + private void createTextFields() { + textfields = $(TextFieldElement.class).all(); + } + + private void writeOnTextField(int index) { + textfields.get(index).sendKeys(RANDOM_INPUT); + } + + private void emptyTextField(int index) { + for (int i = 0; i < 15; i++) { + textfields.get(index).sendKeys(Keys.BACK_SPACE); + } + } +} -- 2.39.5