From 65a4fd14bff1043ab62c045d7d176d2097242fb2 Mon Sep 17 00:00:00 2001 From: Anna Miroshnik Date: Tue, 25 Nov 2014 12:19:05 +0300 Subject: Position tooltips in the visible area (#15129). Based on Mika's reverted patch, with additional fix and test for regression "an empty tooltip appears while the application is initializing". Change-Id: I8237fc9340265708a05a7576a5d9e8e374dc1fea --- .../vaadin/tests/components/TooltipPosition.java | 70 +++++++++ .../tests/components/TooltipPositionTest.java | 173 +++++++++++++++++++++ .../tests/components/menubar/MenuTooltipTest.java | 1 + 3 files changed, 244 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/components/TooltipPosition.java create mode 100644 uitest/src/com/vaadin/tests/components/TooltipPositionTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/uitest/src/com/vaadin/tests/components/TooltipPosition.java b/uitest/src/com/vaadin/tests/components/TooltipPosition.java new file mode 100644 index 0000000000..30222722d9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/TooltipPosition.java @@ -0,0 +1,70 @@ +/* + * 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; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.Button; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +/** + * This UI is used for testing that a tooltip is not positioned partially + * outside the browser window when there is enough space to display it. + * + * @author Vaadin Ltd + */ +public class TooltipPosition extends AbstractTestUI { + + public static final int NUMBER_OF_BUTTONS = 5; + + @Override + protected void setup(VaadinRequest request) { + // These tooltip delay settings can be removed once #13854 is resolved. + getTooltipConfiguration().setOpenDelay(0); + getTooltipConfiguration().setQuickOpenDelay(0); + getTooltipConfiguration().setCloseTimeout(1000); + + VerticalLayout layout = new VerticalLayout(); + layout.setSpacing(true); + layout.setHeight(UI.getCurrent().getPage().getBrowserWindowHeight(), + Unit.PIXELS); + addComponent(layout); + for (int i = 0; i < NUMBER_OF_BUTTONS; i++) { + Button button = new Button("Button"); + button.setDescription(generateTooltipText()); + layout.addComponent(button); + } + } + + private String generateTooltipText() { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < 50; i++) { + result.append("This is the line ").append(i) + .append(" of the long tooltip text.
"); + } + return result.toString(); + } + + @Override + public String getTestDescription() { + return "The tooltips of the buttons should not be clipped when there is enough space to display them."; + } + + @Override + public Integer getTicketNumber() { + return 15129; + } +} diff --git a/uitest/src/com/vaadin/tests/components/TooltipPositionTest.java b/uitest/src/com/vaadin/tests/components/TooltipPositionTest.java new file mode 100644 index 0000000000..4106374d64 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/TooltipPositionTest.java @@ -0,0 +1,173 @@ +/* + * 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; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.Point; +import org.openqa.selenium.StaleElementReferenceException; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebDriver.Window; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that the tooltip is positioned so that it fits in the displayed area. + * + * @author Vaadin Ltd + */ +public class TooltipPositionTest extends MultiBrowserTest { + + @Test + public void testRegression_EmptyTooltipShouldNotBeAppearedDuringInitialization() + throws Exception { + openTestURL(); + + waitForElementVisible(By.cssSelector(".v-tooltip")); + WebElement tooltip = driver.findElement(By.cssSelector(".v-tooltip")); + + Assert.assertTrue( + "This init tooltip with text ' ' is present in the DOM and should be entirely outside the browser window", + isOutsideOfWindow(tooltip)); + } + + @Test + public void testTooltipPosition() throws Exception { + openTestURL(); + for (int i = 0; i < TooltipPosition.NUMBER_OF_BUTTONS; i++) { + ButtonElement button = $(ButtonElement.class).get(i); + // Move the mouse to display the tooltip. + Actions actions = new Actions(driver); + actions.moveToElement(button, 10, 10); + actions.build().perform(); + waitUntil(tooltipToBeInsideWindow(By.cssSelector(".v-tooltip"), + driver.manage().window())); + + if (i < TooltipPosition.NUMBER_OF_BUTTONS - 1) { + // Remove the tooltip by moving the mouse. + actions = new Actions(driver); + actions.moveByOffset(300, 0); + actions.build().perform(); + waitUntil(tooltipNotToBeShown(By.cssSelector(".v-tooltip"), + driver.manage().window())); + } + } + } + + /* + * An expectation for checking that the tooltip found by the given locator + * is present in the DOM and entirely inside the browser window. The + * coordinate of the top left corner of the window is supposed to be (0, 0). + */ + private ExpectedCondition tooltipToBeInsideWindow( + final By tooltipLocator, final Window window) { + return new ExpectedCondition() { + + @Override + public Boolean apply(WebDriver input) { + List elements = findElements(tooltipLocator); + if (elements.isEmpty()) { + return false; + } + WebElement element = elements.get(0); + try { + if (!element.isDisplayed()) { + return false; + } + Point topLeft = element.getLocation(); + int xLeft = topLeft.getX(); + int yTop = topLeft.getY(); + if (xLeft < 0 || yTop < 0) { + return false; + } + Dimension elementSize = element.getSize(); + int xRight = xLeft + elementSize.getWidth() - 1; + int yBottom = yTop + elementSize.getHeight() - 1; + Dimension browserSize = window.getSize(); + return xRight < browserSize.getWidth() + && yBottom < browserSize.getHeight(); + } catch (StaleElementReferenceException e) { + return false; + } + } + + @Override + public String toString() { + return "the tooltip to be displayed inside the window"; + } + }; + }; + + /* + * An expectation for checking that the tooltip found by the given locator + * is not shown in the window, even partially. The top left corner of window + * should have coordinates (0, 0). + */ + private ExpectedCondition tooltipNotToBeShown( + final By tooltipLocator, final Window window) { + return new ExpectedCondition() { + + @Override + public Boolean apply(WebDriver input) { + List elements = findElements(tooltipLocator); + if (elements.isEmpty()) { + return true; + } + WebElement tooltip = elements.get(0); + try { + return isOutsideOfWindow(tooltip); + } catch (StaleElementReferenceException e) { + return true; + } + } + + @Override + public String toString() { + return "the tooltip not to be displayed inside the window"; + } + + }; + } + + private boolean isOutsideOfWindow(WebElement tooltip) { + if (!tooltip.isDisplayed()) { + return true; + } + // The tooltip is shown, at least partially, if + // its intervals of both horizontal and vertical coordinates + // overlap those of the window. + Point topLeft = tooltip.getLocation(); + Dimension tooltipSize = tooltip.getSize(); + Dimension windowSize = driver.manage().window().getSize(); + int xLeft = topLeft.getX(); + int yTop = topLeft.getY(); + int xRight = xLeft + tooltipSize.getWidth() - 1; + int yBottom = yTop + tooltipSize.getHeight() - 1; + boolean overlapHorizontally = !(xRight < 0 || xLeft >= windowSize + .getWidth()); + boolean overlapVertically = !(yBottom < 0 || yTop >= windowSize + .getHeight()); + return !(overlapHorizontally && overlapVertically); + } +} \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java index 24025b9f39..091f7be954 100644 --- a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java +++ b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java @@ -49,6 +49,7 @@ public class MenuTooltipTest extends MultiBrowserTest { Coordinates elementCoordinates = getCoordinates($(MenuBarElement.class) .first()); + sleep(1000); Mouse mouse = ((HasInputDevices) getDriver()).getMouse(); -- cgit v1.2.3 From 551c06548831c05e9519836c1e068011b3a95c40 Mon Sep 17 00:00:00 2001 From: Sauli Tähkäpää Date: Tue, 25 Nov 2014 14:41:48 +0200 Subject: Converted SetCurrentPageFirstItemIndex to TB4. (#15286) Change-Id: Iea990c243e083b3302fd1e448402ac3aa3db08ac --- .../table/SetCurrentPageFirstItemIndex.html | 43 --------------- .../table/SetCurrentPageFirstItemIndexTest.java | 63 ++++++++++++++++++++++ 2 files changed, 63 insertions(+), 43 deletions(-) delete mode 100644 uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndex.html create mode 100644 uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndexTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndex.html b/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndex.html deleted file mode 100644 index 904f3b0470..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndex.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - -New Test - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
New Test
openrun/com.vaadin.tests.components.table.SetCurrentPageFirstItemIndex?restartApplication
clickvaadin=runcomvaadintestscomponentstableSetCurrentPageFirstItemIndex::/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]
clickvaadin=runcomvaadintestscomponentstableSetCurrentPageFirstItemIndex::/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]
pause500
assertTextvaadin=runcomvaadintestscomponentstableSetCurrentPageFirstItemIndex::/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]6
- - \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndexTest.java b/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndexTest.java new file mode 100644 index 0000000000..8102f82834 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndexTest.java @@ -0,0 +1,63 @@ +/* + * 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.table; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import junit.framework.Assert; + +import org.junit.Ignore; +import org.junit.Test; +import org.openqa.selenium.NoSuchElementException; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * + * @since + * @author Vaadin Ltd + */ +@Ignore +// Enable after #15286 is fixed. +public class SetCurrentPageFirstItemIndexTest extends MultiBrowserTest { + + @Test + public void currentPageIndexChangesTwice() { + openTestURL(); + + ButtonElement button = $(ButtonElement.class).first(); + button.click(); // change to 20 + button.click(); // change to 5 + + // When failing, the index stays on 20. + assertThatRowIsVisible(5); + } + + private void assertThatRowIsVisible(int index) { + try { + TableElement table = $(TableElement.class).first(); + TestBenchElement cell = table.getCell(index, 0); + + assertThat(cell.getText(), is(Integer.toString(index + 1))); + } catch (NoSuchElementException e) { + Assert.fail(String.format("Can't locate row for index: %s", index)); + } + } + +} -- cgit v1.2.3 From d9829d6636e046b452fdf6f93194c55db9c3997c Mon Sep 17 00:00:00 2001 From: Sergey Budkin Date: Fri, 7 Nov 2014 12:38:05 +0200 Subject: One pixel discrepancy in headers and rows border with minimal width (#15118) Disabled old patch for VTreeTable, which caused the problem. Change-Id: I3fdf6b0890307b27e32ceff4492cb7d0bfc6b680 --- client/src/com/vaadin/client/ui/VScrollTable.java | 3 +- client/src/com/vaadin/client/ui/VTreeTable.java | 2 + .../components/treetable/MinimalWidthColumns.java | 44 ++++++++++++++++++++++ .../treetable/MinimalWidthColumnsTest.java | 31 +++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumns.java create mode 100644 uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumnsTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index 6c241f1033..14e4c658ad 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -5392,6 +5392,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private Map cellToolTips = new HashMap(); private boolean isDragging = false; private String rowStyle = null; + protected boolean applyZeroWidthFix = true; private VScrollTableRow(int rowKey) { this.rowKey = rowKey; @@ -5497,7 +5498,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * definition of zero width table cells. Instead, use 1px * and compensate with a negative margin. */ - if (width == 0) { + if (applyZeroWidthFix && width == 0) { wrapperWidth = 1; wrapperStyle.setMarginRight(-1, Unit.PX); } else { diff --git a/client/src/com/vaadin/client/ui/VTreeTable.java b/client/src/com/vaadin/client/ui/VTreeTable.java index 9b7e9702b2..9e5940a2f2 100644 --- a/client/src/com/vaadin/client/ui/VTreeTable.java +++ b/client/src/com/vaadin/client/ui/VTreeTable.java @@ -155,6 +155,8 @@ public class VTreeTable extends VScrollTable { public VTreeTableRow(UIDL uidl, char[] aligns2) { super(uidl, aligns2); + // this fix causes #15118 and doesn't work for treetable anyway + applyZeroWidthFix = false; } @Override diff --git a/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumns.java b/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumns.java new file mode 100644 index 0000000000..c4679f739b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumns.java @@ -0,0 +1,44 @@ +package com.vaadin.tests.components.treetable; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.TreeTable; + +@Theme("valo") +public class MinimalWidthColumns extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + TreeTable tt = new TreeTable(); + tt.addContainerProperty("Foo", String.class, ""); + tt.addContainerProperty("Bar", String.class, ""); + + Object item1 = tt.addItem(new Object[] { "f", "Bar" }, null); + Object item2 = tt.addItem(new Object[] { "Foo2", "Bar2" }, null); + + tt.setParent(item2, item1); + + tt.setColumnWidth("Foo", 0); + tt.setColumnWidth("Bar", 50); + tt.setWidth("300px"); + addComponent(tt); + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(15118); + } + + @Override + protected String getTestDescription() { + return "There should be no 1px discrepancy between vertical borders in headers and rows"; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumnsTest.java b/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumnsTest.java new file mode 100644 index 0000000000..46c2f397b6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumnsTest.java @@ -0,0 +1,31 @@ +/* + * 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.treetable; + +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class MinimalWidthColumnsTest extends MultiBrowserTest { + + @Test + public void testFor1pxDifference() throws Exception { + openTestURL(); + sleep(500); + compareScreen("onepixdifference"); + } + +} -- cgit v1.2.3 From a0f4c3dfb37b1e742b74a78d8133b1bb4a399052 Mon Sep 17 00:00:00 2001 From: Fabian Lange Date: Thu, 30 Oct 2014 11:58:26 +0100 Subject: Window modalitycurtain will now respect $v-animations-enabled (#15135) Change-Id: I80beea694c2a103aaf1fb479e1de48c515428fbb --- .../tests-valo-disabled-animations/_variables.scss | 3 ++ .../tests-valo-disabled-animations/styles.scss | 6 ++++ .../VAADIN/themes/valo/components/_window.scss | 11 +++---- .../vaadin/tests/themes/valo/ModalWindowTest.java | 34 ++++++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 WebContent/VAADIN/themes/tests-valo-disabled-animations/_variables.scss create mode 100644 WebContent/VAADIN/themes/tests-valo-disabled-animations/styles.scss create mode 100644 uitest/src/com/vaadin/tests/themes/valo/ModalWindowTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/WebContent/VAADIN/themes/tests-valo-disabled-animations/_variables.scss b/WebContent/VAADIN/themes/tests-valo-disabled-animations/_variables.scss new file mode 100644 index 0000000000..d2411c675c --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-disabled-animations/_variables.scss @@ -0,0 +1,3 @@ +$v-animations-enabled: false; + +@import "../valo/valo"; diff --git a/WebContent/VAADIN/themes/tests-valo-disabled-animations/styles.scss b/WebContent/VAADIN/themes/tests-valo-disabled-animations/styles.scss new file mode 100644 index 0000000000..b941c1b3d1 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-disabled-animations/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-disabled-animations { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/valo/components/_window.scss b/WebContent/VAADIN/themes/valo/components/_window.scss index ce7a530c98..23fa5338c2 100644 --- a/WebContent/VAADIN/themes/valo/components/_window.scss +++ b/WebContent/VAADIN/themes/valo/components/_window.scss @@ -89,11 +89,12 @@ $v-window-modality-curtain-background-color: #222 !default; left: 0; @include radial-gradient(circle at 50% 50%, $v-window-modality-curtain-background-color, darken($v-window-modality-curtain-background-color, valo-gradient-opacity()), $fallback: $v-window-modality-curtain-background-color); @include opacity(max(0.2, 0.8 - valo-gradient-opacity()/100%)); - @include valo-animate-in-fade($duration: 400ms, $delay: 100ms); - - .v-op12 & { - // Opera 12 has a shitbreak with the fade-in (flickers) - @include animation(none); + @if $v-animations-enabled { + @include valo-animate-in-fade($duration: 400ms, $delay: 100ms); + .v-op12 & { + // Opera 12 has a shitbreak with the fade-in (flickers) + @include animation(none); + } } } diff --git a/uitest/src/com/vaadin/tests/themes/valo/ModalWindowTest.java b/uitest/src/com/vaadin/tests/themes/valo/ModalWindowTest.java new file mode 100644 index 0000000000..b97ce43ed6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/ModalWindowTest.java @@ -0,0 +1,34 @@ +package com.vaadin.tests.themes.valo; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.ModalWindow; +import com.vaadin.tests.tb3.SingleBrowserTest; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class ModalWindowTest extends SingleBrowserTest { + + @Override + protected Class getUIClass() { + return ModalWindow.class; + } + + @Test + public void modalAnimationsAreDisabled() { + openTestURL("theme=tests-valo-disabled-animations"); + + openModalWindow(); + + WebElement modalityCurtain = findElement(By.className("v-window-modalitycurtain")); + + assertThat(modalityCurtain.getCssValue("-webkit-animation-name"), is("none")); + } + + private void openModalWindow() { + $(ButtonElement.class).get(1).click(); + } +} \ No newline at end of file -- cgit v1.2.3 From 53f87e5bf3014382f0bf9cd7acb18c56709ba1f7 Mon Sep 17 00:00:00 2001 From: Denis Anisimov Date: Sun, 19 Oct 2014 14:54:47 +0300 Subject: Show push version information in debug window (#14904). Change-Id: Id1761abbf2b2dc29b4138520f11ce51bb4d423fc --- .../vaadin/client/ApplicationConfiguration.java | 45 +++++++++ .../vaadin/client/debug/internal/InfoSection.java | 8 ++ server/src/com/vaadin/server/BootstrapHandler.java | 2 + .../com/vaadin/tests/debug/PushVersionInfo.java | 51 +++++++++++ .../vaadin/tests/debug/PushVersionInfoTest.java | 102 +++++++++++++++++++++ 5 files changed, 208 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/debug/PushVersionInfo.java create mode 100644 uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java index 12b1585292..4865e38a4a 100644 --- a/client/src/com/vaadin/client/ApplicationConfiguration.java +++ b/client/src/com/vaadin/client/ApplicationConfiguration.java @@ -172,6 +172,33 @@ public class ApplicationConfiguration implements EntryPoint { return this.getConfig("versionInfo").vaadinVersion; }-*/; + /** + * Gets the version of the Atmosphere framework. + * + * @return a string with the version + * + * @see org.atmosphere.util#getRawVersion() + */ + private native String getAtmosphereVersion() + /*-{ + return this.getConfig("versionInfo").atmosphereVersion; + }-*/; + + /** + * Gets the JS version used in the Atmosphere framework. + * + * @return a string with the version + */ + private native String getAtmosphereJSVersion() + /*-{ + if ($wnd.jQueryVaadin != undefined){ + return $wnd.jQueryVaadin.atmosphere.version; + } + else { + return null; + } + }-*/; + private native String getUIDL() /*-{ return this.getConfig("uidl"); @@ -461,6 +488,24 @@ public class ApplicationConfiguration implements EntryPoint { return getJsoConfiguration(id).getVaadinVersion(); } + /** + * Return Atmosphere version. + * + * @return Atmosphere version. + */ + public String getAtmosphereVersion() { + return getJsoConfiguration(id).getAtmosphereVersion(); + } + + /** + * Return Atmosphere JS version. + * + * @return Atmosphere JS version. + */ + public String getAtmosphereJSVersion() { + return getJsoConfiguration(id).getAtmosphereJSVersion(); + } + public Class getConnectorClassByEncodedTag( int tag) { Class type = classes.get(tag); diff --git a/client/src/com/vaadin/client/debug/internal/InfoSection.java b/client/src/com/vaadin/client/debug/internal/InfoSection.java index a7a84f5f8f..dfb31cdd18 100644 --- a/client/src/com/vaadin/client/debug/internal/InfoSection.java +++ b/client/src/com/vaadin/client/debug/internal/InfoSection.java @@ -193,6 +193,9 @@ public class InfoSection implements Section { ApplicationConfiguration applicationConfiguration) { String clientVersion = Version.getFullVersion(); String servletVersion = applicationConfiguration.getServletVersion(); + String atmosphereVersion = applicationConfiguration + .getAtmosphereVersion(); + String jsVersion = applicationConfiguration.getAtmosphereJSVersion(); String themeVersion; boolean themeOk; @@ -213,6 +216,11 @@ public class InfoSection implements Section { addRow("Server engine version", servletVersion, servletOk ? null : ERROR_STYLE); addRow("Theme version", themeVersion, themeOk ? null : ERROR_STYLE); + if (jsVersion != null) { + addRow("Push server version", atmosphereVersion); + addRow("Push client version", jsVersion + + " (note: does not need to match server version)"); + } } /** diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java index f0666f63fc..c34e986fce 100644 --- a/server/src/com/vaadin/server/BootstrapHandler.java +++ b/server/src/com/vaadin/server/BootstrapHandler.java @@ -469,6 +469,8 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { JsonObject versionInfo = Json.createObject(); versionInfo.put("vaadinVersion", Version.getFullVersion()); + versionInfo.put("atmosphereVersion", + org.atmosphere.util.Version.getRawVersion()); appConfig.put("versionInfo", versionInfo); appConfig.put("widgetset", context.getWidgetsetName()); diff --git a/uitest/src/com/vaadin/tests/debug/PushVersionInfo.java b/uitest/src/com/vaadin/tests/debug/PushVersionInfo.java new file mode 100644 index 0000000000..d8c23a390f --- /dev/null +++ b/uitest/src/com/vaadin/tests/debug/PushVersionInfo.java @@ -0,0 +1,51 @@ +/* + * 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.debug; + +import org.atmosphere.util.Version; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.communication.PushMode; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; + +/** + * Test UI for PUSH version string in debug window. + * + * @author Vaadin Ltd + */ +public class PushVersionInfo extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + if (request.getParameter("enablePush") != null) { + getPushConfiguration().setPushMode(PushMode.AUTOMATIC); + Label label = new Label(Version.getRawVersion()); + label.addStyleName("atmosphere-version"); + addComponent(label); + } + } + + @Override + public String getDescription() { + return "Debug window shows Push version in info Tab."; + } + + @Override + protected Integer getTicketNumber() { + return 14904; + } +} diff --git a/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java b/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java new file mode 100644 index 0000000000..90ea645ab8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java @@ -0,0 +1,102 @@ +/* + * 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.debug; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for PUSH version string in debug window. + * + * @author Vaadin Ltd + */ +@TestCategory("push") +public class PushVersionInfoTest extends MultiBrowserTest { + + @Test + public void testDisabledPush() { + setDebug(true); + openTestURL(); + + selectInfoTab(); + Assert.assertNull("Found push info server string for disabled Push", + getPushRowValue("Push server version")); + Assert.assertNull("Found push info client string for disabled Push", + getPushRowValue("Push client version")); + } + + @Test + public void testEnabledPush() { + setDebug(true); + openTestURL("enablePush=true"); + + selectInfoTab(); + WebElement pushRow = getPushRowValue("Push server version"); + String atmVersion = findElement(By.className("atmosphere-version")) + .getText(); + Assert.assertTrue("Push row doesn't contain Atmosphere version", + pushRow.getText().contains(atmVersion)); + String jsString = getPushRowValue("Push client version").getText(); + Assert.assertTrue( + "Push client version doesn't contain 'vaadin' string", + jsString.contains("vaadin")); + Assert.assertTrue( + "Push client version doesn't contain 'jquery' string", + jsString.contains("jquery")); + } + + private void selectInfoTab() { + if (isElementPresent(By.className("v-ie8"))) { + + int size = findElements(By.className("v-debugwindow-tab")).size(); + for (int i = 0; i < size; i++) { + WebElement tab = findElement(By + .className("v-debugwindow-tab-selected")); + String title = tab.getAttribute("title"); + if (title != null && title.startsWith("General information")) { + break; + } + Actions actions = new Actions(getDriver()); + actions.sendKeys(Keys.TAB); + actions.sendKeys(Keys.SPACE); + actions.build().perform(); + } + } else { + findElements(By.className("v-debugwindow-tab")).get(0).click(); + findElements(By.className("v-debugwindow-tab")).get(1).click(); + } + } + + private WebElement getPushRowValue(String key) { + List rows = findElements(By.className("v-debugwindow-row")); + for (WebElement row : rows) { + WebElement caption = row.findElement(By.className("caption")); + if (caption.getText().startsWith(key)) { + return row.findElement(By.className("value")); + } + } + return null; + } +} -- cgit v1.2.3 From e8868a225504dd90dbecaceb1d6eb9df40116355 Mon Sep 17 00:00:00 2001 From: Sauli Tähkäpää Date: Sun, 23 Nov 2014 14:16:02 +0200 Subject: Fix opacity for disabled links in Valo. (#15253) Change-Id: I865526499a6d55a835758f0194a977c36c10304a --- WebContent/VAADIN/themes/valo/components/_link.scss | 8 ++++++-- uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java | 5 +++++ uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'uitest/src/com/vaadin/tests') diff --git a/WebContent/VAADIN/themes/valo/components/_link.scss b/WebContent/VAADIN/themes/valo/components/_link.scss index b568df1d7b..270de1aace 100644 --- a/WebContent/VAADIN/themes/valo/components/_link.scss +++ b/WebContent/VAADIN/themes/valo/components/_link.scss @@ -20,8 +20,8 @@ $v-link-cursor: pointer !default; /** * * - * @param {string} $primary-stylename (v-link) - - * @param {bool} $include-additional-styles - + * @param {string} $primary-stylename (v-link) - + * @param {bool} $include-additional-styles - * * @group link */ @@ -74,4 +74,8 @@ $v-link-cursor: pointer !default; &:hover { color: lighten($v-link-font-color, 10%); } + + &.v-disabled { + @include opacity($v-disabled-opacity); + } } diff --git a/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java b/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java index e66cd2668b..9ed48896eb 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java @@ -178,6 +178,11 @@ public class ButtonsAndLinks extends VerticalLayout implements View { link.setIcon(testIcon.get()); link.addStyleName("large"); row.addComponent(link); + + link = new Link("Disabled", new ExternalResource("https://vaadin.com")); + link.setIcon(testIcon.get()); + link.setEnabled(false); + row.addComponent(link); } @Override diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java index 92cb837b38..a826d9a8f2 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java @@ -39,7 +39,7 @@ public class ValoThemeUITest extends MultiBrowserTest { public void buttonsLinks() throws Exception { openTestURL("test"); open("Buttons & Links", "Buttons"); - compareScreen("buttonsLinks"); + compareScreen("buttonsLinks_with_disabled"); } @Test -- cgit v1.2.3 From 285b4bc21f85a4570b5f3b45fc4fd120104b4d11 Mon Sep 17 00:00:00 2001 From: Jouni Koivuviita Date: Thu, 4 Dec 2014 15:58:07 +0200 Subject: Fix opacity for disabled checkboxes and option groups. (#15239) Change-Id: I2d09a116d07621053f2fc9524f95e47bf7fc834e --- .../VAADIN/themes/valo/components/_checkbox.scss | 36 ++++++++++------------ .../com/vaadin/tests/themes/valo/CheckBoxes.java | 16 ++++++++++ .../vaadin/tests/themes/valo/ValoThemeUITest.java | 2 +- 3 files changed, 34 insertions(+), 20 deletions(-) (limited to 'uitest/src/com/vaadin/tests') diff --git a/WebContent/VAADIN/themes/valo/components/_checkbox.scss b/WebContent/VAADIN/themes/valo/components/_checkbox.scss index 3c418ec9b7..7283c4cbbf 100644 --- a/WebContent/VAADIN/themes/valo/components/_checkbox.scss +++ b/WebContent/VAADIN/themes/valo/components/_checkbox.scss @@ -99,7 +99,7 @@ } & ~ label:before { - @include valo-button-style($background-color: $background-color, $unit-size: $size, $border-radius: min(round($size/3), $v-border-radius)); + @include valo-button-style($background-color: $background-color, $unit-size: $size, $border-radius: min(round($size/3), $v-border-radius), $states: normal); padding: 0; height: round($size); } @@ -119,24 +119,6 @@ &:checked ~ label:after { color: $selection-color; } - - &[disabled] { - ~ label, - ~ label .v-icon, - ~ .v-icon { - cursor: default; - } - - ~ label:before, - ~ label:after { - @include opacity($v-disabled-opacity); - } - - &:active ~ label:after { - background: transparent; - } - } - } & > .v-icon, @@ -146,4 +128,20 @@ cursor: pointer; } + &.v-disabled { + > label, + > .v-icon { + cursor: default; + @include opacity($v-disabled-opacity); + } + + > label > .v-icon { + cursor: default; + } + + :root & > input:active ~ label:after { + background: transparent; + } + } + } diff --git a/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java b/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java index c7a2610a21..c79447bd86 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java +++ b/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java @@ -79,6 +79,11 @@ public class CheckBoxes extends VerticalLayout implements View { check.addStyleName("large"); row.addComponent(check); + check = new CheckBox("Disabled", true); + check.setEnabled(false); + check.setIcon(testIcon.get()); + row.addComponent(check); + h1 = new Label("Option Groups"); h1.addStyleName("h1"); addComponent(h1); @@ -184,6 +189,17 @@ public class CheckBoxes extends VerticalLayout implements View { options.setItemIcon(two, testIcon.get()); options.setItemIcon("Option Three", testIcon.get()); row.addComponent(options); + + options = new OptionGroup("Disabled items"); + options.setEnabled(false); + options.addItem("Option One"); + options.addItem("Option Two"); + options.addItem("Option Three"); + options.select("Option One"); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon("Option Two", testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); + row.addComponent(options); } @Override diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java index a826d9a8f2..13b0c7144c 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java @@ -85,7 +85,7 @@ public class ValoThemeUITest extends MultiBrowserTest { public void checkboxes() throws Exception { openTestURL("test"); open("Check Boxes & Option Groups", "Check Boxes"); - compareScreen("checkboxes"); + compareScreen("checkboxes_with_disabled"); } @Test -- cgit v1.2.3 From 7e8b23a73a5dd1bef54b8fc5ddc4d3c431c298af Mon Sep 17 00:00:00 2001 From: Anna Miroshnik Date: Mon, 8 Dec 2014 17:25:00 +0300 Subject: Hierarchy change markAsDirty to AbstractComponentContainer (#14227) Change-Id: I7a05ad72dfa3d16d85aa4d0cdd235572ec01e31a --- server/src/com/vaadin/ui/AbsoluteLayout.java | 2 - .../com/vaadin/ui/AbstractComponentContainer.java | 2 + server/src/com/vaadin/ui/AbstractSplitPanel.java | 2 - server/src/com/vaadin/ui/CssLayout.java | 4 -- server/src/com/vaadin/ui/CustomLayout.java | 4 +- server/src/com/vaadin/ui/GridLayout.java | 3 -- server/src/com/vaadin/ui/TabSheet.java | 11 +++-- .../ComponentAttachDetachListenerTest.java | 50 ++++++++++++++++++++++ .../tests/minitutorials/v7a2/WidgetContainer.java | 2 - 9 files changed, 59 insertions(+), 21 deletions(-) (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/ui/AbsoluteLayout.java b/server/src/com/vaadin/ui/AbsoluteLayout.java index afc73f5ecc..af47981db6 100644 --- a/server/src/com/vaadin/ui/AbsoluteLayout.java +++ b/server/src/com/vaadin/ui/AbsoluteLayout.java @@ -153,7 +153,6 @@ public class AbsoluteLayout extends AbstractLayout implements internalRemoveComponent(c); throw e; } - markAsDirty(); } /** @@ -197,7 +196,6 @@ public class AbsoluteLayout extends AbstractLayout implements public void removeComponent(Component c) { internalRemoveComponent(c); super.removeComponent(c); - markAsDirty(); } /** diff --git a/server/src/com/vaadin/ui/AbstractComponentContainer.java b/server/src/com/vaadin/ui/AbstractComponentContainer.java index e70b0fa0ce..1095331602 100644 --- a/server/src/com/vaadin/ui/AbstractComponentContainer.java +++ b/server/src/com/vaadin/ui/AbstractComponentContainer.java @@ -209,6 +209,7 @@ public abstract class AbstractComponentContainer extends AbstractComponent c.setParent(this); fireComponentAttachEvent(c); + markAsDirty(); } /** @@ -223,6 +224,7 @@ public abstract class AbstractComponentContainer extends AbstractComponent if (equals(c.getParent())) { c.setParent(null); fireComponentDetachEvent(c); + markAsDirty(); } } diff --git a/server/src/com/vaadin/ui/AbstractSplitPanel.java b/server/src/com/vaadin/ui/AbstractSplitPanel.java index e9b37f8cff..a78f192fa2 100644 --- a/server/src/com/vaadin/ui/AbstractSplitPanel.java +++ b/server/src/com/vaadin/ui/AbstractSplitPanel.java @@ -214,7 +214,6 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { } else if (c == getSecondComponent()) { getState().secondChild = null; } - markAsDirty(); } /* @@ -256,7 +255,6 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { } else if (oldComponent == getSecondComponent()) { setSecondComponent(newComponent); } - markAsDirty(); } /** diff --git a/server/src/com/vaadin/ui/CssLayout.java b/server/src/com/vaadin/ui/CssLayout.java index e7b63cc87a..350423576f 100644 --- a/server/src/com/vaadin/ui/CssLayout.java +++ b/server/src/com/vaadin/ui/CssLayout.java @@ -118,7 +118,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier { components.add(c); try { super.addComponent(c); - markAsDirty(); } catch (IllegalArgumentException e) { components.remove(c); throw e; @@ -141,7 +140,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier { components.addFirst(c); try { super.addComponent(c); - markAsDirty(); } catch (IllegalArgumentException e) { components.remove(c); throw e; @@ -170,7 +168,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier { components.add(index, c); try { super.addComponent(c); - markAsDirty(); } catch (IllegalArgumentException e) { components.remove(c); throw e; @@ -187,7 +184,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier { public void removeComponent(Component c) { components.remove(c); super.removeComponent(c); - markAsDirty(); } /** diff --git a/server/src/com/vaadin/ui/CustomLayout.java b/server/src/com/vaadin/ui/CustomLayout.java index f4fe7fa66c..a9c266b0b9 100644 --- a/server/src/com/vaadin/ui/CustomLayout.java +++ b/server/src/com/vaadin/ui/CustomLayout.java @@ -144,8 +144,8 @@ public class CustomLayout extends AbstractLayout implements LegacyComponent { } slots.put(location, c); getState().childLocations.put(c, location); - c.setParent(this); - fireComponentAttachEvent(c); + + super.addComponent(c); } /** diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/com/vaadin/ui/GridLayout.java index 0dd16a03e7..96854c5b1b 100644 --- a/server/src/com/vaadin/ui/GridLayout.java +++ b/server/src/com/vaadin/ui/GridLayout.java @@ -255,8 +255,6 @@ public class GridLayout extends AbstractLayout implements cursorY = row1; } } - - markAsDirty(); } /** @@ -390,7 +388,6 @@ public class GridLayout extends AbstractLayout implements getState().childData.remove(component); components.remove(component); - super.removeComponent(component); } diff --git a/server/src/com/vaadin/ui/TabSheet.java b/server/src/com/vaadin/ui/TabSheet.java index d3410464a2..88002104b1 100644 --- a/server/src/com/vaadin/ui/TabSheet.java +++ b/server/src/com/vaadin/ui/TabSheet.java @@ -195,7 +195,6 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, if (component != null && components.contains(component)) { int componentIndex = components.indexOf(component); - super.removeComponent(component); keyMapper.remove(component); components.remove(component); @@ -232,7 +231,6 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, fireSelectedTabChange(); } } - markAsDirty(); } } @@ -394,8 +392,9 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, setSelected(tabComponent); fireSelectedTabChange(); } + super.addComponent(tabComponent); - markAsDirty(); + return tab; } } @@ -967,16 +966,16 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, /** * Gets the icon alt text for the tab. - * + * * @since 7.2 */ public String getIconAlternateText(); /** * Sets the icon alt text for the tab. - * + * * @since 7.2 - * + * * @param iconAltText * the icon to set */ diff --git a/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java b/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java index df515795eb..d8b366ffbc 100644 --- a/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java +++ b/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java @@ -9,6 +9,7 @@ import com.vaadin.ui.AbsoluteLayout.ComponentPosition; import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Component; import com.vaadin.ui.CssLayout; +import com.vaadin.ui.CustomLayout; import com.vaadin.ui.GridLayout; import com.vaadin.ui.GridLayout.Area; import com.vaadin.ui.HasComponents; @@ -25,6 +26,7 @@ public class ComponentAttachDetachListenerTest extends TestCase { private GridLayout gridlayout; private AbsoluteLayout absolutelayout; private CssLayout csslayout; + private CustomLayout customlayout; // General variables private int attachCounter = 0; @@ -143,6 +145,10 @@ public class ComponentAttachDetachListenerTest extends TestCase { csslayout = new CssLayout(); csslayout.addComponentAttachListener(new MyAttachListener()); csslayout.addComponentDetachListener(new MyDetachListener()); + + customlayout = new CustomLayout("
"); + customlayout.addComponentAttachListener(new MyAttachListener()); + customlayout.addComponentDetachListener(new MyDetachListener()); } public void testOrderedLayoutAttachListener() { @@ -342,4 +348,48 @@ public class ComponentAttachDetachListenerTest extends TestCase { // The detached component should not be found in the container assertFalse(foundInContainer); } + + public void testCustomLayoutAttachListener() { + // Reset state variables + resetVariables(); + + // Add component -> Should trigger attach listener + Component comp = new Label(); + customlayout.addComponent(comp, "loc"); + + assertEquals("Attach counter should get incremented", 1, attachCounter); + + assertSame("The attached component should be the label", comp, + attachedComponent); + + assertSame("The attached target should be the layout", customlayout, + attachTarget); + + assertTrue("The attached component should be found in the container", + foundInContainer); + } + + public void testCustomLayoutDetachListener() { + // Add a component to detach + Component comp = new Label(); + customlayout.addComponent(comp); + + // Reset state variables (since they are set by the attach listener) + resetVariables(); + + // Detach the component -> triggers the detach listener + customlayout.removeComponent(comp); + + assertEquals("Detach counter should get incremented", 1, detachCounter); + + assertSame("The detached component should be the label", comp, + detachedComponent); + + assertSame("The detached target should be the layout", customlayout, + detachedTarget); + + assertFalse( + "The detached component should not be found in the container", + foundInContainer); + } } diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java b/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java index 8c14ba8bd7..850fa1044f 100644 --- a/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java +++ b/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java @@ -15,14 +15,12 @@ public class WidgetContainer extends AbstractComponentContainer { public void addComponent(Component c) { children.add(c); super.addComponent(c); - markAsDirty(); } @Override public void removeComponent(Component c) { children.remove(c); super.removeComponent(c); - markAsDirty(); } @Override -- cgit v1.2.3 From 206055708b0a8e1c17a8c63d482a5e202d3ebf6d Mon Sep 17 00:00:00 2001 From: Teemu Pöntelin Date: Mon, 8 Dec 2014 23:21:08 +0200 Subject: Fix issues when using java.sql.Date as DateField range (#15342) Change-Id: I656cc0600f929239605e17ab9cf71dc1ba96582f --- server/src/com/vaadin/ui/DateField.java | 14 +++--- .../components/datefield/DateRangeWithSqlDate.java | 54 ++++++++++++++++++++++ .../datefield/DateRangeWithSqlDateTest.java | 51 ++++++++++++++++++++ 3 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/ui/DateField.java b/server/src/com/vaadin/ui/DateField.java index 030bd5f6c2..d5700c4b65 100644 --- a/server/src/com/vaadin/ui/DateField.java +++ b/server/src/com/vaadin/ui/DateField.java @@ -316,10 +316,10 @@ public class DateField extends AbstractField implements throw new IllegalStateException( "startDate cannot be later than endDate"); } - getState().rangeStart = startDate; - // rangeStart = startDate; - // This has to be done to correct for the resolution - // updateRangeState(); + + // Create a defensive copy against issues when using java.sql.Date (and + // also against mutable Date). + getState().rangeStart = new Date(startDate.getTime()); updateRangeValidator(); } @@ -436,8 +436,10 @@ public class DateField extends AbstractField implements throw new IllegalStateException( "endDate cannot be earlier than startDate"); } - // rangeEnd = endDate; - getState().rangeEnd = endDate; + + // Create a defensive copy against issues when using java.sql.Date (and + // also against mutable Date). + getState().rangeEnd = new Date(endDate.getTime()); updateRangeValidator(); } diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java new file mode 100644 index 0000000000..74d3e85892 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java @@ -0,0 +1,54 @@ +/* + * 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.datefield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.DateField; +import com.vaadin.ui.InlineDateField; + +public class DateRangeWithSqlDate extends AbstractTestUI { + + // 2014-12-01 + private static final java.sql.Date startDate = new java.sql.Date( + 1417467822699L); + + // 2014-12-02 + private static final java.sql.Date endDate = new java.sql.Date( + 1417554763317L); + + @Override + protected void setup(VaadinRequest request) { + DateField df = new InlineDateField(); + df.setRangeStart(startDate); + df.setRangeEnd(endDate); + + df.setValue(startDate); + + addComponent(df); + } + + @Override + protected String getTestDescription() { + return "Test that java.sql.Date can be given to specify date range start and end dates."; + } + + @Override + protected Integer getTicketNumber() { + return 15342; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java new file mode 100644 index 0000000000..2352011585 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java @@ -0,0 +1,51 @@ +/* + * 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.datefield; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateRangeWithSqlDateTest extends MultiBrowserTest { + + @Test + public void testDateRange() { + openTestURL(); + + // Get all cells of the inline datefield. + List cells = driver.findElements(By + .className("v-inline-datefield-calendarpanel-day")); + + // Verify the range is rendered correctly. + assertCell(cells.get(0), "30", true); + assertCell(cells.get(1), "1", false); + assertCell(cells.get(2), "2", false); + assertCell(cells.get(3), "3", true); + } + + private void assertCell(WebElement cell, String text, boolean outsideRange) { + assertEquals(text, cell.getText()); + assertEquals(outsideRange, + cell.getAttribute("class").contains("outside-range")); + } + +} -- cgit v1.2.3 From 153129d52d0167a4d54d7c133155eeec7d407a19 Mon Sep 17 00:00:00 2001 From: Alexey Fansky Date: Wed, 3 Dec 2014 17:07:43 -0800 Subject: Returning all validation errors in the exception cause when submitting a field group (#14742) Following the similar logic as in AbstractField when multiple validation errors occur. Catching all InvalidValueExceptions and putting them together wrapped into the exception. Change-Id: Ied08fd2155412539b28ef94bc74e6c989c62f709 --- .../src/com/vaadin/data/fieldgroup/FieldGroup.java | 86 ++++++++++++++++------ uitest/ivy.xml | 2 + .../tests/fieldgroup/MultipleValidationErrors.java | 72 ++++++++++++++++++ .../fieldgroup/MultipleValidationErrorsTest.java | 37 ++++++++++ .../PersonBeanWithValidationAnnotations.java | 31 ++++++++ 5 files changed, 205 insertions(+), 23 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java create mode 100644 uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java create mode 100644 uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java index 5a4e877554..bcfa8395df 100644 --- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java +++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java @@ -26,6 +26,7 @@ import java.util.List; import com.vaadin.data.Item; import com.vaadin.data.Property; +import com.vaadin.data.Validator; import com.vaadin.data.Validator.InvalidValueException; import com.vaadin.data.util.TransactionalPropertyWrapper; import com.vaadin.ui.AbstractField; @@ -452,6 +453,54 @@ public class FieldGroup implements Serializable { // Not using buffered mode, nothing to do return; } + + startTransactions(); + + try { + firePreCommitEvent(); + + List invalidValueExceptions = commitFields(); + + if(invalidValueExceptions.isEmpty()) { + firePostCommitEvent(); + commitTransactions(); + } else { + throwInvalidValueException(invalidValueExceptions); + } + } catch (Exception e) { + rollbackTransactions(); + + throw new CommitException("Commit failed", e); + } + + } + + private List commitFields() { + List invalidValueExceptions = new ArrayList(); + + for (Field f : fieldToPropertyId.keySet()) { + try { + f.commit(); + } catch (InvalidValueException e) { + invalidValueExceptions.add(e); + } + } + + return invalidValueExceptions; + } + + private void throwInvalidValueException(List invalidValueExceptions) { + if(invalidValueExceptions.size() == 1) { + throw invalidValueExceptions.get(0); + } else { + InvalidValueException[] causes = invalidValueExceptions.toArray( + new InvalidValueException[invalidValueExceptions.size()]); + + throw new InvalidValueException(null, causes); + } + } + + private void startTransactions() throws CommitException { for (Field f : fieldToPropertyId.keySet()) { Property.Transactional property = (Property.Transactional) f .getPropertyDataSource(); @@ -462,33 +511,24 @@ public class FieldGroup implements Serializable { } property.startTransaction(); } - try { - firePreCommitEvent(); - // Commit the field values to the properties - for (Field f : fieldToPropertyId.keySet()) { - f.commit(); - } - firePostCommitEvent(); + } - // Commit the properties - for (Field f : fieldToPropertyId.keySet()) { - ((Property.Transactional) f.getPropertyDataSource()) - .commit(); - } + private void commitTransactions() { + for (Field f : fieldToPropertyId.keySet()) { + ((Property.Transactional) f.getPropertyDataSource()) + .commit(); + } + } - } catch (Exception e) { - for (Field f : fieldToPropertyId.keySet()) { - try { - ((Property.Transactional) f.getPropertyDataSource()) - .rollback(); - } catch (Exception rollbackException) { - // FIXME: What to do ? - } + private void rollbackTransactions() { + for (Field f : fieldToPropertyId.keySet()) { + try { + ((Property.Transactional) f.getPropertyDataSource()) + .rollback(); + } catch (Exception rollbackException) { + // FIXME: What to do ? } - - throw new CommitException("Commit failed", e); } - } /** diff --git a/uitest/ivy.xml b/uitest/ivy.xml index 14c8bc6ce3..78171f9a9c 100644 --- a/uitest/ivy.xml +++ b/uitest/ivy.xml @@ -27,6 +27,8 @@ + diff --git a/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java new file mode 100644 index 0000000000..5110bf6dcf --- /dev/null +++ b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java @@ -0,0 +1,72 @@ +package com.vaadin.tests.fieldgroup; + +import com.vaadin.data.Validator; +import com.vaadin.data.fieldgroup.FieldGroup; +import com.vaadin.data.util.BeanItem; +import com.vaadin.data.validator.BeanValidator; +import com.vaadin.server.AbstractErrorMessage; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextField; +import org.apache.commons.lang.StringEscapeUtils; + +public class MultipleValidationErrors extends AbstractTestUI { + + public static final String FIRST_NAME_NOT_NULL_VALIDATION_MESSAGE = "first name is null"; + public static final String LAST_NAME_NOT_NULL_VALIDATION_MESSAGE = "last name is null"; + public static final String FIRST_NAME_NOT_EMPTY_VALIDATION_MESSAGE = "first name is empty"; + public static final String LAST_NAME_NOT_EMPTY_VALIDATION_MESSAGE = "last name is empty"; + + @Override + protected void setup(VaadinRequest request) { + BeanItem item = new BeanItem( + new PersonBeanWithValidationAnnotations()); + final FieldGroup fieldGroup = new FieldGroup(item); + + bindTextField(item, fieldGroup, "First Name", "firstName"); + bindTextField(item, fieldGroup, "Last Name", "lastName"); + + final Label validationErrors = new Label(); + validationErrors.setId("validationErrors"); + addComponent(validationErrors); + + addButton("Submit", new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + validationErrors.setValue(""); + try { + fieldGroup.commit(); + } catch (FieldGroup.CommitException e) { + if (e.getCause() != null && e.getCause() instanceof Validator.InvalidValueException) { + validationErrors.setValue(StringEscapeUtils.unescapeHtml( + AbstractErrorMessage.getErrorMessageForException(e.getCause()).getFormattedHtmlMessage())); + } + } + + + } + }); + } + + private void bindTextField(BeanItem item, FieldGroup fieldGroup, + String caption, String propertyId) { + TextField textfield = new TextField(caption, item.getItemProperty(propertyId)); + textfield.addValidator(new BeanValidator(PersonBeanWithValidationAnnotations.class, propertyId)); + + fieldGroup.bind(textfield, propertyId); + + addComponent(textfield); + } + + @Override + protected Integer getTicketNumber() { + return 14742; + } + + @Override + protected String getTestDescription() { + return "All validation errors should be included when committing a field group."; + } +} diff --git a/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java new file mode 100644 index 0000000000..175b650be6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java @@ -0,0 +1,37 @@ +package com.vaadin.tests.fieldgroup; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; + +public class MultipleValidationErrorsTest extends MultiBrowserTest { + + private void commitTextFields() { + $(ButtonElement.class).caption("Submit").first().click(); + } + + private void clearTextField(String caption) { + TextFieldElement textField = $(TextFieldElement.class).caption(caption).first(); + textField.clear(); + } + + @Test + public void validationErrorsIncludeBothErrors() { + openTestURL(); + + clearTextField("First Name"); + clearTextField("Last Name"); + + commitTextFields(); + + String validationErrors = $(LabelElement.class).id("validationErrors").getText(); + + assertThat(validationErrors, containsString(MultipleValidationErrors.FIRST_NAME_NOT_EMPTY_VALIDATION_MESSAGE)); + assertThat(validationErrors, containsString(MultipleValidationErrors.LAST_NAME_NOT_EMPTY_VALIDATION_MESSAGE)); + } +} diff --git a/uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java b/uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java new file mode 100644 index 0000000000..5f81ee248b --- /dev/null +++ b/uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java @@ -0,0 +1,31 @@ +package com.vaadin.tests.fieldgroup; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; + +public class PersonBeanWithValidationAnnotations implements Serializable { + @NotNull(message = MultipleValidationErrors.FIRST_NAME_NOT_NULL_VALIDATION_MESSAGE) + @Size(min = 1, message = MultipleValidationErrors.FIRST_NAME_NOT_EMPTY_VALIDATION_MESSAGE) + private String firstName; + + @NotNull(message = MultipleValidationErrors.LAST_NAME_NOT_NULL_VALIDATION_MESSAGE) + @Size(min = 1, message = MultipleValidationErrors.LAST_NAME_NOT_EMPTY_VALIDATION_MESSAGE) + private String lastName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} \ No newline at end of file -- cgit v1.2.3 From 8ce89592362226d6687e1267632a75d85774b67d Mon Sep 17 00:00:00 2001 From: Denis Anisimov Date: Thu, 6 Nov 2014 09:15:15 +0200 Subject: Position calendar popup on the left side if there is no space (#14757). Change-Id: I83836bbf077033712a569c8eff52576b012b4dee --- .../VAADIN/themes/valo/components/_datefield.scss | 2 + .../src/com/vaadin/client/ui/VPopupCalendar.java | 165 ++++++++++++++------- .../datefield/DateFieldPopupPosition.java | 52 +++++++ .../datefield/DateFieldPopupPositionTest.java | 68 +++++++++ .../datefield/DefaultDateFieldPopupPosition.java | 27 ++++ .../DefaultDateFieldPopupPositionTest.java | 43 ++++++ .../datefield/ValoDateFieldPopupPosition.java | 30 ++++ .../datefield/ValoDateFieldPopupPositionTest.java | 43 ++++++ 8 files changed, 376 insertions(+), 54 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPosition.java create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPositionTest.java create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPosition.java create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPositionTest.java create mode 100644 uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPosition.java create mode 100644 uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPositionTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/WebContent/VAADIN/themes/valo/components/_datefield.scss b/WebContent/VAADIN/themes/valo/components/_datefield.scss index 3201288120..6d36ade43a 100644 --- a/WebContent/VAADIN/themes/valo/components/_datefield.scss +++ b/WebContent/VAADIN/themes/valo/components/_datefield.scss @@ -276,6 +276,8 @@ @include valo-overlay-style; margin-top: ceil($v-unit-size/8) !important; + margin-bottom: ceil($v-unit-size/8) !important; + margin-right: ceil($v-unit-size/8) !important; cursor: default; width: auto; diff --git a/client/src/com/vaadin/client/ui/VPopupCalendar.java b/client/src/com/vaadin/client/ui/VPopupCalendar.java index 51b2ee22ec..15302f0784 100644 --- a/client/src/com/vaadin/client/ui/VPopupCalendar.java +++ b/client/src/com/vaadin/client/ui/VPopupCalendar.java @@ -42,6 +42,7 @@ import com.google.gwt.user.client.ui.PopupPanel.PositionCallback; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.BrowserInfo; +import com.vaadin.client.ComputedStyle; import com.vaadin.client.VConsole; import com.vaadin.client.ui.VCalendarPanel.FocusOutListener; import com.vaadin.client.ui.VCalendarPanel.SubmitListener; @@ -372,60 +373,7 @@ public class VPopupCalendar extends VTextualDate implements Field, // clear previous values popup.setWidth(""); popup.setHeight(""); - popup.setPopupPositionAndShow(new PositionCallback() { - @Override - public void setPosition(int offsetWidth, int offsetHeight) { - final int w = offsetWidth; - final int h = offsetHeight; - final int browserWindowWidth = Window.getClientWidth() - + Window.getScrollLeft(); - final int browserWindowHeight = Window.getClientHeight() - + Window.getScrollTop(); - int t = calendarToggle.getAbsoluteTop(); - int l = calendarToggle.getAbsoluteLeft(); - - // Add a little extra space to the right to avoid - // problems with IE7 scrollbars and to make it look - // nicer. - int extraSpace = 30; - - boolean overflowRight = false; - if (l + +w + extraSpace > browserWindowWidth) { - overflowRight = true; - // Part of the popup is outside the browser window - // (to the right) - l = browserWindowWidth - w - extraSpace; - } - - if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) { - // Part of the popup is outside the browser window - // (below) - t = browserWindowHeight - h - - calendarToggle.getOffsetHeight() - 30; - if (!overflowRight) { - // Show to the right of the popup button unless we - // are in the lower right corner of the screen - l += calendarToggle.getOffsetWidth(); - } - } - - popup.setPopupPosition(l, - t + calendarToggle.getOffsetHeight() + 2); - - /* - * We have to wait a while before focusing since the popup - * needs to be opened before we can focus - */ - Timer focusTimer = new Timer() { - @Override - public void run() { - setFocus(true); - } - }; - - focusTimer.schedule(100); - } - }); + popup.setPopupPositionAndShow(new PopupPositionCallback()); } else { VConsole.error("Cannot reopen popup, it is already open!"); } @@ -642,4 +590,113 @@ public class VPopupCalendar extends VTextualDate implements Field, calendar.setRangeEnd(rangeEnd); } + private class PopupPositionCallback implements PositionCallback { + + @Override + public void setPosition(int offsetWidth, int offsetHeight) { + final int width = offsetWidth; + final int height = offsetHeight; + final int browserWindowWidth = Window.getClientWidth() + + Window.getScrollLeft(); + final int windowHeight = Window.getClientHeight() + + Window.getScrollTop(); + int left = calendarToggle.getAbsoluteLeft(); + + // Add a little extra space to the right to avoid + // problems with IE7 scrollbars and to make it look + // nicer. + int extraSpace = 30; + + boolean overflow = left + width + extraSpace > browserWindowWidth; + if (overflow) { + // Part of the popup is outside the browser window + // (to the right) + left = browserWindowWidth - width - extraSpace; + } + + int top = calendarToggle.getAbsoluteTop(); + int extraHeight = 2; + boolean verticallyRepositioned = false; + ComputedStyle style = new ComputedStyle(popup.getElement()); + int[] margins = style.getMargin(); + int desiredPopupBottom = top + height + + calendarToggle.getOffsetHeight() + margins[0] + + margins[2]; + + if (desiredPopupBottom > windowHeight) { + int updatedLeft = left; + left = getLeftPosition(left, width, style, overflow); + + // if position has not been changed then it means there is no + // space to make popup fully visible + if (updatedLeft == left) { + // let's try to show popup on the top of the field + int updatedTop = top - extraHeight - height - margins[0] + - margins[2]; + verticallyRepositioned = updatedTop >= 0; + if (verticallyRepositioned) { + top = updatedTop; + } + } + // Part of the popup is outside the browser window + // (below) + if (!verticallyRepositioned) { + verticallyRepositioned = true; + top = windowHeight - height - extraSpace + extraHeight; + } + } + if (verticallyRepositioned) { + popup.setPopupPosition(left, top); + } else { + popup.setPopupPosition(left, + top + calendarToggle.getOffsetHeight() + extraHeight); + } + doSetFocus(); + } + + private int getLeftPosition(int left, int width, ComputedStyle style, + boolean overflow) { + if (positionRightSide()) { + // Show to the right of the popup button unless we + // are in the lower right corner of the screen + if (overflow) { + return left; + } else { + return left + calendarToggle.getOffsetWidth(); + } + } else { + int[] margins = style.getMargin(); + int desiredLeftPosition = calendarToggle.getAbsoluteLeft() + - width - margins[1] - margins[3]; + if (desiredLeftPosition >= 0) { + return desiredLeftPosition; + } else { + return left; + } + } + } + + private boolean positionRightSide() { + int buttonRightSide = calendarToggle.getAbsoluteLeft() + + calendarToggle.getOffsetWidth(); + int textRightSide = text.getAbsoluteLeft() + text.getOffsetWidth(); + return buttonRightSide >= textRightSide; + } + + private void doSetFocus() { + /* + * We have to wait a while before focusing since the popup needs to + * be opened before we can focus + */ + Timer focusTimer = new Timer() { + @Override + public void run() { + setFocus(true); + } + }; + + focusTimer.schedule(100); + } + } + } diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPosition.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPosition.java new file mode 100644 index 0000000000..4469ad3b1a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPosition.java @@ -0,0 +1,52 @@ +/* + * 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.datefield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.PopupDateField; + +/** + * Test UI for date field Popup calendar. + * + * @author Vaadin Ltd + */ +public abstract class DateFieldPopupPosition extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + HorizontalLayout layout = new HorizontalLayout(); + addComponent(layout); + Label gap = new Label(); + gap.setWidth(250, Unit.PIXELS); + layout.addComponent(gap); + PopupDateField field = new PopupDateField(); + layout.addComponent(field); + } + + @Override + protected Integer getTicketNumber() { + return 14757; + } + + @Override + protected String getTestDescription() { + return "Calendar popup should not placed on the top of text field when " + + "there is no space on bottom."; + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPositionTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPositionTest.java new file mode 100644 index 0000000000..f896519aae --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPositionTest.java @@ -0,0 +1,68 @@ +/* + * 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.datefield; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for date field popup calendar position. + * + * @author Vaadin Ltd + */ +public abstract class DateFieldPopupPositionTest extends MultiBrowserTest { + + @Test + public void testPopupPosition() { + openTestURL(); + + int height = getFieldBottom() + 150; + adjustBrowserWindow(height); + + openPopup(); + + checkPopupPosition(); + } + + protected abstract void checkPopupPosition(); + + protected WebElement getPopup() { + return findElement(By.className("v-datefield-popup")); + } + + private void adjustBrowserWindow(int height) { + Dimension size = getDriver().manage().window().getSize(); + getDriver().manage().window() + .setSize(new Dimension(size.getWidth(), height)); + } + + private int getFieldBottom() { + DateFieldElement dateField = $(DateFieldElement.class).first(); + return dateField.getLocation().getY() + dateField.getSize().getHeight(); + } + + private void openPopup() { + findElement(By.className("v-datefield-button")).click(); + if (!isElementPresent(By.className("v-datefield-popup"))) { + findElement(By.className("v-datefield-button")).click(); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPosition.java b/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPosition.java new file mode 100644 index 0000000000..8e4de77837 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPosition.java @@ -0,0 +1,27 @@ +/* + * 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.datefield; + +/** + * Test UI for date field Popup calendar in default theme. + * + * All UI initialization is defined in super class. + * + * @author Vaadin Ltd + */ +public class DefaultDateFieldPopupPosition extends DateFieldPopupPosition { + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPositionTest.java b/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPositionTest.java new file mode 100644 index 0000000000..61cc876a3f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPositionTest.java @@ -0,0 +1,43 @@ +/* + * 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.datefield; + +import org.junit.Assert; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.DateFieldElement; + +/** + * Test for date field popup calendar position in default theme. + * + * Test method is defined in super class. + * + * @author Vaadin Ltd + */ +public class DefaultDateFieldPopupPositionTest extends + DateFieldPopupPositionTest { + + @Override + protected void checkPopupPosition() { + DateFieldElement field = $(DateFieldElement.class).first(); + int right = field.getLocation().getX() + field.getSize().getWidth(); + WebElement popup = getPopup(); + + Assert.assertTrue("Calendar popup has wrong X coordinate=" + + popup.getLocation().getX() + " , right side of the field is " + + right, popup.getLocation().getX() >= right); + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPosition.java b/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPosition.java new file mode 100644 index 0000000000..59ff6aa9e8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPosition.java @@ -0,0 +1,30 @@ +/* + * 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.datefield; + +import com.vaadin.annotations.Theme; + +/** + * Test UI for date field Popup calendar in Valo theme. + * + * All UI initialization is defined in super class. + * + * @author Vaadin Ltd + */ +@Theme("valo") +public class ValoDateFieldPopupPosition extends DateFieldPopupPosition { + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPositionTest.java b/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPositionTest.java new file mode 100644 index 0000000000..4009b9d991 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPositionTest.java @@ -0,0 +1,43 @@ +/* + * 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.datefield; + +import org.junit.Assert; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.DateFieldElement; + +/** + * Test for date field popup calendar position in Valo theme. + * + * Test method is defined in super class. + * + * @author Vaadin Ltd + */ +public class ValoDateFieldPopupPositionTest extends DateFieldPopupPositionTest { + + @Override + protected void checkPopupPosition() { + DateFieldElement field = $(DateFieldElement.class).first(); + WebElement popup = getPopup(); + int left = field.getLocation().getX(); + int popupRight = popup.getLocation().getX() + + popup.getSize().getWidth(); + + Assert.assertTrue("Calendar popup has wrong X coordinate=" + popupRight + + " , left side of the field is " + left, popupRight <= left); + } +} -- cgit v1.2.3 From e1b335022ec359061e696cf2711327663267e704 Mon Sep 17 00:00:00 2001 From: Sergey Budkin Date: Tue, 25 Nov 2014 19:35:13 +0200 Subject: Long events aren't displayed properly when using Container (#15242) Rewrote event selection. Change-Id: I8f0dd1c5ec736ea14037619b1656a79b7e3532be --- .../calendar/ContainerEventProvider.java | 74 ++++++---------------- .../calendar/BeanItemContainerLongEventTest.java | 55 ++++++++++++++++ .../calendar/BeanItemContainerTestUI.java | 8 +++ 3 files changed, 81 insertions(+), 56 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java index fcaabcc079..2f51b21f7c 100644 --- a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java +++ b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java @@ -249,71 +249,33 @@ public class ContainerEventProvider implements CalendarEditableEventProvider, @Override public List getEvents(Date startDate, Date endDate) { eventCache.clear(); - - int[] rangeIndexes = getFirstAndLastEventIndex(startDate, endDate); - for (int i = rangeIndexes[0]; i <= rangeIndexes[1] - && i < container.size(); i++) { - eventCache.add(getEvent(i)); - } - return Collections.unmodifiableList(eventCache); - } - - /** - * Get the first event for a date - * - * @param date - * The date to search for, NUll returns first event in container - * @return Returns an array where the first item is the start index and the - * second item is the end item - */ - private int[] getFirstAndLastEventIndex(Date start, Date end) { - int startIndex = 0; int size = container.size(); assert size >= 0; - int endIndex = size - 1; - if (start != null) { - /* - * Iterating from the start of the container, if range is in the end - * of the container then this will be slow TODO This could be - * improved by using some sort of divide and conquer algorithm - */ - while (startIndex < size) { - Object id = container.getIdByIndex(startIndex); - Item item = container.getItem(id); - Date d = (Date) item.getItemProperty(startDateProperty) + for (int i = 0; i < size; i++) { + Object id = container.getIdByIndex(i); + Item item = container.getItem(id); + boolean add = true; + if (startDate != null) { + Date eventEnd = (Date) item.getItemProperty(endDateProperty) .getValue(); - if (d.compareTo(start) >= 0) { - break; + if (eventEnd.compareTo(startDate) < 0) { + add = false; } - startIndex++; } - } - - if (end != null) { - /* - * Iterate from the start index until range ends - */ - endIndex = startIndex; - while (endIndex < size - 1) { - Object id = container.getIdByIndex(endIndex); - Item item = container.getItem(id); - Date d = (Date) item.getItemProperty(endDateProperty) - .getValue(); - if (d == null) { - // No end date present, use start date - d = (Date) item.getItemProperty(startDateProperty) - .getValue(); + if (add && endDate != null) { + Date eventStart = (Date) item + .getItemProperty(startDateProperty).getValue(); + if (eventStart.compareTo(endDate) >= 0) { + break; // because container is sorted, all further events + // will be even later } - if (d.compareTo(end) >= 0) { - endIndex--; - break; - } - endIndex++; + } + if (add) { + eventCache.add(getEvent(i)); } } - - return new int[] { startIndex, endIndex }; + return Collections.unmodifiableList(eventCache); } /* diff --git a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java new file mode 100644 index 0000000000..0ec196f266 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java @@ -0,0 +1,55 @@ +/* + * 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.calendar; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests if long event which began before the view period is shown (#15242) + */ +public class BeanItemContainerLongEventTest extends MultiBrowserTest { + + @Override + protected String getDeploymentPath() { + return "/run/BeanItemContainerTestUI?restartApplication"; + } + + @Test + public void testEventDisplayedInWeekView() { + openTestURL(); + WebElement target = driver.findElements( + By.className("v-calendar-week-number")).get(1); + target.click(); + target = driver.findElement(By.className("v-calendar-event")); + Assert.assertEquals("Wrong event name", "Long event", target.getText()); + } + + @Test + public void testEventDisplayedInDayView() { + openTestURL(); + WebElement target = driver.findElements( + By.className("v-calendar-day-number")).get(5); + target.click(); + target = driver.findElement(By.className("v-calendar-event")); + Assert.assertEquals("Wrong event name", "Long event", target.getText()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java index 83fc4a03cb..bda3b34875 100644 --- a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java +++ b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java @@ -17,6 +17,7 @@ package com.vaadin.tests.components.calendar; import java.util.Arrays; import java.util.Date; +import java.util.GregorianCalendar; import com.vaadin.data.fieldgroup.FieldGroup; import com.vaadin.data.fieldgroup.FieldGroup.CommitException; @@ -69,6 +70,13 @@ public class BeanItemContainerTestUI extends UI { table.setVisibleColumns(new Object[] { "caption", "description", "start", "end" }); content.addComponent(table); + + BasicEvent longEvent = new BasicEvent(); + longEvent.setCaption("Long event"); + longEvent.setAllDay(true); + longEvent.setStart(new GregorianCalendar(2000, 1, 3).getTime()); + longEvent.setEnd(new GregorianCalendar(2000, 2, 5).getTime()); + events.addBean(longEvent); } /** -- cgit v1.2.3 From 98d0eec7bb50e4af342358d2aa2ed80fe4564c85 Mon Sep 17 00:00:00 2001 From: Jouni Koivuviita Date: Wed, 10 Dec 2014 10:42:37 +0200 Subject: MenuBar submenus close unexpectedly if use Valo theme (#15255) This fix is for animation-in and animation-out. Fix was done in VMenuBar. VOverlay provides now hide() method with possibility to enable/disable the animations via parameters boolean animateIn, boolean animateOut. By default they are true (not to break animate-in, animate-out for VWindow and VNotification) Change-Id: I49981952c7c18a02edd7fa9e6d247bb18f660207 --- .../VAADIN/themes/valo/components/_menubar.scss | 4 - client/src/com/vaadin/client/ui/VMenuBar.java | 28 +++++-- client/src/com/vaadin/client/ui/VOverlay.java | 91 ++++++++++++++-------- .../menubar/MenuBarSubmenusClosingValo.java | 60 ++++++++++++++ .../menubar/MenuBarSubmenusClosingValoTest.java | 72 +++++++++++++++++ 5 files changed, 212 insertions(+), 43 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValo.java create mode 100644 uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValoTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/WebContent/VAADIN/themes/valo/components/_menubar.scss b/WebContent/VAADIN/themes/valo/components/_menubar.scss index 9075eb7ba8..0f9c61d2ce 100644 --- a/WebContent/VAADIN/themes/valo/components/_menubar.scss +++ b/WebContent/VAADIN/themes/valo/components/_menubar.scss @@ -70,10 +70,6 @@ .#{$primary-stylename}-popup { @include valo-menubar-popup-style($primary-stylename); - - &.#{$primary-stylename}-popup-animate-out { - @include animation(none); - } } diff --git a/client/src/com/vaadin/client/ui/VMenuBar.java b/client/src/com/vaadin/client/ui/VMenuBar.java index 5102e6faea..66160e691d 100644 --- a/client/src/com/vaadin/client/ui/VMenuBar.java +++ b/client/src/com/vaadin/client/ui/VMenuBar.java @@ -476,7 +476,8 @@ public class VMenuBar extends SimpleFocusablePanel implements if (menuVisible && visibleChildMenu != item.getSubMenu() && popup != null) { - popup.hide(); + // #15255 - disable animation-in/out when hide in this case + popup.hide(false, false, false); } if (menuVisible && item.getSubMenu() != null @@ -707,9 +708,22 @@ public class VMenuBar extends SimpleFocusablePanel implements * Recursively hide all child menus */ public void hideChildren() { + hideChildren(true, true); + } + + /** + * + * Recursively hide all child menus + * + * @param animateIn + * enable/disable animate-in animation when hide popup + * @param animateOut + * enable/disable animate-out animation when hide popup + */ + public void hideChildren(boolean animateIn, boolean animateOut) { if (visibleChildMenu != null) { - visibleChildMenu.hideChildren(); - popup.hide(); + visibleChildMenu.hideChildren(animateIn, animateOut); + popup.hide(false, animateIn, animateOut); } } @@ -1326,7 +1340,8 @@ public class VMenuBar extends SimpleFocusablePanel implements VMenuBar root = getParentMenu(); root.getSelected().getSubMenu().setSelected(null); - root.hideChildren(); + // #15255 - disable animate-in/out when hide popup + root.hideChildren(false, false); // Get the root menus items and select the previous one int idx = root.getItems().indexOf(root.getSelected()); @@ -1383,8 +1398,9 @@ public class VMenuBar extends SimpleFocusablePanel implements root = root.getParentMenu(); } - // Hide the submenu - root.hideChildren(); + // Hide the submenu (#15255 - disable animate-in/out when hide + // popup) + root.hideChildren(false, false); // Get the root menus items and select the next one int idx = root.getItems().indexOf(root.getSelected()); diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java index dfd81faf94..9071b6ee47 100644 --- a/client/src/com/vaadin/client/ui/VOverlay.java +++ b/client/src/com/vaadin/client/ui/VOverlay.java @@ -51,7 +51,7 @@ import com.vaadin.client.Util; * temporary float over other components like context menus etc. This is to deal * stacking order correctly with VWindow objects. *

- * + * *

Shadow

*

* The separate shadow element underneath the main overlay element is @@ -62,7 +62,7 @@ import com.vaadin.client.Util; * supports, add -webkit-box-shadow and the standard * box-shadow properties. *

- * + * *

* For IE8, which doesn't support CSS box-shadow, you can use the proprietary * DropShadow filter. It doesn't provide the exact same features as box-shadow, @@ -70,7 +70,7 @@ import com.vaadin.client.Util; * border or a pseudo-element underneath the overlay which mimics a shadow, or * any combination of these. *

- * + * *

* Read more about the DropShadow filter from { * Shadow element style. If an extending class wishes to use a different * style of shadow, it can use setShadowStyle(String) to give the shadow * element a new style name. - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -187,9 +187,9 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * The shadow element for this overlay. - * + * * @deprecated See main JavaDoc for VOverlay - * + * */ @Deprecated private Element shadow; @@ -218,7 +218,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * The HTML snippet that is used to render the actual shadow. In consists of * nine different DIV-elements with the following class names: - * + * *

      *   .v-shadow[-stylename]
      *   ----------------------------------------------
@@ -231,9 +231,9 @@ public class VOverlay extends PopupPanel implements CloseHandler {
      *   | .bottom-left  |  .bottom  |  .bottom-right |
      *   ----------------------------------------------
      * 
- * + * * See default theme 'shadow.css' for implementation example. - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -280,7 +280,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { * Return true if a separate shadow div should be used. Since Vaadin 7.3, * shadows are implemented with CSS box-shadow. Thus, a shadow div is only * used for IE8 by default. - * + * * @deprecated See main JavaDoc for VOverlay * @since 7.3 * @return true to use a shadow div @@ -294,10 +294,10 @@ public class VOverlay extends PopupPanel implements CloseHandler { * Method to control whether DOM elements for shadow are added. With this * method subclasses can control displaying of shadow also after the * constructor. - * + * * @param enabled * true if shadow should be displayed - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -361,7 +361,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * Set the z-index (visual stack position) for this overlay. - * + * * @param zIndex * The new z-index */ @@ -574,12 +574,12 @@ public class VOverlay extends PopupPanel implements CloseHandler { * Sets the shadow style for this overlay. Will override any previous style * for the shadow. The default style name is defined by CLASSNAME_SHADOW. * The given style will be prefixed with CLASSNAME_SHADOW. - * + * * @param style * The new style name for the shadow element. Will be prefixed by * CLASSNAME_SHADOW, e.g. style=='foobar' -> actual style * name=='v-shadow-foobar'. - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -593,7 +593,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { * Extending classes should always call this method after they change the * size of overlay without using normal 'setWidth(String)' and * 'setHeight(String)' methods (if not calling super.setWidth/Height). - * + * */ public void positionOrSizeUpdated() { positionOrSizeUpdated(1.0); @@ -612,7 +612,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { * elements. Can be used to animate the related elements, using the * 'progress' parameter (used to animate the shadow in sync with GWT * PopupPanel's default animation 'PopupPanel.AnimationType.CENTER'). - * + * * @param progress * A value between 0.0 and 1.0, indicating the progress of the * animation (0=start, 1=end). @@ -721,7 +721,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { * Returns true if we should add a shim iframe below the overlay to deal * with zindex issues with PDFs and applets. Can be overriden to disable * shim iframes if they are not needed. - * + * * @return true if a shim iframe should be added, false otherwise */ protected boolean needsShimElement() { @@ -783,13 +783,13 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * Enables or disables sinking the events of the shadow to the same * onBrowserEvent as events to the actual overlay goes. - * + * * Please note, that if you enable this, you can't assume that e.g. * event.getEventTarget returns an element inside the DOM structure of the * overlay - * + * * @param sinkShadowEvents - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -813,7 +813,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * Get owner (Widget that made this VOverlay, not the layout parent) of * VOverlay - * + * * @return Owner (creator) or null if not defined */ public Widget getOwner() { @@ -823,7 +823,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * Set owner (Widget that made this VOverlay, not the layout parent) of * VOverlay - * + * * @param owner * Owner (creator) of VOverlay */ @@ -834,7 +834,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * Get the {@link ApplicationConnection} that this overlay belongs to. If * it's not set, {@link #getOwner()} is used to figure it out. - * + * * @return */ protected ApplicationConnection getApplicationConnection() { @@ -854,7 +854,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * Gets the 'overlay container' element. Tries to find the current * {@link ApplicationConnection} using {@link #getApplicationConnection()}. - * + * * @return the overlay container element for the current * {@link ApplicationConnection} or another element if the current * {@link ApplicationConnection} cannot be determined. @@ -878,7 +878,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { * {@link ApplicationConnection}. Each overlay should be created in a * overlay container element, so that the correct theme and styles can be * applied. - * + * * @param ac * A reference to {@link ApplicationConnection} * @return The overlay container @@ -905,7 +905,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * Set the label of the container element, where tooltip, notification and * dialgs are added to. - * + * * @param applicationConnection * the application connection for which to change the label * @param overlayContainerLabel @@ -938,10 +938,10 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * Gets the visual viewport width, which is useful for e.g iOS where the * view can be zoomed in while keeping the layout viewport intact. - * + * * Falls back to layout viewport; for those browsers/devices the difference * is that the scrollbar with is included (if there is a scrollbar). - * + * * @since 7.0.7 * @return */ @@ -957,10 +957,10 @@ public class VOverlay extends PopupPanel implements CloseHandler { /** * Gets the visual viewport height, which is useful for e.g iOS where the * view can be zoomed in while keeping the layout viewport intact. - * + * * Falls back to layout viewport; for those browsers/devices the difference * is that the scrollbar with is included (if there is a scrollbar). - * + * * @since 7.0.7 * @return */ @@ -1000,10 +1000,33 @@ public class VOverlay extends PopupPanel implements CloseHandler { */ @Override public void hide(final boolean autoClosed) { + hide(autoClosed, true, true); + } + + /** + * + * Hides the popup and detaches it from the page. This has no effect if it + * is not currently showing. Animation-in, animation-out can be + * enable/disabled for different use cases. + * + * @see com.google.gwt.user.client.ui.PopupPanel#hide(boolean) + * + * @param autoClosed + * the value that will be passed to + * {@link CloseHandler#onClose(CloseEvent)} when the popup is + * closed + * @param animateIn + * enable/disable animate-in animation + * @param animateOut + * enable/disable animate-out animation + */ + public void hide(final boolean autoClosed, final boolean animateIn, + final boolean animateOut) { if (BrowserInfo.get().isIE8() || BrowserInfo.get().isIE9()) { super.hide(autoClosed); } else { - if (getStyleName().contains(ADDITIONAL_CLASSNAME_ANIMATE_IN)) { + if (animateIn + && getStyleName().contains(ADDITIONAL_CLASSNAME_ANIMATE_IN)) { AnimationUtil.addAnimationEndListener(getElement(), new AnimationEndListener() { @Override @@ -1029,7 +1052,9 @@ public class VOverlay extends PopupPanel implements CloseHandler { animationName = ""; } - if (animationName.contains(ADDITIONAL_CLASSNAME_ANIMATE_OUT)) { + if (animateOut + && animationName + .contains(ADDITIONAL_CLASSNAME_ANIMATE_OUT)) { // Disable GWT PopupPanel closing animation if used setAnimationEnabled(false); diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValo.java b/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValo.java new file mode 100644 index 0000000000..88d89abbf4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValo.java @@ -0,0 +1,60 @@ +package com.vaadin.tests.components.menubar; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.MenuBar.MenuItem; + +@Theme("valo") +public class MenuBarSubmenusClosingValo extends AbstractTestUI { + + private MenuItem edit; + private MenuItem file; + private MenuItem help; + + @Override + protected String getTestDescription() { + return "Tests that when moving mouse fast over menu items " + + "previous submenu popup closes before new submenu popup opens"; + } + + @Override + protected Integer getTicketNumber() { + return 15255; + } + + @Override + protected void setup(VaadinRequest request) { + // here we increase animation time to 1 second for to do auto testing + // possible + getPage().getStyles().add( + ".valo .v-menubar-popup[class*=\"animate-in\"] {" + + "-webkit-animation: valo-overlay-animate-in 1000ms; " + + "-moz-animation: valo-overlay-animate-in 1000ms; " + + "animation: valo-overlay-animate-in 1000ms;};"); + + getPage().getStyles().add( + ".valo .v-menubar-popup[class*=\"animate-out\"] {" + + "-webkit-animation: valo-animate-out-fade 1000ms; " + + "-moz-animation: valo-animate-out-fade 1000ms; " + + "animation: valo-animate-out-fade 1000ms;};"); + + MenuBar mb = new MenuBar(); + file = mb.addItem("File", null); + file.addItem("File1", null); + file.addItem("File2", null); + file.addItem("File3", null); + edit = mb.addItem("Edit", null); + edit.addItem("Edit1", null); + edit.addItem("Edit2", null); + edit.addItem("Edit3", null); + help = mb.addItem("Help", null); + help.addItem("Help1", null); + help.addItem("Help2", null); + MenuItem helpMenuItem = help.addItem("Help3", null); + helpMenuItem.addItem("SubHelp3", null); + + addComponent(mb); + } +} diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValoTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValoTest.java new file mode 100644 index 0000000000..b7ed88c9ca --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValoTest.java @@ -0,0 +1,72 @@ +/* + * 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.menubar; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.HasInputDevices; +import org.openqa.selenium.interactions.Mouse; +import org.openqa.selenium.internal.Locatable; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.MenuBarElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class MenuBarSubmenusClosingValoTest extends MultiBrowserTest { + + @Test + public void testEnableParentLayoutControlByKeyboard() { + openTestURL(); + + MenuBarElement menu = $(MenuBarElement.class).get(0); + menu.focus(); + menu.sendKeys(Keys.SPACE); + menu.sendKeys(Keys.DOWN); + + waitForElementPresent(By.className("v-menubar-popup")); + + menu.sendKeys(Keys.ARROW_RIGHT); + menu.sendKeys(Keys.ARROW_RIGHT); + + int count = driver.findElements(By.className("v-menubar-popup")).size(); + Assert.assertTrue("The count of open popups should be one", count == 1); + } + + @Test + public void testEnableParentLayoutControlByMouse() { + openTestURL(); + + Mouse mouse = ((HasInputDevices) getDriver()).getMouse(); + + List menuItemList = driver.findElements(By + .className("v-menubar-menuitem")); + + mouse.click(((Locatable) menuItemList.get(0)).getCoordinates()); + waitForElementPresent(By.className("v-menubar-popup")); + + mouse.mouseMove(((Locatable) menuItemList.get(1)).getCoordinates()); + mouse.mouseMove(((Locatable) menuItemList.get(2)).getCoordinates()); + + waitForElementPresent(By.className("v-menubar-popup")); + + int count = driver.findElements(By.className("v-menubar-popup")).size(); + Assert.assertTrue("The count of open popups should be one", count == 1); + } +} -- cgit v1.2.3 From f0d0b207114bc373f643c961546cfe543626057b Mon Sep 17 00:00:00 2001 From: Anna Miroshnik Date: Mon, 17 Nov 2014 17:33:54 +0300 Subject: DateField popup doesn't close when popup button is clicked (#14857) Change-Id: Ieb6ff2f072726fe8707d3cce61569dd623b13ebd --- .../src/com/vaadin/client/ui/VPopupCalendar.java | 51 +++++++++++--- .../datefield/DateFieldPopupClosing.java | 43 ++++++++++++ .../datefield/DateFieldPopupClosingTest.java | 81 ++++++++++++++++++++++ 3 files changed, 165 insertions(+), 10 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/VPopupCalendar.java b/client/src/com/vaadin/client/ui/VPopupCalendar.java index 15302f0784..cf88ceb8d6 100644 --- a/client/src/com/vaadin/client/ui/VPopupCalendar.java +++ b/client/src/com/vaadin/client/ui/VPopupCalendar.java @@ -27,6 +27,10 @@ import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.DomEvent; import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.MouseOutEvent; +import com.google.gwt.event.dom.client.MouseOutHandler; +import com.google.gwt.event.dom.client.MouseOverEvent; +import com.google.gwt.event.dom.client.MouseOverHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.i18n.client.DateTimeFormat; @@ -77,6 +81,15 @@ public class VPopupCalendar extends VTextualDate implements Field, private boolean open = false; + /* + * #14857: If calendarToggle button is clicked when calendar popup is + * already open we should prevent calling openCalendarPanel() in onClick, + * since we don't want to reopen it again right after it closes. + */ + private boolean preventOpenPopupCalendar = false; + private boolean cursorOverCalendarToggleButton = false; + private boolean toggleButtonClosesWithGuarantee = false; + private boolean textFieldEnabled = true; private String captionId; @@ -90,6 +103,21 @@ public class VPopupCalendar extends VTextualDate implements Field, calendarToggle.setText(""); calendarToggle.addClickHandler(this); + + calendarToggle.addDomHandler(new MouseOverHandler() { + @Override + public void onMouseOver(MouseOverEvent event) { + cursorOverCalendarToggleButton = true; + } + }, MouseOverEvent.getType()); + + calendarToggle.addDomHandler(new MouseOutHandler() { + @Override + public void onMouseOut(MouseOutEvent event) { + cursorOverCalendarToggleButton = false; + } + }, MouseOutEvent.getType()); + // -2 instead of -1 to avoid FocusWidget.onAttach to reset it calendarToggle.getElement().setTabIndex(-2); @@ -389,7 +417,10 @@ public class VPopupCalendar extends VTextualDate implements Field, @Override public void onClick(ClickEvent event) { if (event.getSource() == calendarToggle && isEnabled()) { - openCalendarPanel(); + if (!preventOpenPopupCalendar) { + openCalendarPanel(); + } + preventOpenPopupCalendar = false; } } @@ -412,15 +443,14 @@ public class VPopupCalendar extends VTextualDate implements Field, focus(); } - // TODO resolve what the "Sigh." is all about and document it here - // Sigh. - Timer t = new Timer() { - @Override - public void run() { - open = false; - } - }; - t.schedule(100); + open = false; + + if (cursorOverCalendarToggleButton + && !toggleButtonClosesWithGuarantee) { + preventOpenPopupCalendar = true; + } + + toggleButtonClosesWithGuarantee = false; } } @@ -520,6 +550,7 @@ public class VPopupCalendar extends VTextualDate implements Field, */ public void closeCalendarPanel() { if (open) { + toggleButtonClosesWithGuarantee = true; popup.hide(true); } } diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java new file mode 100644 index 0000000000..60508a30d4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java @@ -0,0 +1,43 @@ +/* + * 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.datefield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.DateField; + +public class DateFieldPopupClosing extends AbstractTestUI { + + static final String DATEFIELD_ID = "datefield"; + + @Override + protected void setup(VaadinRequest request) { + final DateField df = new DateField(); + df.setId(DATEFIELD_ID); + addComponent(df); + } + + @Override + protected String getTestDescription() { + return "DateField popup should be closed when click on popup button"; + } + + @Override + protected Integer getTicketNumber() { + return 14857; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java new file mode 100644 index 0000000000..9fd6fe82e2 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java @@ -0,0 +1,81 @@ +package com.vaadin.tests.components.datefield; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.support.ui.ExpectedCondition; +import org.openqa.selenium.support.ui.ExpectedConditions; + +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateFieldPopupClosingTest extends MultiBrowserTest { + + @Test + public void testDateFieldPopupClosingLongClick() + throws InterruptedException, IOException { + openTestURL(); + + fastClickDateDatePickerButton(); + + assertThatPopupIsVisible(); + + longClickDateDatePickerButton(); + + assertThatPopupIsInvisible(); + } + + private void assertThatPopupIsVisible() { + waitUntil(ExpectedConditions.visibilityOfElementLocated(By + .className("v-datefield-popup"))); + } + + private void assertThatPopupIsInvisible() { + // ExpectedConditions.invisibilityOfElementLocated doesn't work + // with PhantomJS when running with a hub: + // https://code.google.com/p/selenium/issues/detail?id=5000 + // so we need to make our own. + + waitUntil(new ExpectedCondition() { + @Override + public Boolean apply(WebDriver input) { + try { + return !(findElement(By.className("v-datefield-popup")) + .isDisplayed()); + } catch (Exception e) { + return true; + } + } + + @Override + public String toString() { + // Timed out after 10 seconds waiting for ... + return "popup to not be visible"; + } + }); + } + + private void longClickDateDatePickerButton() { + WebElement button = getToggleButton(); + + new Actions(getDriver()).clickAndHold(button).perform(); + assertThatPopupIsInvisible(); + + new Actions(getDriver()).release(button).perform(); + } + + private WebElement getToggleButton() { + DateFieldElement dateField = $(DateFieldElement.class).first(); + + return dateField.findElement(By.tagName("button")); + } + + private void fastClickDateDatePickerButton() { + getToggleButton().click(); + } + +} \ No newline at end of file -- cgit v1.2.3 From db14140a6acf6db78ca86d77d8bcbf1db0d36600 Mon Sep 17 00:00:00 2001 From: Sergey Budkin Date: Thu, 13 Nov 2014 16:47:15 +0200 Subject: Accordion causes SEVERE error in browser console (#15182) Refactored to remove invisible widgets from DOM. Change-Id: I94d0ba37f4a75d71df88fbb0b1767ae60f39432d --- client/src/com/vaadin/client/ui/VAccordion.java | 38 ++++++++++++---------- .../client/ui/accordion/AccordionConnector.java | 5 +-- .../accordion/AccordionRemoveTabTest.java | 13 ++++++++ 3 files changed, 37 insertions(+), 19 deletions(-) (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/VAccordion.java b/client/src/com/vaadin/client/ui/VAccordion.java index 3e89958a98..ff77a8cb91 100644 --- a/client/src/com/vaadin/client/ui/VAccordion.java +++ b/client/src/com/vaadin/client/ui/VAccordion.java @@ -159,6 +159,8 @@ public class VAccordion extends VTabsheetBase { */ public class StackItem extends ComplexPanel implements ClickHandler { + private Widget widget; + public void setHeight(int height) { if (height == -1) { super.setHeight(""); @@ -171,10 +173,7 @@ public class VAccordion extends VTabsheetBase { } public Widget getComponent() { - if (getWidgetCount() < 2) { - return null; - } - return getWidget(1); + return widget; } @Override @@ -268,24 +267,26 @@ public class VAccordion extends VTabsheetBase { } public Widget getChildWidget() { - if (getWidgetCount() > 1) { - return getWidget(1); - } else { - return null; - } + return widget; } public void replaceWidget(Widget newWidget) { - if (getWidgetCount() > 1) { - Widget oldWidget = getWidget(1); - remove(oldWidget); - widgets.remove(oldWidget); + if (widget != null) { + widgets.remove(widget); + if (open) { + remove(widget); + } } - add(newWidget, content); + widget = newWidget; widgets.add(newWidget); + if (open) { + add(widget, content); + } + } public void open() { + add(widget, content); open = true; content.getStyle().setTop(getCaptionHeight(), Unit.PX); content.getStyle().setLeft(0, Unit.PX); @@ -298,6 +299,9 @@ public class VAccordion extends VTabsheetBase { } public void close() { + if (widget != null) { + remove(widget); + } content.getStyle().setVisibility(Visibility.HIDDEN); content.getStyle().setTop(-100000, Unit.PX); content.getStyle().setLeft(-100000, Unit.PX); @@ -322,10 +326,10 @@ public class VAccordion extends VTabsheetBase { * new content */ public void setContent(Widget newWidget) { - if (getChildWidget() == null) { - add(newWidget, content); + if (widget == null) { + widget = newWidget; widgets.add(newWidget); - } else if (getChildWidget() != newWidget) { + } else if (widget != newWidget) { replaceWidget(newWidget); } if (isOpen() && isDynamicHeight()) { diff --git a/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java b/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java index c0caded759..72aa2dbdfd 100644 --- a/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java +++ b/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java @@ -50,12 +50,13 @@ public class AccordionConnector extends TabsheetBaseConnector implements StackItem selectedItem = getWidget().getStackItem( getWidget().selectedItemIndex); - getWidget().open(getWidget().selectedItemIndex); - ComponentConnector contentConnector = getChildComponents().get(0); if (contentConnector != null) { selectedItem.setContent(contentConnector.getWidget()); } + + getWidget().open(getWidget().selectedItemIndex); + } else if (getWidget().getOpenStackItem() != null) { getWidget().close(getWidget().getOpenStackItem()); } diff --git a/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java b/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java index f5651e0ada..1047c070c8 100644 --- a/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java +++ b/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java @@ -44,6 +44,19 @@ public class AccordionRemoveTabTest extends MultiBrowserTest { checkFirstItemHeight("On third tab"); } + @Test + public void testConsoleErrorOnSwitch() { + setDebug(true); + openTestURL(); + WebElement firstItem = driver.findElement(By + .className("v-accordion-item-first")); + WebElement caption = firstItem.findElement(By + .className("v-accordion-item-caption")); + caption.click(); + Assert.assertEquals("Errors present in console", 0, + findElements(By.className("SEVERE")).size()); + } + private void checkFirstItemHeight(String text) { WebElement firstItem = driver.findElement(By .className("v-accordion-item-first")); -- cgit v1.2.3 From 52236519d9d3ed0cd7de5ed52c6aa19c514e15d6 Mon Sep 17 00:00:00 2001 From: Sara Seppola Date: Thu, 6 Nov 2014 15:46:17 +0200 Subject: TextField's input prompt is now disabled properly (#15144) Change-Id: I9b5d07ec2d8df78c3f120c2a891cc548da787f38 --- .../client/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 (limited to 'uitest/src/com/vaadin/tests') 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); + } + } +} -- cgit v1.2.3 From 67b20a12d6016654663eb2726c2a095a6935593a Mon Sep 17 00:00:00 2001 From: Sauli Tähkäpää Date: Wed, 10 Dec 2014 12:38:45 +0200 Subject: Set locale explicitly in DateRangeWithSql. (#15342) Change-Id: I5f73ac5e8bc6be93fa0f9b9089b1584fb35f4a76 --- .../com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'uitest/src/com/vaadin/tests') diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java index 74d3e85892..d3bc4267ec 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java +++ b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java @@ -20,6 +20,8 @@ import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.DateField; import com.vaadin.ui.InlineDateField; +import java.util.Locale; + public class DateRangeWithSqlDate extends AbstractTestUI { // 2014-12-01 @@ -33,6 +35,7 @@ public class DateRangeWithSqlDate extends AbstractTestUI { @Override protected void setup(VaadinRequest request) { DateField df = new InlineDateField(); + df.setLocale(Locale.US); df.setRangeStart(startDate); df.setRangeEnd(endDate); -- cgit v1.2.3 From da91036c92d8088d02471bb939b21eb228638d8f Mon Sep 17 00:00:00 2001 From: Denis Anisimov Date: Sun, 14 Sep 2014 12:49:23 +0300 Subject: Set explicit calculated size for drag image element (#14617). Change-Id: I6bfcd0a5ad78bd79aad2fa2357a7e33a00b3c33d --- client/src/com/vaadin/client/ui/dd/VDragEvent.java | 5 ++ .../DragAndDropRelativeWidth.java | 58 ++++++++++++++++++++++ .../DragAndDropRelativeWidthTest.java | 57 +++++++++++++++++++++ .../draganddropwrapper/DragStartModesTest.java | 2 +- 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidth.java create mode 100644 uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidthTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/dd/VDragEvent.java b/client/src/com/vaadin/client/ui/dd/VDragEvent.java index 6291a38e42..45f89bdb87 100644 --- a/client/src/com/vaadin/client/ui/dd/VDragEvent.java +++ b/client/src/com/vaadin/client/ui/dd/VDragEvent.java @@ -244,6 +244,11 @@ public class VDragEvent { public void createDragImage(com.google.gwt.user.client.Element element, boolean alignImageToEvent) { Element cloneNode = (Element) element.cloneNode(true); + + // Set size explicitly for cloned node to avoid stretching #14617. + cloneNode.getStyle().setWidth(element.getOffsetWidth(), Unit.PX); + cloneNode.getStyle().setHeight(element.getOffsetHeight(), Unit.PX); + syncContent(element, cloneNode); if (BrowserInfo.get().isIE()) { if (cloneNode.getTagName().toLowerCase().equals("tr")) { diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidth.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidth.java new file mode 100644 index 0000000000..90ec704a8c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidth.java @@ -0,0 +1,58 @@ +/* + * 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.draganddropwrapper; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.DragStartMode; +import com.vaadin.ui.Label; + +/** + * Test UI for DnD image element size + * + * @author Vaadin Ltd + */ +public class DragAndDropRelativeWidth extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + CssLayout layout = new CssLayout(); + layout.setWidth(300, Unit.PIXELS); + + Label label = new Label("drag source"); + label.addStyleName("drag-source"); + label.setWidth(100, Unit.PERCENTAGE); + DragAndDropWrapper wrapper = new DragAndDropWrapper(label); + wrapper.setWidth(100, Unit.PERCENTAGE); + wrapper.setDragStartMode(DragStartMode.COMPONENT); + + layout.addComponent(wrapper); + addComponent(layout); + } + + @Override + protected String getTestDescription() { + return "Set explicit size for drag image element using calclulated size from the source"; + } + + @Override + protected Integer getTicketNumber() { + return 14617; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidthTest.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidthTest.java new file mode 100644 index 0000000000..9cb7a63046 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidthTest.java @@ -0,0 +1,57 @@ +/* + * 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.draganddropwrapper; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test to check size of drag image element. + * + * @author Vaadin Ltd + */ +public class DragAndDropRelativeWidthTest extends MultiBrowserTest { + + @Test + public void testDragImageElementSize() { + openTestURL(); + + WebElement label = getDriver().findElement(By.className("drag-source")); + Dimension size = label.getSize(); + int height = size.getHeight(); + int width = size.getWidth(); + Actions actions = new Actions(getDriver()); + actions.moveToElement(label); + actions.clickAndHold(); + actions.moveByOffset(100, 100); + actions.build().perform(); + + WebElement dragImage = getDriver().findElement( + By.className("v-drag-element")); + + Assert.assertEquals("Drag image element height is unexpected", height, + dragImage.getSize().getHeight()); + Assert.assertEquals("Drag image element width is unexpected", width, + dragImage.getSize().getWidth()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java index ba27ee293e..4e60b43ea2 100644 --- a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java @@ -40,7 +40,7 @@ public class DragStartModesTest extends MultiBrowserTest { new Actions(driver).moveToElement(draggable, 10, 10).clickAndHold() .moveByOffset(5, 0).perform(); new Actions(driver).moveToElement(dropTarget, 12, 10).perform(); - compareScreen("dragMode" + dragMode); + compareScreen("dragImageMode" + dragMode); new Actions(driver).release().perform(); } -- cgit v1.2.3 From 60f0bdaa6ef00f14664ead0d0b4aefb18343c8a7 Mon Sep 17 00:00:00 2001 From: Denis Anisimov Date: Fri, 31 Oct 2014 20:33:39 +0200 Subject: Horizontal split panel height shouldn't ignore second component (#15149) Change-Id: Ie925757167b6d8521707b6d5515157eca85f9dba --- .../com/vaadin/client/ui/VAbstractSplitPanel.java | 194 +++++++++++---------- .../splitpanel/HorizontalSplitPanelHeight.java | 87 +++++++++ .../splitpanel/HorizontalSplitPanelHeightTest.java | 71 ++++++++ 3 files changed, 261 insertions(+), 91 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeight.java create mode 100644 uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeightTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/VAbstractSplitPanel.java b/client/src/com/vaadin/client/ui/VAbstractSplitPanel.java index 6ee88d51dd..9d32355b70 100644 --- a/client/src/com/vaadin/client/ui/VAbstractSplitPanel.java +++ b/client/src/com/vaadin/client/ui/VAbstractSplitPanel.java @@ -199,6 +199,7 @@ public class VAbstractSplitPanel extends ComplexPanel { private void setOrientation(Orientation orientation) { this.orientation = orientation; + if (orientation == Orientation.HORIZONTAL) { splitter.getStyle().setHeight(100, Unit.PCT); splitter.getStyle().setTop(0, Unit.PX); @@ -393,107 +394,118 @@ public class VAbstractSplitPanel extends ComplexPanel { return; } - int wholeSize; - int pixelPosition; - switch (orientation) { case HORIZONTAL: - wholeSize = DOM.getElementPropertyInt(wrapper, "clientWidth"); - pixelPosition = DOM.getElementPropertyInt(splitter, "offsetLeft"); - - // reposition splitter in case it is out of box - if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize) - || (positionReversed && pixelPosition < 0)) { - pixelPosition = wholeSize - getSplitterSize(); - if (pixelPosition < 0) { - pixelPosition = 0; - } - // Move splitter within bounds, but don't remember the new value - setSplitPosition(pixelPosition + "px", false); - return; - } + horizontalOrientationUpdateSizes(); + break; + case VERTICAL: + verticalOrientationUpdateSizes(); + break; + } + } - firstContainer.getStyle().setWidth(pixelPosition, Unit.PX); - int secondContainerWidth = (wholeSize - pixelPosition - getSplitterSize()); - if (secondContainerWidth < 0) { - secondContainerWidth = 0; - } - secondContainer.getStyle().setWidth(secondContainerWidth, Unit.PX); - secondContainer.getStyle().setLeft( - pixelPosition + getSplitterSize(), Unit.PX); - - LayoutManager layoutManager = LayoutManager.get(client); - ConnectorMap connectorMap = ConnectorMap.get(client); - if (firstChild != null) { - ComponentConnector connector = connectorMap - .getConnector(firstChild); - if (connector.isRelativeWidth()) { - layoutManager.reportWidthAssignedToRelative(connector, - pixelPosition); - } else { - layoutManager.setNeedsMeasure(connector); - } + private void verticalOrientationUpdateSizes() { + int wholeSize = DOM.getElementPropertyInt(wrapper, "clientHeight"); + int pixelPosition = DOM.getElementPropertyInt(splitter, "offsetTop"); + + // reposition splitter in case it is out of box + if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize) + || (positionReversed && pixelPosition < 0)) { + pixelPosition = wholeSize - getSplitterSize(); + if (pixelPosition < 0) { + pixelPosition = 0; } - if (secondChild != null) { - ComponentConnector connector = connectorMap - .getConnector(secondChild); - if (connector.isRelativeWidth()) { - layoutManager.reportWidthAssignedToRelative(connector, - secondContainerWidth); - } else { - layoutManager.setNeedsMeasure(connector); - } + // Move splitter within bounds, but don't remember the new value + setSplitPosition(pixelPosition + "px", false); + return; + } + + firstContainer.getStyle().setHeight(pixelPosition, Unit.PX); + int secondContainerHeight = (wholeSize - pixelPosition - getSplitterSize()); + if (secondContainerHeight < 0) { + secondContainerHeight = 0; + } + secondContainer.getStyle().setHeight(secondContainerHeight, Unit.PX); + secondContainer.getStyle().setTop(pixelPosition + getSplitterSize(), + Unit.PX); + + LayoutManager layoutManager = LayoutManager.get(client); + ConnectorMap connectorMap = ConnectorMap.get(client); + if (firstChild != null) { + ComponentConnector connector = connectorMap + .getConnector(firstChild); + if (connector.isRelativeHeight()) { + layoutManager.reportHeightAssignedToRelative(connector, + pixelPosition); + } else { + layoutManager.setNeedsMeasure(connector); } - break; - case VERTICAL: - wholeSize = DOM.getElementPropertyInt(wrapper, "clientHeight"); - pixelPosition = DOM.getElementPropertyInt(splitter, "offsetTop"); - - // reposition splitter in case it is out of box - if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize) - || (positionReversed && pixelPosition < 0)) { - pixelPosition = wholeSize - getSplitterSize(); - if (pixelPosition < 0) { - pixelPosition = 0; - } - // Move splitter within bounds, but don't remember the new value - setSplitPosition(pixelPosition + "px", false); - return; + } + if (secondChild != null) { + ComponentConnector connector = connectorMap + .getConnector(secondChild); + if (connector.isRelativeHeight()) { + layoutManager.reportHeightAssignedToRelative(connector, + secondContainerHeight); + } else { + layoutManager.setNeedsMeasure(connector); } + } + } + + private void horizontalOrientationUpdateSizes() { + int wholeSize = DOM.getElementPropertyInt(wrapper, "clientWidth"); + int pixelPosition = DOM.getElementPropertyInt(splitter, "offsetLeft"); - firstContainer.getStyle().setHeight(pixelPosition, Unit.PX); - int secondContainerHeight = (wholeSize - pixelPosition - getSplitterSize()); - if (secondContainerHeight < 0) { - secondContainerHeight = 0; + // reposition splitter in case it is out of box + if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize) + || (positionReversed && pixelPosition < 0)) { + pixelPosition = wholeSize - getSplitterSize(); + if (pixelPosition < 0) { + pixelPosition = 0; } - secondContainer.getStyle() - .setHeight(secondContainerHeight, Unit.PX); - secondContainer.getStyle().setTop( - pixelPosition + getSplitterSize(), Unit.PX); - - layoutManager = LayoutManager.get(client); - connectorMap = ConnectorMap.get(client); - if (firstChild != null) { - ComponentConnector connector = connectorMap - .getConnector(firstChild); - if (connector.isRelativeHeight()) { - layoutManager.reportHeightAssignedToRelative(connector, - pixelPosition); - } else { - layoutManager.setNeedsMeasure(connector); - } + // Move splitter within bounds, but don't remember the new value + setSplitPosition(pixelPosition + "px", false); + return; + } + + firstContainer.getStyle().setWidth(pixelPosition, Unit.PX); + int secondContainerWidth = (wholeSize - pixelPosition - getSplitterSize()); + if (secondContainerWidth < 0) { + secondContainerWidth = 0; + } + secondContainer.getStyle().setWidth(secondContainerWidth, Unit.PX); + secondContainer.getStyle().setLeft(pixelPosition + getSplitterSize(), + Unit.PX); + + LayoutManager layoutManager = LayoutManager.get(client); + ConnectorMap connectorMap = ConnectorMap.get(client); + if (firstChild != null) { + ComponentConnector connector = connectorMap + .getConnector(firstChild); + if (connector.isRelativeWidth()) { + layoutManager.reportWidthAssignedToRelative(connector, + pixelPosition); + } else { + layoutManager.setNeedsMeasure(connector); } - if (secondChild != null) { - ComponentConnector connector = connectorMap - .getConnector(secondChild); - if (connector.isRelativeHeight()) { - layoutManager.reportHeightAssignedToRelative(connector, - secondContainerHeight); - } else { - layoutManager.setNeedsMeasure(connector); - } + } + if (secondChild != null) { + ComponentConnector connector = connectorMap + .getConnector(secondChild); + if (connector.isRelativeWidth()) { + layoutManager.reportWidthAssignedToRelative(connector, + secondContainerWidth); + } else { + layoutManager.setNeedsMeasure(connector); } - break; + } + + // previous layout pass may have changed the position already, needs to + // be reset before calculating which positioning should be used + secondContainer.getStyle().setPosition(Position.ABSOLUTE); + if (getOffsetHeight() == 0) { + secondContainer.getStyle().setPosition(Position.RELATIVE); } } diff --git a/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeight.java b/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeight.java new file mode 100644 index 0000000000..4da5430cb1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeight.java @@ -0,0 +1,87 @@ +/* + * 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.splitpanel; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.HorizontalSplitPanel; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalSplitPanel; + +/** + * Test UI for horizontal split panel height. + * + * @author Vaadin Ltd + */ +public class HorizontalSplitPanelHeight extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + getLayout().setMargin(new MarginInfo(true, false, false, false)); + + HorizontalSplitPanel panel = new HorizontalSplitPanel(); + panel.setCaption("Horizontal 1 - no first component, label as second component"); + panel.setId("Horizontal 1"); + Label label = new Label("Label"); + label.addStyleName("target"); + panel.setSecondComponent(label); + + addComponent(panel); + + panel = new HorizontalSplitPanel(); + panel.setCaption("Horizontal 2 - button as first component, label as second component"); + panel.setId("Horizontal 2"); + label = new Label("Label"); + label.addStyleName("target"); + panel.setSecondComponent(label); + panel.setFirstComponent(new Button("button")); + + addComponent(panel); + + panel = new HorizontalSplitPanel(); + panel.setCaption("Horizontal 3 - fixed height, no first component, label as second component"); + panel.setId("Horizontal 3"); + label = new Label("Label"); + label.addStyleName("target"); + panel.setSecondComponent(label); + panel.setHeight(30, Unit.PIXELS); + + addComponent(panel); + + VerticalSplitPanel vPanel = new VerticalSplitPanel(); + vPanel.setCaption("Vertical 1 - no first component, label as second component"); + vPanel.setId("Vertical 1"); + vPanel.setHeight(100, Unit.PIXELS); + Label vLabel = new Label("Label"); + vLabel.addStyleName("target"); + vPanel.setSecondComponent(vLabel); + + addComponent(vPanel); + + } + + @Override + protected Integer getTicketNumber() { + return 15149; + } + + @Override + public String getTestDescription() { + return "Height of split panel should be greater than height of second component."; + } +} diff --git a/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeightTest.java b/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeightTest.java new file mode 100644 index 0000000000..0ceca66dd3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeightTest.java @@ -0,0 +1,71 @@ +/* + * 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.splitpanel; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for horizontal split panel height in case when only second component is + * set. + * + * @author Vaadin Ltd + */ +public class HorizontalSplitPanelHeightTest extends MultiBrowserTest { + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + } + + @Test + public void testHorizontalWithoutFirstComponent() { + testSplitPanel("Horizontal 1"); + } + + @Test + public void testHorizontalWithFirstComponent() { + testSplitPanel("Horizontal 2"); + } + + @Test + public void testHorizontalWithFixedHeight() { + testSplitPanel("Horizontal 3"); + } + + @Test + public void testVerticalWithoutFirstComponent() { + testSplitPanel("Vertical 1"); + } + + private void testSplitPanel(String id) { + WebElement splitPanel = findElement(By.id(id)); + WebElement label = splitPanel.findElement(By.className("target")); + Assert.assertTrue(id + ": split panel height (" + + splitPanel.getSize().getHeight() + ") is less than " + + "height of second component (" + label.getSize().getHeight() + + ")", splitPanel.getSize().getHeight() >= label.getSize() + .getHeight()); + Assert.assertEquals("Label text in the second panel is not visible", + "Label", label.getText()); + } +} -- cgit v1.2.3 From 9107b8d8c520bd297ed7685d7a8482d1078604e9 Mon Sep 17 00:00:00 2001 From: Teemu Pöntelin Date: Thu, 4 Dec 2014 20:09:42 +0200 Subject: Fix CustomLayout child rendering when template is missing (#8696) Change-Id: I8ce4fbc566f030bf22c555f68b97beb781b19805 --- .../ui/customlayout/CustomLayoutConnector.java | 23 ++++++++--- .../customlayout/CustomLayoutWithoutTemplate.java | 44 ++++++++++++++++++++++ .../CustomLayoutWithoutTemplateTest.java | 43 +++++++++++++++++++++ 3 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplate.java create mode 100644 uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplateTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java b/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java index a37ce9af38..80979587b9 100644 --- a/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java @@ -34,6 +34,8 @@ import com.vaadin.ui.CustomLayout; public class CustomLayoutConnector extends AbstractLayoutConnector implements SimpleManagedLayout, Paintable { + private boolean templateUpdated; + @Override public CustomLayoutState getState() { return (CustomLayoutState) super.getState(); @@ -62,7 +64,7 @@ public class CustomLayoutConnector extends AbstractLayoutConnector implements } private void updateHtmlTemplate() { - if (getWidget().hasTemplate()) { + if (templateUpdated) { // We (currently) only do this once. You can't change the template // later on. return; @@ -76,14 +78,23 @@ public class CustomLayoutConnector extends AbstractLayoutConnector implements templateContents = getConnection().getResource( "layouts/" + templateName + ".html"); if (templateContents == null) { - templateContents = "Layout file layouts/" - + templateName - + ".html is missing. Components will be drawn for debug purposes."; + // Template missing -> show debug notice and render components + // in order. + getWidget() + .getElement() + .setInnerHTML( + "Layout file layouts/" + + templateName + + ".html is missing. Components will be drawn for debug purposes."); } } - getWidget().initializeHTML(templateContents, - getConnection().getThemeUri()); + if (templateContents != null) { + // Template ok -> initialize. + getWidget().initializeHTML(templateContents, + getConnection().getThemeUri()); + } + templateUpdated = true; } @Override diff --git a/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplate.java b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplate.java new file mode 100644 index 0000000000..54949a053d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplate.java @@ -0,0 +1,44 @@ +/* + * 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.customlayout; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.CustomLayout; +import com.vaadin.ui.Label; + +public class CustomLayoutWithoutTemplate extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + CustomLayout cl = new CustomLayout("missing-layout-file.html"); + cl.addComponent(new Label("This Label should be visible."), "foo"); + cl.addComponent(new Button("And this Button too."), "bar"); + + addComponent(cl); + } + + @Override + protected String getTestDescription() { + return "Verify that CustomLayout renders child components even if the template is missing."; + } + + @Override + protected Integer getTicketNumber() { + return 8696; + } +} diff --git a/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplateTest.java b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplateTest.java new file mode 100644 index 0000000000..695d9cceff --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplateTest.java @@ -0,0 +1,43 @@ +/* + * 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.customlayout; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.ElementQuery; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.CustomLayoutElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class CustomLayoutWithoutTemplateTest extends SingleBrowserTest { + + @Test + public void testChildComponents() { + openTestURL(); + + ElementQuery customLayout = $(CustomLayoutElement.class); + + // Verify the Button and Label are rendered inside the CustomLayout. + assertTrue("Button was not rendered.", + customLayout.$(ButtonElement.class).exists()); + assertTrue("Label was not rendered.", customLayout + .$(LabelElement.class).exists()); + } + +} -- cgit v1.2.3 From 23bdb6e90d970bd4e9ef11c79c095e65b6963414 Mon Sep 17 00:00:00 2001 From: Denis Anisimov Date: Tue, 23 Sep 2014 22:18:40 +0300 Subject: Notify server side component about clicks in form layout (#6346). Change-Id: Idc4399dc94b253694c4e0d716d2b65964a2217f8 --- .../client/ui/formlayout/FormLayoutConnector.java | 24 ++++++++ .../formlayout/FormLayoutClickListener.java | 69 ++++++++++++++++++++++ .../formlayout/FormLayoutClickListenerTest.java | 62 +++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListener.java create mode 100644 uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListenerTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java b/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java index 494a1a87ff..ae4b03e0f8 100644 --- a/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java @@ -24,18 +24,41 @@ import com.vaadin.client.Util; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractFieldConnector; import com.vaadin.client.ui.AbstractLayoutConnector; +import com.vaadin.client.ui.LayoutClickEventHandler; import com.vaadin.client.ui.VFormLayout; import com.vaadin.client.ui.VFormLayout.Caption; import com.vaadin.client.ui.VFormLayout.ErrorFlag; import com.vaadin.client.ui.VFormLayout.VFormLayoutTable; import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.LayoutClickRpc; import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutServerRpc; import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState; import com.vaadin.ui.FormLayout; @Connect(FormLayout.class) public class FormLayoutConnector extends AbstractLayoutConnector { + /* + * Handlers & Listeners + */ + + private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( + this) { + + @Override + protected ComponentConnector getChildComponent( + com.google.gwt.user.client.Element element) { + return Util.getConnectorForElement(getConnection(), getWidget(), + element); + } + + @Override + protected LayoutClickRpc getLayoutClickRPC() { + return getRpcProxy(AbstractOrderedLayoutServerRpc.class); + } + }; + @Override public AbstractOrderedLayoutState getState() { return (AbstractOrderedLayoutState) super.getState(); @@ -45,6 +68,7 @@ public class FormLayoutConnector extends AbstractLayoutConnector { public void onStateChanged(StateChangeEvent stateChangeEvent) { super.onStateChanged(stateChangeEvent); + clickEventHandler.handleEventHandlerRegistration(); VFormLayoutTable formLayoutTable = getWidget().table; formLayoutTable.setMargins(new MarginInfo(getState().marginsBitmask)); diff --git a/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListener.java b/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListener.java new file mode 100644 index 0000000000..35b8d9ca86 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListener.java @@ -0,0 +1,69 @@ +/* + * 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.formlayout; + +import com.vaadin.event.LayoutEvents.LayoutClickEvent; +import com.vaadin.event.LayoutEvents.LayoutClickListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Label; + +/** + * Test UI for Form layout click listener. + * + * @author Vaadin Ltd + */ +public class FormLayoutClickListener extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + FormLayout layout = new FormLayout(); + + layout.addStyleName("form"); + + Label label = new Label("target"); + label.addStyleName("label"); + layout.addComponent(label); + + layout.addLayoutClickListener(new LayoutClickListener() { + + @Override + public void layoutClick(LayoutClickEvent event) { + log("Child component: " + + (event.getChildComponent() == null ? null : event + .getChildComponent().getStyleName())); + log("Clicked component: " + + (event.getClickedComponent() == null ? null : event + .getClickedComponent().getStyleName())); + log("Source component: " + event.getComponent().getStyleName()); + } + }); + + addComponent(layout); + } + + @Override + protected String getTestDescription() { + return "LayoutClickListener should work in FormLayout"; + } + + @Override + protected Integer getTicketNumber() { + return 6346; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListenerTest.java b/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListenerTest.java new file mode 100644 index 0000000000..bcab514a5d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListenerTest.java @@ -0,0 +1,62 @@ +/* + * 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.formlayout; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.testbench.elements.FormLayoutElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for form layout click listener. + * + * @author Vaadin Ltd + */ +public class FormLayoutClickListenerTest extends MultiBrowserTest { + + @Before + public void setUp() { + openTestURL(); + } + + @Test + public void layoutClickListener_clickOnLayout_childAndClickedComponentsAreNull() { + $(FormLayoutElement.class).first().click(); + + Assert.assertEquals("Source component for click event must be form", + "3. Source component: form", getLogRow(0)); + Assert.assertEquals("Clicked component for click event must be null", + "2. Clicked component: null", getLogRow(1)); + Assert.assertEquals("Child component for click event must be null", + "1. Child component: null", getLogRow(2)); + } + + @Test + public void layoutClickListener_clickOnLabel_lableIsChildAndClickedComponent() { + findElement(By.className("label")).click(); + + Assert.assertEquals("Source component for click event must be form", + "3. Source component: form", getLogRow(0)); + Assert.assertEquals("Clicked component for click event must be label", + "2. Clicked component: label", getLogRow(1)); + Assert.assertEquals("Child component for click event must be label", + "1. Child component: label", getLogRow(2)); + } + +} -- cgit v1.2.3 From b91063f884108bfc69a617846d91263339b062fe Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 9 Dec 2014 19:43:06 +0200 Subject: Clear all bound fields when nulling the field group data source (#12371) Change-Id: I48eb0e7851187fa6bbb9024730b2611a74501ad0 --- .../com/vaadin/data/fieldgroup/BeanFieldGroup.java | 9 +- .../src/com/vaadin/data/fieldgroup/FieldGroup.java | 19 ++-- .../component/fieldgroup/BeanFieldGroupTest.java | 12 +-- .../src/com/vaadin/tests/fieldgroup/BasicCrud.java | 110 +++++++++++++++++++++ .../com/vaadin/tests/fieldgroup/BasicCrudTest.java | 68 +++++++++++++ 5 files changed, 198 insertions(+), 20 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/fieldgroup/BasicCrud.java create mode 100644 uitest/src/com/vaadin/tests/fieldgroup/BasicCrudTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java index 1f3ee36d58..257a958f3a 100644 --- a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java +++ b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java @@ -125,12 +125,19 @@ public class BeanFieldGroup extends FieldGroup { * Helper method for setting the data source directly using a bean. This * method wraps the bean in a {@link BeanItem} and calls * {@link #setItemDataSource(Item)}. + *

+ * For null values, a null item is passed to + * {@link #setItemDataSource(Item)} to be properly clear fields. * * @param bean * The bean to use as data source. */ public void setItemDataSource(T bean) { - setItemDataSource(new BeanItem(bean, beanType)); + if (bean == null) { + setItemDataSource((Item) null); + } else { + setItemDataSource(new BeanItem(bean, beanType)); + } } @Override diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java index bcfa8395df..c89b94ace9 100644 --- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java +++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java @@ -26,7 +26,6 @@ import java.util.List; import com.vaadin.data.Item; import com.vaadin.data.Property; -import com.vaadin.data.Validator; import com.vaadin.data.Validator.InvalidValueException; import com.vaadin.data.util.TransactionalPropertyWrapper; import com.vaadin.ui.AbstractField; @@ -256,6 +255,9 @@ public class FieldGroup implements Serializable { fieldToPropertyId.put(field, propertyId); propertyIdToField.put(propertyId, field); if (itemDataSource == null) { + // Clear any possible existing binding to clear the field + field.setPropertyDataSource(null); + field.clear(); // Will be bound when data source is set return; } @@ -461,7 +463,7 @@ public class FieldGroup implements Serializable { List invalidValueExceptions = commitFields(); - if(invalidValueExceptions.isEmpty()) { + if (invalidValueExceptions.isEmpty()) { firePostCommitEvent(); commitTransactions(); } else { @@ -489,12 +491,14 @@ public class FieldGroup implements Serializable { return invalidValueExceptions; } - private void throwInvalidValueException(List invalidValueExceptions) { - if(invalidValueExceptions.size() == 1) { + private void throwInvalidValueException( + List invalidValueExceptions) { + if (invalidValueExceptions.size() == 1) { throw invalidValueExceptions.get(0); } else { - InvalidValueException[] causes = invalidValueExceptions.toArray( - new InvalidValueException[invalidValueExceptions.size()]); + InvalidValueException[] causes = invalidValueExceptions + .toArray(new InvalidValueException[invalidValueExceptions + .size()]); throw new InvalidValueException(null, causes); } @@ -515,8 +519,7 @@ public class FieldGroup implements Serializable { private void commitTransactions() { for (Field f : fieldToPropertyId.keySet()) { - ((Property.Transactional) f.getPropertyDataSource()) - .commit(); + ((Property.Transactional) f.getPropertyDataSource()).commit(); } } diff --git a/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java index 965fb49479..9c37b91ef5 100644 --- a/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java +++ b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java @@ -2,8 +2,6 @@ package com.vaadin.tests.server.component.fieldgroup; import static org.junit.Assert.assertEquals; -import java.util.Collection; - import org.junit.Assert; import org.junit.Test; @@ -144,15 +142,7 @@ public class BeanFieldGroupTest { group.setItemDataSource((MyBean) null); BeanItem dataSource = group.getItemDataSource(); - Assert.assertNotNull("Data source is null for null bean", dataSource); - - Collection itemPropertyIds = dataSource.getItemPropertyIds(); - Assert.assertEquals("Unexpected number of properties", 3, - itemPropertyIds.size()); - for (Object id : itemPropertyIds) { - Assert.assertNull("Value for property " + id + " is not null", - dataSource.getItemProperty(id).getValue()); - } + Assert.assertNull("Data source is null for null bean", dataSource); } @Test diff --git a/uitest/src/com/vaadin/tests/fieldgroup/BasicCrud.java b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrud.java new file mode 100644 index 0000000000..be0368f4ae --- /dev/null +++ b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrud.java @@ -0,0 +1,110 @@ +/* + * 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.fieldgroup; + +import com.vaadin.annotations.Theme; +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.data.fieldgroup.BeanFieldGroup; +import com.vaadin.data.fieldgroup.PropertyId; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.util.Person; +import com.vaadin.tests.util.PersonContainer; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Table; +import com.vaadin.ui.TextField; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +@Theme("valo") +public class BasicCrud extends UI { + + private Form form; + + @Override + protected void init(VaadinRequest request) { + VerticalLayout main = new VerticalLayout(); + main.setMargin(true); + main.setSpacing(true); + final Table t = new Table(); + // t.setSelectionMode(SelectionMode.SINGLE); + t.setSelectable(true); + + PersonContainer c = PersonContainer.createWithTestData(); + + c.addBean(new Person("first", "Last", "email", "phone", "street", + 12332, "Turku")); + c.addBean(new Person("Foo", "Bar", "me@some.where", "123", + "homestreet 12", 10000, "Glasgow")); + t.setContainerDataSource(c); + // t.removeColumn("address"); + // t.setColumnOrder("firstName", "lastName", "email", "phoneNumber", + // "address.streetAddress", "address.postalCode", "address.city"); + t.setVisibleColumns("firstName", "lastName", "email", "phoneNumber", + "address.streetAddress", "address.postalCode", "address.city"); + + // t.addSelectionChangeListener(new SelectionChangeListener() { + // @Override + // public void selectionChange(SelectionChangeEvent event) { + // form.edit((Person) t.getSelectedRow()); + // } + // }); + t.addValueChangeListener(new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + form.edit((Person) t.getValue()); + } + }); + + form = new Form(); + + t.setSizeFull(); + + main.setSizeFull(); + main.addComponent(t); + main.addComponent(form); + main.setExpandRatio(t, 1); + setContent(main); + } + + public static class Form extends HorizontalLayout { + private TextField firstName = new TextField("First name"); + private TextField lastName = new TextField("Last name"); + private TextField email = new TextField("E-mail"); + @PropertyId("address.streetAddress") + private TextField streetAddress = new TextField("Street address"); + @PropertyId("address.postalCode") + private TextField postalCode = new TextField("Postal code"); + + BeanFieldGroup fieldGroup = new BeanFieldGroup( + Person.class); + + public Form() { + setSpacing(true); + setId("form"); + fieldGroup.bindMemberFields(this); + + // Stupid integer binding + postalCode.setNullRepresentation(""); + addComponents(firstName, lastName, email, streetAddress, postalCode); + } + + public void edit(Person p) { + fieldGroup.setItemDataSource(p); + } + } +} diff --git a/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudTest.java b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudTest.java new file mode 100644 index 0000000000..a41725dbc9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudTest.java @@ -0,0 +1,68 @@ +/* + * 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.fieldgroup; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.AbstractOrderedLayoutElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class BasicCrudTest extends SingleBrowserTest { + + @Test + public void fieldsInitiallyEmpty() { + openTestURL(); + AbstractOrderedLayoutElement fieldsLayout = $( + AbstractOrderedLayoutElement.class).id("form"); + List textFields = fieldsLayout.$( + TextFieldElement.class).all(); + + for (TextFieldElement e : textFields) { + Assert.assertEquals("TextField should be empty", "", e.getValue()); + } + } + + @Test + public void fieldsClearedOnDeselect() { + openTestURL(); + AbstractOrderedLayoutElement fieldsLayout = $( + AbstractOrderedLayoutElement.class).id("form"); + + // Select row + $(TableElement.class).first().getCell(2, 2).click(); + + List textFields = fieldsLayout.$( + TextFieldElement.class).all(); + + for (TextFieldElement e : textFields) { + Assert.assertNotEquals("TextField should not be empty", "", + e.getValue()); + } + + // Deselect row + $(TableElement.class).first().getCell(2, 2).click(); + + for (TextFieldElement e : textFields) { + Assert.assertEquals("TextField should be empty", "", e.getValue()); + } + + } +} -- cgit v1.2.3 From c4e4f449464f22c11e33b92f8aa578db959e92b2 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 9 Dec 2014 22:16:50 +0200 Subject: Convert empty string to null Enum value, only throw ConversionExceptions (#14756) Change-Id: I027a245975db12e3661740bd233edd98e73994e9 --- .../data/util/converter/StringToEnumConverter.java | 20 +++++++++++--------- .../data/converter/TestStringToEnumConverter.java | 14 ++++++++++++++ .../tests/components/textfield/EnumTextField.java | 1 + .../components/textfield/EnumTextFieldTest.java | 7 ++++--- 4 files changed, 30 insertions(+), 12 deletions(-) (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java b/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java index a1328d831c..29bf8fc400 100644 --- a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java +++ b/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java @@ -34,7 +34,7 @@ public class StringToEnumConverter implements Converter { @Override public Enum convertToModel(String value, Class targetType, Locale locale) throws ConversionException { - if (value == null) { + if (value == null || value.trim().equals("")) { return null; } if (locale == null) { @@ -46,19 +46,21 @@ public class StringToEnumConverter implements Converter { String result = value.replace(" ", "_").toUpperCase(locale); try { return Enum.valueOf(targetType, result); - } catch (IllegalArgumentException ee) { + } catch (Exception ee) { // There was no match. Try to compare the available values to see if // the constant is using something else than all upper case - - EnumSet set = EnumSet.allOf(targetType); - for (Enum e : set) { - if (e.name().toUpperCase(locale).equals(result)) { - return e; + try { + EnumSet set = EnumSet.allOf(targetType); + for (Enum e : set) { + if (e.name().toUpperCase(locale).equals(result)) { + return e; + } } + } catch (Exception e) { } - // Fallback did not work either, re-throw original exception so user - // knows what went wrong + // Fallback did not work either, re-throw original exception so + // user knows what went wrong throw new ConversionException(ee); } } diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java index 2b19395c08..5dc24ca43a 100644 --- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java +++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java @@ -3,6 +3,7 @@ package com.vaadin.tests.data.converter; import junit.framework.TestCase; import com.vaadin.data.util.converter.Converter; +import com.vaadin.data.util.converter.Converter.ConversionException; import com.vaadin.data.util.converter.ReverseConverter; import com.vaadin.data.util.converter.StringToEnumConverter; @@ -16,6 +17,19 @@ public class TestStringToEnumConverter extends TestCase { Converter reverseConverter = new ReverseConverter( converter); + public void testEmptyStringConversion() { + assertEquals(null, converter.convertToModel("", Enum.class, null)); + } + + public void testInvalidEnumClassConversion() { + try { + converter.convertToModel("Foo", Enum.class, null); + fail("No exception thrown"); + } catch (ConversionException e) { + // OK + } + } + public void testNullConversion() { assertEquals(null, converter.convertToModel(null, Enum.class, null)); } diff --git a/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java b/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java index 67b3b84688..99e08ae32d 100644 --- a/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java +++ b/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java @@ -31,6 +31,7 @@ public class EnumTextField extends AbstractTestUIWithLog { @Override protected void setup(VaadinRequest request) { final TextField tf = new TextField(); + tf.setNullRepresentation(""); tf.addValueChangeListener(new ValueChangeListener() { @Override diff --git a/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java b/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java index 113acee3a2..fe26fb7aad 100644 --- a/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java +++ b/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java @@ -27,8 +27,7 @@ public class EnumTextFieldTest extends SingleBrowserTest { public void validValues() { openTestURL(); $(TextFieldElement.class).first().clear(); - $(TextFieldElement.class).first().sendKeys("Value"); - $(TextFieldElement.class).first().sendKeys(Keys.TAB); + $(TextFieldElement.class).first().sendKeys("Value", Keys.TAB); Assert.assertEquals("3. Value (valid)", getLogRow(0)); $(TextFieldElement.class).first().clear(); @@ -41,13 +40,15 @@ public class EnumTextFieldTest extends SingleBrowserTest { $(TextFieldElement.class).first().sendKeys(Keys.TAB); Assert.assertEquals("7. The last value (valid)", getLogRow(0)); + $(TextFieldElement.class).first().clear(); + Assert.assertEquals("8. null (valid)", getLogRow(0)); + } @Test public void invalidValue() { openTestURL(); $(TextFieldElement.class).first().clear(); - Assert.assertEquals("2. (INVALID)", getLogRow(0)); $(TextFieldElement.class).first().sendKeys("bar"); $(TextFieldElement.class).first().sendKeys(Keys.TAB); -- cgit v1.2.3 From 5eaf32a1404399f7b39f3b60060ed3d101ec08f8 Mon Sep 17 00:00:00 2001 From: Alexey Fansky Date: Wed, 10 Dec 2014 15:52:46 -0800 Subject: Reset tabsheet scroller when unhiding leftmost tab (#14644) Checking whether invisible tab are present before the scroll index and if so resetting the scroll index when tab goes back to visible. Change-Id: I156dbe93963b0d9f46e21a593ffc3c4c77ebd1c6 --- client/src/com/vaadin/client/ui/VTabsheet.java | 27 ++++++++++++- .../tabsheet/FirstTabNotVisibleInTabsheet.java | 44 ++++++++++++++++++++++ .../tabsheet/FirstTabNotVisibleInTabsheetTest.java | 27 +++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheet.java create mode 100644 uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheetTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/VTabsheet.java b/client/src/com/vaadin/client/ui/VTabsheet.java index bcca117395..090f83c066 100644 --- a/client/src/com/vaadin/client/ui/VTabsheet.java +++ b/client/src/com/vaadin/client/ui/VTabsheet.java @@ -78,6 +78,8 @@ import com.vaadin.shared.ui.tabsheet.TabsheetState; public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware { + private static final String PREV_SCROLLER_DISABLED_CLASSNAME = "Prev-disabled"; + private static class VCloseEvent { private Tab tab; @@ -1069,6 +1071,22 @@ public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware updateOpenTabSize(); } + private boolean isAllTabsBeforeIndexInvisible() { + boolean invisible = true; + for (int i = 0; i < scrollerIndex; i++) { + invisible = invisible & !tb.getTab(i).isVisible(); + } + return invisible; + } + + private boolean isScrollerPrevDisabled() { + return scrollerPrev.getClassName().contains(PREV_SCROLLER_DISABLED_CLASSNAME); + } + + private boolean isIndexSkippingHiddenTabs() { + return isAllTabsBeforeIndexInvisible() && isScrollerPrevDisabled(); + } + @Override public void renderTab(final TabState tabState, int index) { Tab tab = tb.getTab(index); @@ -1080,10 +1098,15 @@ public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware tab.setEnabledOnServer((!disabledTabKeys.contains(tabKeys.get(index)))); tab.setHiddenOnServer(!tabState.visible); - if (scrolledOutOfView(index)) { + if (scrolledOutOfView(index) && !isIndexSkippingHiddenTabs()) { // Should not set tabs visible if they are scrolled out of view tab.setVisible(false); } else { + //reset the scroller index back to zero if tab is visible + //again and tab is in view + if(isIndexSkippingHiddenTabs() && tabState.visible) { + scrollerIndex = 0; + } tab.setVisible(tabState.visible); } @@ -1223,7 +1246,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware if (tb.getTabCount() > 0 && tb.isVisible() && (scrolled || clipped)) { scroller.getStyle().clearDisplay(); DOM.setElementProperty(scrollerPrev, "className", - SCROLLER_CLASSNAME + (scrolled ? "Prev" : "Prev-disabled")); + SCROLLER_CLASSNAME + (scrolled ? "Prev" : PREV_SCROLLER_DISABLED_CLASSNAME)); DOM.setElementProperty(scrollerNext, "className", SCROLLER_CLASSNAME + (clipped ? "Next" : "Next-disabled")); diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheet.java b/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheet.java new file mode 100644 index 0000000000..c21c702bd0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheet.java @@ -0,0 +1,44 @@ +package com.vaadin.tests.components.tabsheet; + +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinServlet; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.*; + +import javax.servlet.annotation.WebServlet; + +@SuppressWarnings("serial") +public class FirstTabNotVisibleInTabsheet extends AbstractTestUI { + + private TabSheet.Tab firstTab; + + @Override + protected void setup(VaadinRequest request) { + TabSheet tabSheet = new TabSheet(); + tabSheet.setWidth("600px"); + + firstTab = tabSheet.addTab(new Label("first visible tab"), "first visible tab"); + + for (int i = 2; i < 10; i++) { + tabSheet.addTab(new Label("visible tab " + i), "visible tab " + i); + } + + addComponent(new VerticalLayout(tabSheet, new Button("Toggle first tab", new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + firstTab.setVisible(!firstTab.isVisible()); + } + }))); + } + + @Override + protected Integer getTicketNumber() { + return 14644; + } + + @Override + protected String getTestDescription() { + return "First tabsheet tab is not set visible back once it gets invisible"; + } +} \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheetTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheetTest.java new file mode 100644 index 0000000000..e57651ba03 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheetTest.java @@ -0,0 +1,27 @@ +package com.vaadin.tests.components.tabsheet; + + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TabSheetElement; +import com.vaadin.tests.tb3.MultiBrowserTest; +import junit.framework.Assert; +import org.junit.Test; + +public class FirstTabNotVisibleInTabsheetTest extends MultiBrowserTest { + @Test + public void testFirstTabIsVisibleAfterBeingInvisible() { + openTestURL(); + + toggleFirstTabVisibility(); + toggleFirstTabVisibility(); + + TabSheetElement tabSheet = $(TabSheetElement.class).first(); + + Assert.assertTrue("TabSheet should have first tab visible", + tabSheet.getTabCaptions().contains("first visible tab")); + } + + private void toggleFirstTabVisibility() { + $(ButtonElement.class).caption("Toggle first tab").first().click(); + } +} -- cgit v1.2.3 From c0f689891ca05e9e74d184ee7528e1aadde84023 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 4 Dec 2014 09:13:15 +0200 Subject: Test UI for #15321 Change-Id: I108f8ad473e6637bff9619f110f9194a56482c3e --- .../HorizontalLayoutWithLabelAndButton.java | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/layouts/HorizontalLayoutWithLabelAndButton.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/uitest/src/com/vaadin/tests/layouts/HorizontalLayoutWithLabelAndButton.java b/uitest/src/com/vaadin/tests/layouts/HorizontalLayoutWithLabelAndButton.java new file mode 100644 index 0000000000..9381f2caeb --- /dev/null +++ b/uitest/src/com/vaadin/tests/layouts/HorizontalLayoutWithLabelAndButton.java @@ -0,0 +1,43 @@ +/* + * 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.layouts; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; + +public class HorizontalLayoutWithLabelAndButton extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + HorizontalLayout hl = new HorizontalLayout(); + hl.setSpacing(true); + hl.setWidth("100%"); + Label l = new Label(); + l.setCaption("POTUS Database"); + l.setSizeUndefined(); + + Button b = new Button("Add new"); + hl.addComponents(l, b); + b.setStyleName("primary"); + hl.setExpandRatio(b, 1); + + addComponent(hl); + } + +} -- cgit v1.2.3 From dd879668f5f74dfea8a804f3ff3c1e7c2f89a5a3 Mon Sep 17 00:00:00 2001 From: Markus Koivisto Date: Thu, 11 Dec 2014 12:10:48 +0000 Subject: Revert "Notify server side component about clicks in form layout (#6346)." This reverts commit 23bdb6e90d970bd4e9ef11c79c095e65b6963414. The included test (FormLayoutClickListenerTest) fails on all other browsers except PhantomJS. Change-Id: Ib60d051da9100eef8f30e6578ac73314bcda3ec3 --- .../client/ui/formlayout/FormLayoutConnector.java | 24 -------- .../formlayout/FormLayoutClickListener.java | 69 ---------------------- .../formlayout/FormLayoutClickListenerTest.java | 62 ------------------- 3 files changed, 155 deletions(-) delete mode 100644 uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListener.java delete mode 100644 uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListenerTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java b/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java index ae4b03e0f8..494a1a87ff 100644 --- a/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java @@ -24,41 +24,18 @@ import com.vaadin.client.Util; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractFieldConnector; import com.vaadin.client.ui.AbstractLayoutConnector; -import com.vaadin.client.ui.LayoutClickEventHandler; import com.vaadin.client.ui.VFormLayout; import com.vaadin.client.ui.VFormLayout.Caption; import com.vaadin.client.ui.VFormLayout.ErrorFlag; import com.vaadin.client.ui.VFormLayout.VFormLayoutTable; import com.vaadin.shared.ui.Connect; -import com.vaadin.shared.ui.LayoutClickRpc; import com.vaadin.shared.ui.MarginInfo; -import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutServerRpc; import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState; import com.vaadin.ui.FormLayout; @Connect(FormLayout.class) public class FormLayoutConnector extends AbstractLayoutConnector { - /* - * Handlers & Listeners - */ - - private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( - this) { - - @Override - protected ComponentConnector getChildComponent( - com.google.gwt.user.client.Element element) { - return Util.getConnectorForElement(getConnection(), getWidget(), - element); - } - - @Override - protected LayoutClickRpc getLayoutClickRPC() { - return getRpcProxy(AbstractOrderedLayoutServerRpc.class); - } - }; - @Override public AbstractOrderedLayoutState getState() { return (AbstractOrderedLayoutState) super.getState(); @@ -68,7 +45,6 @@ public class FormLayoutConnector extends AbstractLayoutConnector { public void onStateChanged(StateChangeEvent stateChangeEvent) { super.onStateChanged(stateChangeEvent); - clickEventHandler.handleEventHandlerRegistration(); VFormLayoutTable formLayoutTable = getWidget().table; formLayoutTable.setMargins(new MarginInfo(getState().marginsBitmask)); diff --git a/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListener.java b/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListener.java deleted file mode 100644 index 35b8d9ca86..0000000000 --- a/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListener.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.formlayout; - -import com.vaadin.event.LayoutEvents.LayoutClickEvent; -import com.vaadin.event.LayoutEvents.LayoutClickListener; -import com.vaadin.server.VaadinRequest; -import com.vaadin.tests.components.AbstractTestUIWithLog; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Label; - -/** - * Test UI for Form layout click listener. - * - * @author Vaadin Ltd - */ -public class FormLayoutClickListener extends AbstractTestUIWithLog { - - @Override - protected void setup(VaadinRequest request) { - FormLayout layout = new FormLayout(); - - layout.addStyleName("form"); - - Label label = new Label("target"); - label.addStyleName("label"); - layout.addComponent(label); - - layout.addLayoutClickListener(new LayoutClickListener() { - - @Override - public void layoutClick(LayoutClickEvent event) { - log("Child component: " - + (event.getChildComponent() == null ? null : event - .getChildComponent().getStyleName())); - log("Clicked component: " - + (event.getClickedComponent() == null ? null : event - .getClickedComponent().getStyleName())); - log("Source component: " + event.getComponent().getStyleName()); - } - }); - - addComponent(layout); - } - - @Override - protected String getTestDescription() { - return "LayoutClickListener should work in FormLayout"; - } - - @Override - protected Integer getTicketNumber() { - return 6346; - } - -} diff --git a/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListenerTest.java b/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListenerTest.java deleted file mode 100644 index bcab514a5d..0000000000 --- a/uitest/src/com/vaadin/tests/components/formlayout/FormLayoutClickListenerTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.formlayout; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.By; - -import com.vaadin.testbench.elements.FormLayoutElement; -import com.vaadin.tests.tb3.MultiBrowserTest; - -/** - * Test for form layout click listener. - * - * @author Vaadin Ltd - */ -public class FormLayoutClickListenerTest extends MultiBrowserTest { - - @Before - public void setUp() { - openTestURL(); - } - - @Test - public void layoutClickListener_clickOnLayout_childAndClickedComponentsAreNull() { - $(FormLayoutElement.class).first().click(); - - Assert.assertEquals("Source component for click event must be form", - "3. Source component: form", getLogRow(0)); - Assert.assertEquals("Clicked component for click event must be null", - "2. Clicked component: null", getLogRow(1)); - Assert.assertEquals("Child component for click event must be null", - "1. Child component: null", getLogRow(2)); - } - - @Test - public void layoutClickListener_clickOnLabel_lableIsChildAndClickedComponent() { - findElement(By.className("label")).click(); - - Assert.assertEquals("Source component for click event must be form", - "3. Source component: form", getLogRow(0)); - Assert.assertEquals("Clicked component for click event must be label", - "2. Clicked component: label", getLogRow(1)); - Assert.assertEquals("Child component for click event must be label", - "1. Child component: label", getLogRow(2)); - } - -} -- cgit v1.2.3 From 10fa4e4236ed049ef6eac337d23701bc381763ce Mon Sep 17 00:00:00 2001 From: Sauli Tähkäpää Date: Thu, 11 Dec 2014 23:12:12 +0200 Subject: Fix gradient path for notifications in Chameleon. (#15351) Change-Id: Ie1e2726613033ad321e15f7f58e098080d4d9a5f --- .../components/notification/notification.scss | 4 +-- .../themes/chameleon/ChameleonNotification.java | 30 ++++++++++++++++++++++ .../chameleon/ChameleonNotificationTest.java | 25 ++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotification.java create mode 100644 uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotificationTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss b/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss index 85fbb3295f..c1a8d119c7 100644 --- a/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss +++ b/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss @@ -9,8 +9,8 @@ div.#{$primaryStyleName} { -moz-box-shadow: 0 2px 5px rgba(0,0,0,.7); box-shadow: 0 2px 5px rgba(0,0,0,.7); //IE8 does not support rgba, using just rgb - background:rgb(255,255,255) url(../img/grad-light-top.png) repeat-x; - background:rgba(255,255,255,.90) url(../img/grad-light-top.png) repeat-x; + background:rgb(255,255,255) url(../../img/grad-light-top.png) repeat-x; + background:rgba(255,255,255,.90) url(../../img/grad-light-top.png) repeat-x; } .#{$primaryStyleName} p { diff --git a/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotification.java b/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotification.java new file mode 100644 index 0000000000..efb953530c --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotification.java @@ -0,0 +1,30 @@ +package com.vaadin.tests.themes.chameleon; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Notification; +import com.vaadin.ui.themes.ChameleonTheme; + +@Theme(ChameleonTheme.THEME_NAME) +public class ChameleonNotification extends AbstractTestUI { + @Override + protected void setup(VaadinRequest request) { + + + addButton("Notification", new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + Notification notification = new Notification("Notification"); + notification.setDelayMsec(30000); + notification.show(getUI().getPage()); + } + }); + } + + @Override + protected Integer getTicketNumber() { + return 15351; + } +} diff --git a/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotificationTest.java b/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotificationTest.java new file mode 100644 index 0000000000..ef41ef3df9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotificationTest.java @@ -0,0 +1,25 @@ +package com.vaadin.tests.themes.chameleon; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.tb3.MultiBrowserTest; +import org.junit.Test; + +import java.io.IOException; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +public class ChameleonNotificationTest extends MultiBrowserTest { + @Test + public void gradientPathIsCorrect() throws IOException { + openTestURL(); + $(ButtonElement.class).first().click(); + + NotificationElement notificationElement + = $(NotificationElement.class).first(); + + assertThat(notificationElement.getCssValue("background-image"), + containsString("chameleon/img/grad")); + } +} \ No newline at end of file -- cgit v1.2.3 From dfaaae821ebea039dae6923c7433673b719dd42d Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 25 Sep 2014 10:27:51 +0300 Subject: Use converter for Select/Tree/ComboBox when using item id for caption (#11433) Change-Id: I10c47986b98e132e874b2882fbb2323409d67a25 --- .../data/util/converter/StringToEnumConverter.java | 62 +++++++++++++++---- server/src/com/vaadin/ui/AbstractSelect.java | 17 +++++- .../notification/NotificationsWaiAriaTest.java | 7 ++- .../vaadin/tests/components/select/EnumSelect.java | 69 ++++++++++++++++++++++ .../tests/components/select/EnumSelectTest.java | 61 +++++++++++++++++++ 5 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/select/EnumSelect.java create mode 100644 uitest/src/com/vaadin/tests/components/select/EnumSelectTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java b/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java index 29bf8fc400..e91dd2a303 100644 --- a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java +++ b/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java @@ -37,6 +37,28 @@ public class StringToEnumConverter implements Converter { if (value == null || value.trim().equals("")) { return null; } + + return stringToEnum(value, targetType, locale); + } + + /** + * Converts the given string to the given enum type using the given locale + *

+ * Compatible with {@link #enumToString(Enum, Locale)} + * + * @param value + * The string value to convert + * @param enumType + * The type of enum to create + * @param locale + * The locale to use for conversion. If null, the JVM default + * locale will be used + * @return The enum which matches the given string + * @throws ConversionException + * if the conversion fails + */ + public static > T stringToEnum(String value, + Class enumType, Locale locale) throws ConversionException { if (locale == null) { locale = Locale.getDefault(); } @@ -45,13 +67,13 @@ public class StringToEnumConverter implements Converter { // Foo bar -> FOO_BAR String result = value.replace(" ", "_").toUpperCase(locale); try { - return Enum.valueOf(targetType, result); + return Enum.valueOf(enumType, result); } catch (Exception ee) { // There was no match. Try to compare the available values to see if // the constant is using something else than all upper case try { - EnumSet set = EnumSet.allOf(targetType); - for (Enum e : set) { + EnumSet set = EnumSet.allOf(enumType); + for (T e : set) { if (e.name().toUpperCase(locale).equals(result)) { return e; } @@ -65,13 +87,21 @@ public class StringToEnumConverter implements Converter { } } - @Override - public String convertToPresentation(Enum value, - Class targetType, Locale locale) - throws ConversionException { - if (value == null) { - return null; - } + /** + * Converts the given enum to a human readable string using the given locale + *

+ * Compatible with {@link #stringToEnum(String, Class, Locale)} + * + * @param value + * The enum value to convert + * @param locale + * The locale to use for conversion. If null, the JVM default + * locale will be used + * @return A human readable string based on the enum + * @throws ConversionException + * if the conversion fails + */ + public static String enumToString(Enum value, Locale locale) { if (locale == null) { locale = Locale.getDefault(); } @@ -82,10 +112,20 @@ public class StringToEnumConverter implements Converter { // _FOO -> _foo String result = enumString.substring(0, 1).toUpperCase(locale); result += enumString.substring(1).toLowerCase(locale).replace('_', ' '); - return result; } + @Override + public String convertToPresentation(Enum value, + Class targetType, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + return enumToString(value, locale); + } + @Override public Class getModelType() { return Enum.class; diff --git a/server/src/com/vaadin/ui/AbstractSelect.java b/server/src/com/vaadin/ui/AbstractSelect.java index 70f08c95d8..1a3eeb88a3 100644 --- a/server/src/com/vaadin/ui/AbstractSelect.java +++ b/server/src/com/vaadin/ui/AbstractSelect.java @@ -33,6 +33,8 @@ import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.data.util.IndexedContainer; +import com.vaadin.data.util.converter.Converter; +import com.vaadin.data.util.converter.ConverterUtil; import com.vaadin.event.DataBoundTransferable; import com.vaadin.event.Transferable; import com.vaadin.event.dd.DragAndDropEvent; @@ -1181,7 +1183,7 @@ public abstract class AbstractSelect extends AbstractField implements switch (getItemCaptionMode()) { case ID: - caption = itemId.toString(); + caption = idToCaption(itemId); break; case INDEX: @@ -1207,7 +1209,7 @@ public abstract class AbstractSelect extends AbstractField implements case EXPLICIT_DEFAULTS_ID: caption = itemCaptions.get(itemId); if (caption == null) { - caption = itemId.toString(); + caption = idToCaption(itemId); } break; @@ -1227,6 +1229,17 @@ public abstract class AbstractSelect extends AbstractField implements return caption != null ? caption : ""; } + private String idToCaption(Object itemId) { + try { + Converter c = (Converter) ConverterUtil + .getConverter(String.class, itemId.getClass(), getSession()); + return ConverterUtil.convertFromModel(itemId, String.class, c, + getLocale()); + } catch (Exception e) { + return itemId.toString(); + } + } + /** * Sets tqhe icon for an item. * diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java index 6b517e9887..252efe2824 100644 --- a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java +++ b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java @@ -19,6 +19,7 @@ import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.WebElement; +import com.vaadin.data.util.converter.StringToEnumConverter; import com.vaadin.shared.ui.ui.NotificationRole; import com.vaadin.testbench.By; import com.vaadin.testbench.elements.ButtonElement; @@ -57,7 +58,8 @@ public class NotificationsWaiAriaTest extends MultiBrowserTest { postfix.clear(); postfix.sendKeys("- press ESC to close"); - type.selectByText(NotificationRole.ALERT.toString()); + type.selectByText(StringToEnumConverter.enumToString( + NotificationRole.ALERT, null)); show.click(); waitForElementPresent(By.className("v-Notification")); @@ -83,7 +85,8 @@ public class NotificationsWaiAriaTest extends MultiBrowserTest { } catch (Exception e) { } - type.selectByText("STATUS"); + type.selectByText(StringToEnumConverter.enumToString( + NotificationRole.STATUS, null)); show.click(); waitForElementPresent(By.className("v-Notification")); diff --git a/uitest/src/com/vaadin/tests/components/select/EnumSelect.java b/uitest/src/com/vaadin/tests/components/select/EnumSelect.java new file mode 100644 index 0000000000..5976952f8c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/select/EnumSelect.java @@ -0,0 +1,69 @@ +/* + * 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.select; + +import java.util.Locale; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.combobox.FilteringMode; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.Tree; + +public class EnumSelect extends AbstractTestUIWithLog { + + public enum Constant { + SOME_VALUE, SOME_OTHER_VALUE, FOO, BAR; + } + + @Override + protected void setup(VaadinRequest request) { + + setLocale(new Locale("fi", "FI")); + ComboBox cb = new ComboBox(); + cb.setFilteringMode(FilteringMode.CONTAINS); + for (Constant c : Constant.values()) { + cb.addItem(c); + } + addComponent(cb); + + NativeSelect ns = new NativeSelect(); + for (Constant c : Constant.values()) { + ns.addItem(c); + } + addComponent(ns); + + Tree t = new Tree(); + t.addItem(Constant.SOME_OTHER_VALUE); + t.addItem(2500.12); + t.setParent(2500.12, Constant.SOME_OTHER_VALUE); + + addComponent(t); + + } + + @Override + protected String getTestDescription() { + return "Test formatting captions with enum converters in selection components"; + } + + @Override + protected Integer getTicketNumber() { + return 11433; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/select/EnumSelectTest.java b/uitest/src/com/vaadin/tests/components/select/EnumSelectTest.java new file mode 100644 index 0000000000..c0429baa31 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/select/EnumSelectTest.java @@ -0,0 +1,61 @@ +/* + * 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.select; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.ComboBoxElement; +import com.vaadin.testbench.elements.NativeSelectElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class EnumSelectTest extends SingleBrowserTest { + + @Test + public void enumInNativeSelect() { + openTestURL(); + NativeSelectElement ns = $(NativeSelectElement.class).first(); + List options = ns.getOptions(); + Assert.assertEquals("Some value", options.get(1).getText()); + Assert.assertEquals("Some other value", options.get(2).getText()); + } + + @Test + public void enumInComboBox() { + openTestURL(); + ComboBoxElement cb = $(ComboBoxElement.class).first(); + cb.openPopup(); + List options = cb.getPopupSuggestions(); + Assert.assertEquals("Some value", options.get(1)); + Assert.assertEquals("Some other value", options.get(2)); + } + + @Test + public void enumInComboBoxFiltering() { + openTestURL(); + ComboBoxElement cb = $(ComboBoxElement.class).first(); + cb.findElement(By.vaadin("#textbox")).sendKeys(" other "); + List options = cb.getPopupSuggestions(); + Assert.assertEquals("Only one item should match filter", 1, + options.size()); + Assert.assertEquals("Invalid option matched filter", + "Some other value", options.get(0)); + } +} -- cgit v1.2.3 From eaa5328054cf197e4c8192dd6c2e2fca37f1589d Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Mon, 10 Nov 2014 20:26:02 +0200 Subject: Use ComboBox locale for filtering case tranform (#15193) Change-Id: Id462c3e76c8d761c04851227c949a3124ddf14b3 --- server/src/com/vaadin/ui/ComboBox.java | 4 +- .../combobox/FilteringTurkishLocale.java | 57 +++++++++++++++ .../combobox/FilteringTurkishLocaleTest.java | 80 ++++++++++++++++++++++ 3 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocale.java create mode 100644 uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocaleTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/com/vaadin/ui/ComboBox.java index c2b80fae35..4af93113f9 100644 --- a/server/src/com/vaadin/ui/ComboBox.java +++ b/server/src/com/vaadin/ui/ComboBox.java @@ -622,7 +622,7 @@ public class ComboBox extends AbstractSelect implements if (caption == null || caption.equals("")) { continue; } else { - caption = caption.toLowerCase(); + caption = caption.toLowerCase(getLocale()); } switch (filteringMode) { case CONTAINS: @@ -682,7 +682,7 @@ public class ComboBox extends AbstractSelect implements currentPage = ((Integer) variables.get("page")).intValue(); filterstring = newFilter; if (filterstring != null) { - filterstring = filterstring.toLowerCase(); + filterstring = filterstring.toLowerCase(getLocale()); } requestRepaint(); } else if (isNewItemsAllowed()) { diff --git a/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocale.java b/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocale.java new file mode 100644 index 0000000000..ff7faf1965 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocale.java @@ -0,0 +1,57 @@ +/* + * 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.combobox; + +import java.util.Arrays; +import java.util.Locale; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.NativeSelect; + +public class FilteringTurkishLocale extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + + final ComboBox comboBox = new ComboBox("Box", Arrays.asList( + "I without dot", "İ with dot")); + comboBox.setNullSelectionAllowed(false); + + NativeSelect localeSelect = new NativeSelect("Locale", Arrays.asList( + Locale.ENGLISH, new Locale("tr"))); + localeSelect.addValueChangeListener(new ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + comboBox.setLocale((Locale) event.getProperty().getValue()); + } + }); + localeSelect.setValue(Locale.ENGLISH); + + addComponents(localeSelect, comboBox); + } + + @Override + public String getDescription() { + return "When the Turkish locale is used," + + " filtering for 'i' should show the option with a dot" + + " while filtering for 'ı' should show the option witout a dot"; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocaleTest.java b/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocaleTest.java new file mode 100644 index 0000000000..d7f8e233ec --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocaleTest.java @@ -0,0 +1,80 @@ +/* + * 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.combobox; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ComboBoxElement; +import com.vaadin.testbench.elements.NativeSelectElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class FilteringTurkishLocaleTest extends MultiBrowserTest { + + @Test + public void testEnglishLocale() { + openTestURL(); + + setLocale("en"); + + List suggestions = getFilterSuggestions("i"); + + Assert.assertEquals("Both suggestions should be present", 2, + suggestions.size()); + } + + @Test + public void testTurkishLocaleWithDot() { + openTestURL(); + + setLocale("tr"); + + List suggestions = getFilterSuggestions("i"); + + Assert.assertEquals("There should be only one suggestion", 1, + suggestions.size()); + Assert.assertEquals("İ with dot", suggestions.get(0)); + } + + @Test + public void testTurkishLocaleWithoutDot() { + openTestURL(); + + setLocale("tr"); + + List suggestions = getFilterSuggestions("ı"); + + Assert.assertEquals("There should be only one suggestion", 1, + suggestions.size()); + Assert.assertEquals("I without dot", suggestions.get(0)); + } + + private List getFilterSuggestions(String string) { + ComboBoxElement comboBox = $(ComboBoxElement.class).first(); + comboBox.findElement(By.vaadin("#textbox")).sendKeys(string); + + return comboBox.getPopupSuggestions(); + } + + private void setLocale(String locale) { + NativeSelectElement selector = $(NativeSelectElement.class).first(); + selector.selectByText(locale); + } + +} -- cgit v1.2.3 From f341dac68a5c47049431b5e857e710c6b0d985e0 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Sun, 14 Dec 2014 15:06:42 +0200 Subject: Fix push test broken by new StringToEnumConverter Change-Id: I76885f3254ec28574ac637905af13cba1a9d2b41 --- .../vaadin/tests/push/PushConfigurationLongPollingTest.java | 8 ++------ .../vaadin/tests/push/PushConfigurationStreamingTest.java | 9 ++++----- uitest/src/com/vaadin/tests/push/PushConfigurationTest.java | 12 ++++++------ .../vaadin/tests/push/PushConfigurationWebSocketTest.java | 5 ++--- uitest/src/com/vaadin/tests/push/PushConfigurator.java | 11 ++++------- 5 files changed, 18 insertions(+), 27 deletions(-) (limited to 'uitest/src/com/vaadin/tests') diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java index a04d569e05..1d5ead7d98 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java @@ -18,11 +18,7 @@ package com.vaadin.tests.push; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; -import java.util.List; - import org.junit.Test; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.support.ui.Select; public class PushConfigurationLongPollingTest extends PushConfigurationTest { @@ -30,13 +26,13 @@ public class PushConfigurationLongPollingTest extends PushConfigurationTest { public void testLongPolling() throws InterruptedException { openDebugLogTab(); - new Select(getTransportSelect()).selectByVisibleText("LONG_POLLING"); + getTransportSelect().selectByText("Long polling"); assertThat(getStatusText(), containsString("fallbackTransport: long-polling")); assertThat(getStatusText(), containsString("transport: long-polling")); clearDebugMessages(); - new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC"); + getPushModeSelect().selectByText("Automatic"); waitForDebugMessage("Push connection established using long-polling", 10); waitForServerCounterToUpdate(); diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java index f5c015ad12..202db8d6b7 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java @@ -15,25 +15,24 @@ */ package com.vaadin.tests.push; -import org.junit.Test; -import org.openqa.selenium.support.ui.Select; - import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; +import org.junit.Test; + public class PushConfigurationStreamingTest extends PushConfigurationTest { @Test public void testStreaming() throws InterruptedException { openDebugLogTab(); - new Select(getTransportSelect()).selectByVisibleText("STREAMING"); + getTransportSelect().selectByText("Streaming"); assertThat(getStatusText(), containsString("fallbackTransport: long-polling")); assertThat(getStatusText(), containsString("transport: streaming")); clearDebugMessages(); - new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC"); + getPushModeSelect().selectByText("Automatic"); waitForDebugMessage("Push connection established using streaming", 10); waitForServerCounterToUpdate(); diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java index bb5b420259..396160cc7d 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java @@ -20,8 +20,8 @@ import static org.junit.Assert.assertEquals; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedCondition; -import org.openqa.selenium.support.ui.Select; +import com.vaadin.testbench.elements.NativeSelectElement; import com.vaadin.tests.annotations.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @@ -49,7 +49,7 @@ abstract class PushConfigurationTest extends MultiBrowserTest { } protected void disablePush() throws InterruptedException { - new Select(getPushModeSelect()).selectByVisibleText("DISABLED"); + getPushModeSelect().selectByText("Disabled"); int counter = getServerCounter(); sleep(2000); @@ -57,12 +57,12 @@ abstract class PushConfigurationTest extends MultiBrowserTest { getServerCounter()); } - protected WebElement getPushModeSelect() { - return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]"); + protected NativeSelectElement getPushModeSelect() { + return $(NativeSelectElement.class).caption("Push mode").first(); } - protected WebElement getTransportSelect() { - return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[1]/VNativeSelect[0]/domChild[0]"); + protected NativeSelectElement getTransportSelect() { + return $(NativeSelectElement.class).caption("Transport").first(); } protected int getServerCounter() { diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java index c9a813fac0..475fa2165f 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java @@ -23,7 +23,6 @@ import java.util.List; import org.junit.Test; import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.support.ui.Select; public class PushConfigurationWebSocketTest extends PushConfigurationTest { @@ -40,8 +39,8 @@ public class PushConfigurationWebSocketTest extends PushConfigurationTest { @Test public void testWebsocket() throws InterruptedException { - new Select(getTransportSelect()).selectByVisibleText("WEBSOCKET"); - new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC"); + getTransportSelect().selectByText("Websocket"); + getPushModeSelect().selectByText("Automatic"); assertThat(getStatusText(), containsString("fallbackTransport: long-polling")); diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurator.java b/uitest/src/com/vaadin/tests/push/PushConfigurator.java index 5a45ab7206..7da58af1da 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurator.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurator.java @@ -87,11 +87,9 @@ public class PushConfigurator extends VerticalLayout { pushMode.addItem(PushMode.AUTOMATIC); for (Transport t : Transport.values()) { - transport.addItem(t.toString()); - fallbackTransport.addItem(t.toString()); + transport.addItem(t); + fallbackTransport.addItem(t); } - transport.addItem(""); - fallbackTransport.addItem(""); pushMode.setImmediate(true); transport.setImmediate(true); @@ -124,7 +122,7 @@ public class PushConfigurator extends VerticalLayout { transport.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { - Transport t = Transport.valueOf((String) transport.getValue()); + Transport t = (Transport) transport.getValue(); ui.getPushConfiguration().setTransport(t); refreshStatus(); } @@ -133,8 +131,7 @@ public class PushConfigurator extends VerticalLayout { fallbackTransport.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { - Transport t = Transport.valueOf((String) fallbackTransport - .getValue()); + Transport t = (Transport) fallbackTransport.getValue(); ui.getPushConfiguration().setFallbackTransport(t); refreshStatus(); } -- cgit v1.2.3 From 60ddbbf566607cef5a67d35252c62629261933df Mon Sep 17 00:00:00 2001 From: Anna Miroshnik Date: Fri, 14 Nov 2014 13:46:12 +0300 Subject: Delayed column layouting is visible (#15189) Full Name of defect: Regression: Table column jumps when table is shown and table is contained in a layout Regression is a outcome of change due to #12672. No TB4 test because problem happens too fast to be caught. Change-Id: I9af5ed3c11e0fb673c7f2f1c5fd4739bd4b8c655 --- .../AbstractOrderedLayoutConnector.java | 15 +---- .../components/table/DelayedColumnLayouting.java | 72 ++++++++++++++++++++++ 2 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/table/DelayedColumnLayouting.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java index aace349392..0c09ae49c6 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java @@ -152,20 +152,7 @@ public abstract class AbstractOrderedLayoutConnector extends public void onElementResize(ElementResizeEvent e) { updateLayoutHeight(); if (needsExpand()) { - /* - * updateLayoutHeight causes calling of - * getLayoutManager().setNeedsMeasure(this) which informs this - * LayoutManager that the size of a component might have - * changed. Then a new layout phase is scheduled. So - * updateExpandCompensation must be delayed until layout phase - * will be completed. #12672 - */ - Scheduler.get().scheduleFinally(new ScheduledCommand() { - @Override - public void execute() { - getWidget().updateExpandCompensation(); - } - }); + getWidget().updateExpandCompensation(); } } }; diff --git a/uitest/src/com/vaadin/tests/components/table/DelayedColumnLayouting.java b/uitest/src/com/vaadin/tests/components/table/DelayedColumnLayouting.java new file mode 100644 index 0000000000..c327ddb6f3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/DelayedColumnLayouting.java @@ -0,0 +1,72 @@ +/* + * 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.table; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Table; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +/** + * For tables that are contained in a layout, a delayed column layouting should + * not be visible (because it makes the column jump around). + * + * #15189 + * + * @author Vaadin Ltd + */ +public class DelayedColumnLayouting extends UI { + + @Override + protected void init(VaadinRequest request) { + VerticalLayout verticalLayout = new VerticalLayout(); + verticalLayout.setSizeFull(); + final VerticalLayout layout = new VerticalLayout(); + layout.setSizeFull(); + layout.setSpacing(true); + + Button reset = new Button("Recreate layout with contained table"); + verticalLayout.addComponent(reset); + reset.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + fillLayout(layout); + } + }); + + fillLayout(layout); + + verticalLayout.addComponent(layout); + verticalLayout.setExpandRatio(layout, 1f); + + setContent(verticalLayout); + } + + private void fillLayout(VerticalLayout layout) { + layout.removeAllComponents(); + + Table table = new Table(); + table.setSizeFull(); + table.addContainerProperty("First", String.class, ""); + table.addContainerProperty("This column jumps", String.class, ""); + + layout.addComponent(table); + layout.setExpandRatio(table, 1f); + } +} \ No newline at end of file -- cgit v1.2.3 From 8c8ce29d6a6b3b1698cf28dd0e3a711d94f3bf25 Mon Sep 17 00:00:00 2001 From: Anna Miroshnik Date: Thu, 11 Dec 2014 18:22:42 +0300 Subject: Back button doesn't change URL if view blocks the navigation (#10901) Change-Id: Ib1211a7a2282753b329129615a544264e62d1ed5 --- server/src/com/vaadin/navigator/Navigator.java | 7 ++ .../NavigatorViewBlocksBackButtonAction.java | 128 +++++++++++++++++++++ .../NavigatorViewBlocksBackButtonActionTest.java | 95 +++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonAction.java create mode 100644 uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/navigator/Navigator.java b/server/src/com/vaadin/navigator/Navigator.java index 80dad2244e..591f73dc75 100644 --- a/server/src/com/vaadin/navigator/Navigator.java +++ b/server/src/com/vaadin/navigator/Navigator.java @@ -371,6 +371,7 @@ public class Navigator implements Serializable { private View currentView = null; private List listeners = new LinkedList(); private List providers = new LinkedList(); + private String currentNavigationState = null; private ViewProvider errorProvider; /** @@ -551,6 +552,11 @@ public class Navigator implements Serializable { ViewChangeEvent event = new ViewChangeEvent(this, currentView, view, viewName, parameters); if (!fireBeforeViewChange(event)) { + // #10901. Revert URL to previous state if back-button navigation + // was canceled + if (currentNavigationState != null) { + getStateManager().setState(currentNavigationState); + } return; } @@ -561,6 +567,7 @@ public class Navigator implements Serializable { } if (!navigationState.equals(getStateManager().getState())) { getStateManager().setState(navigationState); + currentNavigationState = navigationState; } } diff --git a/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonAction.java b/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonAction.java new file mode 100644 index 0000000000..5c78a3f42a --- /dev/null +++ b/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonAction.java @@ -0,0 +1,128 @@ +package com.vaadin.tests.navigator; + +import com.vaadin.navigator.Navigator; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; + +public class NavigatorViewBlocksBackButtonAction extends AbstractTestUI { + + private Navigator navigator; + + protected static final String LABEL_MAINVIEW_ID = "LABEL_MAINVIEW_ID"; + protected static final String LABEL_PROMPTEDVIEW_ID = "LABEL_PROMPTEDVIEW_ID"; + + @Override + protected void setup(VaadinRequest request) { + navigator = new Navigator(this, this); + navigator.addView(MainView.NAME, new MainView()); + navigator.addView(ViewWithPromptedLeave.NAME, + new ViewWithPromptedLeave()); + navigator.navigateTo(MainView.NAME); + } + + class MainView extends VerticalLayout implements View { + + public static final String NAME = "mainview"; + + public MainView() { + Label label = new Label("MainView content"); + label.setId(LABEL_MAINVIEW_ID); + addComponent(label); + + Button buttonNavToAnotherView = new Button( + "Navigate to another view", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + navigator.navigateTo(ViewWithPromptedLeave.NAME); + } + }); + addComponent(buttonNavToAnotherView); + } + + @Override + public void enter(ViewChangeEvent event) { + } + + } + + class ViewWithPromptedLeave extends VerticalLayout implements View, + ViewChangeListener { + + public static final String NAME = "prompted"; + + protected boolean okToLeave; + + public ViewWithPromptedLeave() { + Label label = new Label("ViewWithPromptedLeave content"); + label.setId(LABEL_PROMPTEDVIEW_ID); + addComponent(label); + addComponent(new Label( + "Try to navigate back to first view with browser back button.")); + } + + @Override + public void enter(ViewChangeEvent event) { + event.getNavigator().addViewChangeListener(this); + } + + @Override + public boolean beforeViewChange(final ViewChangeEvent event) { + if (okToLeave) { + okToLeave = false; + return true; + } else { + final Window confirmationWindow = new Window("Confirm"); + confirmationWindow.setModal(true); + confirmationWindow.setClosable(true); + + VerticalLayout confirmationWindowLayout = new VerticalLayout(); + confirmationWindow.setContent(confirmationWindowLayout); + confirmationWindowLayout.setMargin(true); + confirmationWindowLayout.setSpacing(true); + confirmationWindowLayout.addComponent(new Label( + "Really exit this view?")); + confirmationWindowLayout.addComponent(new Button("Yeah, sure!", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent buttonEvent) { + okToLeave = true; + getUI().removeWindow(confirmationWindow); + event.getNavigator().navigateTo( + event.getViewName() + "/" + + event.getParameters()); + } + })); + getUI().addWindow(confirmationWindow); + return false; + } + } + + @Override + public void afterViewChange(ViewChangeEvent event) { + if (event.getNewView() != this) { + event.getNavigator().removeViewChangeListener(this); + } + } + } + + @Override + protected String getTestDescription() { + return "URL should not be changed when view blocks navigating away from view using the browser's Back-button"; + } + + @Override + protected Integer getTicketNumber() { + return 10901; + } +} \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java b/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java new file mode 100644 index 0000000000..84abdca24b --- /dev/null +++ b/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java @@ -0,0 +1,95 @@ +/* + * 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.navigator; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class NavigatorViewBlocksBackButtonActionTest extends MultiBrowserTest { + + @Test + public void testIfConfirmBack() { + openTestURL(); + + // keep URL of main view + final String initialUrl = driver.getCurrentUrl(); + + // do it 2 times to verify that login is not broken after first time + for (int i = 0; i < 2; i++) { + // go to prompted view + WebElement button = $(ButtonElement.class).first(); + button.click(); + + // click back button + driver.navigate().back(); + + // confirm "go back by clicking confirm button + WebElement buttonConfirmView = $(ButtonElement.class).first(); + buttonConfirmView.click(); + + // verify we are in main view and url is correct + waitForElementPresent(By + .id(NavigatorViewBlocksBackButtonAction.LABEL_MAINVIEW_ID)); + String currentUrl = driver.getCurrentUrl(); + assertEquals( + "Current URL should be equal to initial main view URL", + initialUrl, currentUrl); + } + } + + @Test + public void testIfCancelBack() { + openTestURL(); + + // go to prompted view + WebElement button = $(ButtonElement.class).first(); + button.click(); + + // keep URL of prompted view + final String initialPromptedUrl = driver.getCurrentUrl(); + + // click back button + driver.navigate().back(); + + // verify url is correct (is not changed) + waitForElementPresent(By + .id(NavigatorViewBlocksBackButtonAction.LABEL_PROMPTEDVIEW_ID)); + String currentUrl = driver.getCurrentUrl(); + assertEquals( + "Current URL should be equal to initial prompted view URL", + initialPromptedUrl, currentUrl); + + WebElement cancelButton = driver.findElement(By + .className("v-window-closebox")); + + // click cancel button + cancelButton.click(); + + // verify we leave in prompted view and url is correct + waitForElementPresent(By + .id(NavigatorViewBlocksBackButtonAction.LABEL_PROMPTEDVIEW_ID)); + currentUrl = driver.getCurrentUrl(); + assertEquals( + "Current URL should be equal to initial prompted view URL", + initialPromptedUrl, currentUrl); + } +} -- cgit v1.2.3 From 1b211745b02fbff5d4084f5ccada07cff8c09c85 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Sat, 13 Dec 2014 21:42:54 +0200 Subject: Release session memory at the end of each test Change-Id: I30dd917158091f1fe6f16d050ff7d6037493d3ef --- server/src/com/vaadin/server/VaadinService.java | 8 ++++---- uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java | 12 +++++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'uitest/src/com/vaadin/tests') diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java index fb93a44d37..36d6910a7a 100644 --- a/server/src/com/vaadin/server/VaadinService.java +++ b/server/src/com/vaadin/server/VaadinService.java @@ -703,12 +703,12 @@ public abstract class VaadinService implements Serializable { final boolean closeApplication = hasParameter(request, URL_PARAMETER_CLOSE_APPLICATION); - if (restartApplication) { - closeSession(session, request.getWrappedSession(false)); - return createAndRegisterSession(request); - } else if (closeApplication) { + if (closeApplication) { closeSession(session, request.getWrappedSession(false)); return null; + } else if (restartApplication) { + closeSession(session, request.getWrappedSession(false)); + return createAndRegisterSession(request); } else { return session; } diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index 76b851fd23..b5a345bd30 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -32,7 +32,6 @@ import java.util.Collections; import java.util.List; import java.util.NoSuchElementException; -import com.vaadin.testbench.elements.TableElement; import org.apache.commons.io.IOUtils; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; @@ -69,6 +68,7 @@ import com.vaadin.testbench.TestBenchDriverProxy; import com.vaadin.testbench.TestBenchElement; import com.vaadin.testbench.TestBenchTestCase; import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.TableElement; import com.vaadin.testbench.elements.VerticalLayoutElement; import com.vaadin.tests.components.AbstractTestUIWithLog; import com.vaadin.tests.tb3.MultiBrowserTest.Browser; @@ -257,7 +257,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { @Override public Object apply(WebDriver input) { try { - return table.getCell(row, 0) != null; + return table.getCell(row, 0) != null; } catch (NoSuchElementException e) { return false; } @@ -266,7 +266,8 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } protected void scrollTable(TableElement table, int rows, int rowToWait) { - testBenchElement(table.findElement(By.className("v-scrollable"))).scroll(rows * 30); + testBenchElement(table.findElement(By.className("v-scrollable"))) + .scroll(rows * 30); waitUntilRowIsVisible(table, rowToWait); } @@ -430,6 +431,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { @After public void tearDown() throws Exception { if (driver != null) { + try { + openTestURL("&closeApplication"); + } catch (Exception e) { + e.printStackTrace(); + } driver.quit(); } driver = null; -- cgit v1.2.3