From 74dcb6f2478f611ce828a9fee7c7be52812af964 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 29 Nov 2013 16:53:05 +0200 Subject: Correct assertion message which changed due to #12915 Converted to TB3 to allow running on only one browser Change-Id: I8a0d20cfb5af798d8b89f3fca86ef7d9d7a37527 --- .../vaadin/launcher/ApplicationRunnerServlet.java | 2 +- .../applicationservlet/NoApplicationClass.html | 26 ------------ .../applicationservlet/NoApplicationClass.java | 49 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 27 deletions(-) delete mode 100644 uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.html create mode 100644 uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.java diff --git a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java index a2f3c59f07..47d3a19fde 100644 --- a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java +++ b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java @@ -280,7 +280,7 @@ public class ApplicationRunnerServlet extends LegacyVaadinServlet { } - throw new ClassNotFoundException(); + throw new ClassNotFoundException(baseName); } private Logger getLogger() { diff --git a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.html b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.html deleted file mode 100644 index 6ed410fdb6..0000000000 --- a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -New Test - - - - - - - - - - - - - - - - -
New Test
open/run/ClassThatIsNotPresent?restartApplication
assertText//pre[2]*java.lang.InstantiationException: Failed to load application class: ClassThatIsNotPresent*
- - diff --git a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.java b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.java new file mode 100644 index 0000000000..c2222c4608 --- /dev/null +++ b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2013 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.applicationservlet; + +import java.util.Collections; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class NoApplicationClass extends MultiBrowserTest { + + @Test + public void testInvalidApplicationClass() { + openTestURL(); + String exceptionMessage = getDriver().findElement(By.xpath("//pre[2]")) + .getText(); + Assert.assertTrue(exceptionMessage + .contains("ServletException: ClassThatIsNotPresent")); + } + + @Override + public List getBrowsersToTest() { + return Collections.singletonList(Browser.CHROME + .getDesiredCapabilities()); + } + + @Override + protected String getDeploymentPath() { + return "/run/ClassThatIsNotPresent"; + } +} -- cgit v1.2.3 From 12b6a8b42f3327e315e617e015304c4cc9dd4fa8 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Wed, 6 Nov 2013 17:17:42 +0200 Subject: Test for broken Webkit feature which causes extra scrollbars (#12736, #12727) This is the original cause for the Vaadin issues Live test at http://artur.virtuallypreinstalled.com/webkit-scrollbars.html Change-Id: Iaf9a46b635fabcb7cd795547c782c596aa57ce12 --- .../WebkitPositionAbsoluteScrollbars.html | 69 ++++++++++++++++++++++ .../WebkitPositionAbsoluteScrollbarsTest.java | 39 ++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 WebContent/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html create mode 100644 uitest/src/com/vaadin/tests/browserfeatures/WebkitPositionAbsoluteScrollbarsTest.java diff --git a/WebContent/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html b/WebContent/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html new file mode 100644 index 0000000000..7547816006 --- /dev/null +++ b/WebContent/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html @@ -0,0 +1,69 @@ + + + + + +
+ Starting point: No horizontal scrollbar
+ Expected: Get back to starting point after clicking through steps (do 1, do 2, cancel 1, cancel 2)
+ Actual: Scrollbars after doing the steps

+
+ + + + +
+
+
+
+
+
+
+
+ + + + + + diff --git a/uitest/src/com/vaadin/tests/browserfeatures/WebkitPositionAbsoluteScrollbarsTest.java b/uitest/src/com/vaadin/tests/browserfeatures/WebkitPositionAbsoluteScrollbarsTest.java new file mode 100644 index 0000000000..54fb7212ca --- /dev/null +++ b/uitest/src/com/vaadin/tests/browserfeatures/WebkitPositionAbsoluteScrollbarsTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2013 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.browserfeatures; + +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class WebkitPositionAbsoluteScrollbarsTest extends MultiBrowserTest { + + @Override + protected String getDeploymentPath() { + return "/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html"; + } + + @Test + public void testWebkitScrollbarProblem() throws Exception { + openTestURL(); + getDriver().findElement(By.id("step1")).click(); + getDriver().findElement(By.id("step2")).click(); + getDriver().findElement(By.id("step3")).click(); + getDriver().findElement(By.id("step4")).click(); + compareScreen("no-scrollbars"); + } +} -- cgit v1.2.3 From ea46029ea154cc018525219f06095817339607e8 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 29 Nov 2013 18:40:35 +0200 Subject: Allow excluding test from the standard test suite Mostly useful for very long running tests Change-Id: I9027f981da0a1e6ba464196449f2a9c27e965d2f --- .../src/com/vaadin/tests/tb3/ExcludeFromSuite.java | 28 ++++++++++++++++++++++ uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java | 18 ++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/tb3/ExcludeFromSuite.java diff --git a/uitest/src/com/vaadin/tests/tb3/ExcludeFromSuite.java b/uitest/src/com/vaadin/tests/tb3/ExcludeFromSuite.java new file mode 100644 index 0000000000..722b643f78 --- /dev/null +++ b/uitest/src/com/vaadin/tests/tb3/ExcludeFromSuite.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2013 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.tb3; + +/** + * Marker interface for a TB3+ test class which will exclude the test from any + * test suite which automatically scans for test classes. Mostly useful for long + * tests which should not be run in every build. + * + * @since 7.1.10 + * @author Vaadin Ltd + */ +public @interface ExcludeFromSuite { + +} diff --git a/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java index e1c8edfd60..f1576a9393 100644 --- a/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java +++ b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java @@ -223,6 +223,10 @@ public class TB3TestSuite extends Suite { if (!baseClass.isAssignableFrom(c)) { return; } + if (!includeInSuite(c)) { + return; + } + if (!Modifier.isAbstract(c.getModifiers()) && !c.isAnonymousClass()) { result.add((Class) c); } @@ -235,4 +239,18 @@ public class TB3TestSuite extends Suite { } + /** + * @return true if the class should be included in the suite, false if not + */ + private static boolean includeInSuite(Class c) { + if (c.getAnnotation(ExcludeFromSuite.class) != null) { + return false; + } + if (c == Object.class) { + return true; + } + + return includeInSuite(c.getSuperclass()); + } + } \ No newline at end of file -- cgit v1.2.3 From c171850a2c6fab38a81b2d0ab92d3433b2cf558c Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 29 Nov 2013 18:18:04 +0200 Subject: Disable client timeout so websockets are not disconnected when idle (#13015) Updated sleep method to ensure that long sleeps can be performed without losing the connection to the browser Change-Id: I4f29d946e7a9a400e303e3a574876e1bc2d56773 --- .../communication/AtmospherePushConnection.java | 12 +++++++ .../window/SubWindowsTextSelectionTest.java | 3 +- .../src/com/vaadin/tests/push/BasicPushTest.java | 2 +- .../tests/push/IdlePushChannelStreamingTest.java | 23 ++++++++++++++ .../com/vaadin/tests/push/IdlePushChannelTest.java | 37 ++++++++++++++++++++++ .../tests/push/IdlePushChannelWebsocketTest.java | 35 ++++++++++++++++++++ .../tests/push/PushLargeDataStreamingTest.java | 4 +-- .../tests/push/PushLargeDataWebsocketTest.java | 4 +-- .../src/com/vaadin/tests/push/TogglePushTest.java | 4 +-- .../src/com/vaadin/tests/tb3/AbstractTB3Test.java | 23 ++++++++++---- 10 files changed, 131 insertions(+), 16 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/push/IdlePushChannelStreamingTest.java create mode 100644 uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java create mode 100644 uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java index 320ba9ebe7..95584412cd 100644 --- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java +++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java @@ -348,6 +348,14 @@ public class AtmospherePushConnection implements PushConnection { state = State.CONNECT_PENDING; } + protected void onClientTimeout(AtmosphereResponse response) { + state = State.DISCONNECTED; + errorHandler + .onError( + "Client unexpectedly disconnected. Ensure client timeout is disabled.", + -1); + } + protected void onReconnect(JavaScriptObject request, final AtmosphereResponse response) { if (state == State.CONNECTED) { @@ -442,6 +450,7 @@ public class AtmospherePushConnection implements PushConnection { fallbackTransport: 'streaming', contentType: 'application/json; charset=UTF-8', reconnectInterval: 5000, + timeout: -1, maxReconnectOnClose: 10000000, trackMessageLength: true, enableProtocol: false, @@ -476,6 +485,9 @@ public class AtmospherePushConnection implements PushConnection { config.onReconnect = $entry(function(request, response) { self.@com.vaadin.client.communication.AtmospherePushConnection::onReconnect(*)(request, response); }); + config.onClientTimeout = $entry(function(request) { + self.@com.vaadin.client.communication.AtmospherePushConnection::onClientTimeout(*)(request); + }); return $wnd.jQueryVaadin.atmosphere.subscribe(config); }-*/; diff --git a/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java b/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java index 1df036af58..2e0873956c 100644 --- a/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java +++ b/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.components.window; -import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; @@ -64,7 +63,7 @@ public class SubWindowsTextSelectionTest extends MultiBrowserTest { } @Test - public void verifyNoTextSelectionOnMove() throws MalformedURLException { + public void verifyNoTextSelectionOnMove() throws Exception { openTestURL(); diff --git a/uitest/src/com/vaadin/tests/push/BasicPushTest.java b/uitest/src/com/vaadin/tests/push/BasicPushTest.java index ef40ae09dc..e03262ca7e 100644 --- a/uitest/src/com/vaadin/tests/push/BasicPushTest.java +++ b/uitest/src/com/vaadin/tests/push/BasicPushTest.java @@ -25,7 +25,7 @@ import com.vaadin.tests.tb3.MultiBrowserTest; public abstract class BasicPushTest extends MultiBrowserTest { @Test - public void testPush() { + public void testPush() throws InterruptedException { openTestURL(); // Test client initiated push diff --git a/uitest/src/com/vaadin/tests/push/IdlePushChannelStreamingTest.java b/uitest/src/com/vaadin/tests/push/IdlePushChannelStreamingTest.java new file mode 100644 index 0000000000..f9a0a722e5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/IdlePushChannelStreamingTest.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2013 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.push; + +public class IdlePushChannelStreamingTest extends IdlePushChannelTest { + @Override + protected Class getUIClass() { + return BasicPushStreaming.class; + } +} diff --git a/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java b/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java new file mode 100644 index 0000000000..4dcc8a680d --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2013 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.push; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public abstract class IdlePushChannelTest extends MultiBrowserTest { + + private static final int SEVEN_MINUTES_IN_MS = 7 * 60 * 1000; + + @Test + public void longWaitBetweenActions() throws Exception { + openTestURL(); + BasicPushTest.getIncrementButton(this).click(); + Assert.assertEquals(1, BasicPushTest.getClientCounter(this)); + sleep(SEVEN_MINUTES_IN_MS); + BasicPushTest.getIncrementButton(this).click(); + Assert.assertEquals(2, BasicPushTest.getClientCounter(this)); + } + +} diff --git a/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java b/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java new file mode 100644 index 0000000000..3fd9c616fb --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2013 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.push; + +import java.util.List; + +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.tests.tb3.WebsocketTest; + +public class IdlePushChannelWebsocketTest extends IdlePushChannelTest { + + @Override + protected Class getUIClass() { + return BasicPushWebsocket.class; + } + + @Override + public List getBrowsersToTest() { + return WebsocketTest.getWebsocketBrowsers(); + } +} diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java index 8f10f0fbba..0d71c21118 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java @@ -24,7 +24,7 @@ import com.vaadin.tests.tb3.MultiBrowserTest; public class PushLargeDataStreamingTest extends MultiBrowserTest { @Test - public void testStreamingLargeData() { + public void testStreamingLargeData() throws InterruptedException { openTestURL(); // Without this there is a large chance that we will wait for all pushes @@ -38,7 +38,7 @@ public class PushLargeDataStreamingTest extends MultiBrowserTest { } - private void push() { + private void push() throws InterruptedException { // Wait for startButton to be present waitForElementToBePresent(vaadinLocatorById("startButton")); diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java index 70a94f743e..cc8668a729 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java @@ -24,7 +24,7 @@ import com.vaadin.tests.tb3.WebsocketTest; public class PushLargeDataWebsocketTest extends WebsocketTest { @Test - public void testWebsocketLargeData() { + public void testWebsocketLargeData() throws Exception { openTestURL(); // Without this timing will be completly off as pushing "start" can @@ -38,7 +38,7 @@ public class PushLargeDataWebsocketTest extends WebsocketTest { } - private void push() { + private void push() throws Exception { // Wait for startButton to be present waitForElementToBePresent(vaadinLocatorById("startButton")); diff --git a/uitest/src/com/vaadin/tests/push/TogglePushTest.java b/uitest/src/com/vaadin/tests/push/TogglePushTest.java index 68d6f52b9f..1867f4a63a 100644 --- a/uitest/src/com/vaadin/tests/push/TogglePushTest.java +++ b/uitest/src/com/vaadin/tests/push/TogglePushTest.java @@ -24,7 +24,7 @@ import com.vaadin.tests.tb3.MultiBrowserTest; public class TogglePushTest extends MultiBrowserTest { @Test - public void togglePushInInit() { + public void togglePushInInit() throws Exception { setPush(true); String url = getTestUrl(); @@ -58,7 +58,7 @@ public class TogglePushTest extends MultiBrowserTest { } @Test - public void togglePush() { + public void togglePush() throws InterruptedException { setPush(true); openTestURL(); getDelayedCounterUpdateButton().click(); diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index d7b7cd050f..f6fce18fae 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -74,6 +74,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { */ private static final int SCREENSHOT_WIDTH = 1500; + /** + * Timeout used by the TB grid + */ + private static final int BROWSER_TIMEOUT_IN_MS = 30 * 1000; + private DesiredCapabilities desiredCapabilities; private boolean debug = false; @@ -641,17 +646,21 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } /** - * Helper method for sleeping X ms in a test. Catches and ignores - * InterruptedExceptions + * Sleeps for the given number of ms but ensures that the browser connection + * does not time out. * * @param timeoutMillis * Number of ms to wait + * @throws InterruptedException */ - protected void sleep(int timeoutMillis) { - try { - Thread.sleep(timeoutMillis); - } catch (InterruptedException e) { - throw new RuntimeException(e); + protected void sleep(int timeoutMillis) throws InterruptedException { + while (timeoutMillis > 0) { + int d = Math.min(BROWSER_TIMEOUT_IN_MS, timeoutMillis); + Thread.sleep(d); + timeoutMillis -= d; + + // Do something to keep the connection alive + getDriver().getTitle(); } } -- cgit v1.2.3 From 36fce654841a5bf82a6be765930db07892e374fb Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 29 Nov 2013 19:10:19 +0200 Subject: Test for pushing for an extended period of time (24h) Change-Id: I8e47ba926f41fdc103cfa72ba85ca2f9edbc57d0 --- .../vaadin/tests/push/ExtremelyLongPushTime.java | 50 ++++++++++++++++ .../tests/push/ExtremelyLongPushTimeStreaming.java | 33 +++++++++++ .../push/ExtremelyLongPushTimeStreamingTest.java | 21 +++++++ .../tests/push/ExtremelyLongPushTimeTest.java | 67 ++++++++++++++++++++++ .../tests/push/ExtremelyLongPushTimeWebsocket.java | 34 +++++++++++ .../push/ExtremelyLongPushTimeWebsocketTest.java | 31 ++++++++++ .../src/com/vaadin/tests/push/PushLargeData.java | 12 +++- 7 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/push/ExtremelyLongPushTime.java create mode 100644 uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreaming.java create mode 100644 uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreamingTest.java create mode 100644 uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java create mode 100644 uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocket.java create mode 100644 uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTime.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTime.java new file mode 100644 index 0000000000..d90394d3b5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTime.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2013 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.push; + +import com.vaadin.server.VaadinRequest; + +public abstract class ExtremelyLongPushTime extends PushLargeData { + + private static final int DURATION_MS = 48 * 60 * 60 * 1000; // 48 H + private static int INTERVAL_MS = 60 * 1000; // 1 minute + private static int PAYLOAD_SIZE = 100 * 1024; // 100 KB + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + super.setup(request); + duration.setConvertedValue(DURATION_MS); + interval.setConvertedValue(INTERVAL_MS); + dataSize.setConvertedValue(PAYLOAD_SIZE); + } + + @Override + protected String getTestDescription() { + return "Test which pushes data every minute for 48 hours"; + } + + @Override + protected Integer getTicketNumber() { + return null; + } + +} diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreaming.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreaming.java new file mode 100644 index 0000000000..3e9582740d --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreaming.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2013 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.push; + +import com.vaadin.annotations.Push; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.ui.Transport; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; + +@Push(transport = Transport.STREAMING) +public class ExtremelyLongPushTimeStreaming extends ExtremelyLongPushTime { + + @Override + public void init(VaadinRequest request) { + super.init(request); + // Don't use fallback so we can easier detect failures + getPushConfiguration().setParameter( + PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + } +} diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreamingTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreamingTest.java new file mode 100644 index 0000000000..17837cb2d3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreamingTest.java @@ -0,0 +1,21 @@ +/* + * Copyright 2000-2013 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.push; + +public class ExtremelyLongPushTimeStreamingTest extends + ExtremelyLongPushTimeTest { + +} diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java new file mode 100644 index 0000000000..56eb8b6929 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2013 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.push; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.support.ui.ExpectedConditions; + +import com.vaadin.tests.tb3.ExcludeFromSuite; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@ExcludeFromSuite +public abstract class ExtremelyLongPushTimeTest extends MultiBrowserTest { + + private static final int ONE_HOUR_IN_MS = 20 * 1000; + + @Test + public void test24HourPush() { + openTestURL(); + + // Without this there is a large chance that we will wait for all pushes + // to complete before moving on + testBench(driver).disableWaitForVaadin(); + + // Wait for startButton to be present + waitForElementToBePresent(vaadinLocatorById("startButton")); + + String logRow0Id = "Log_row_0"; + By logRow0 = vaadinLocatorById(logRow0Id); + + // Start the test + vaadinElementById("startButton").click(); + + // Wait for push to start. Should take 60s + waitUntil(ExpectedConditions.textToBePresentInElement(logRow0, + "Package "), 120); + + // Check every hour that push is still going on + for (int i = 0; i < 24; i++) { + sleep(ONE_HOUR_IN_MS); + ensureStillPushing(logRow0); + } + + } + + private void ensureStillPushing(By logRow0) { + String logValue = getDriver().findElement(logRow0).getText(); + // Wait for the log value to change. Should take max 60s + waitUntilNot( + ExpectedConditions.textToBePresentInElement(logRow0, logValue), + 120); + } + +} diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocket.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocket.java new file mode 100644 index 0000000000..8346d49234 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocket.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2013 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.push; + +import com.vaadin.annotations.Push; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.ui.Transport; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; + +@Push(transport = Transport.WEBSOCKET) +public class ExtremelyLongPushTimeWebsocket extends ExtremelyLongPushTime { + + @Override + public void init(VaadinRequest request) { + super.init(request); + // Don't use fallback so we can easier detect if websocket fails + getPushConfiguration().setParameter( + PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + } + +} diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java new file mode 100644 index 0000000000..23d773c7da --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2013 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.push; + +import java.util.List; + +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.tests.tb3.WebsocketTest; + +public class ExtremelyLongPushTimeWebsocketTest extends + ExtremelyLongPushTimeTest { + + @Override + public List getBrowsersToTest() { + return WebsocketTest.getWebsocketBrowsers(); + } +} diff --git a/uitest/src/com/vaadin/tests/push/PushLargeData.java b/uitest/src/com/vaadin/tests/push/PushLargeData.java index 3b72424b32..83f573ed2c 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeData.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeData.java @@ -51,14 +51,20 @@ public abstract class PushLargeData extends AbstractTestUIWithLog { private final ExecutorService executor = Executors .newSingleThreadExecutor(); + protected TextField dataSize; + + protected TextField interval; + + protected TextField duration; + @Override protected void setup(VaadinRequest request) { dataLabel.setSizeUndefined(); - final TextField dataSize = new TextField("Data size"); + dataSize = new TextField("Data size"); dataSize.setConverter(Integer.class); - final TextField interval = new TextField("Interval (ms)"); + interval = new TextField("Interval (ms)"); interval.setConverter(Integer.class); - final TextField duration = new TextField("Duration (ms)"); + duration = new TextField("Duration (ms)"); duration.setConverter(Integer.class); dataSize.setValue(DEFAULT_SIZE_BYTES + ""); -- cgit v1.2.3 From 54a5667b2cebf6df7825d92c287112f6be64fe7d Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 2 Dec 2013 15:24:38 +0200 Subject: Fix compilation error Change-Id: Ib2ca104b8ab92a23a525c617004c6efe7f7edc14 --- uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java index 56eb8b6929..a1ce4b9d8f 100644 --- a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java @@ -28,7 +28,7 @@ public abstract class ExtremelyLongPushTimeTest extends MultiBrowserTest { private static final int ONE_HOUR_IN_MS = 20 * 1000; @Test - public void test24HourPush() { + public void test24HourPush() throws Exception { openTestURL(); // Without this there is a large chance that we will wait for all pushes -- cgit v1.2.3 From 25fc48c52067237faa208cea849a775a7aa1668c Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 15 Nov 2013 18:40:57 +0200 Subject: Do not throw NPE if conversion messages is null (#12962) Change-Id: Ie2b95ed4da89e2c5ab8b462300a6f4bd28dc7570 --- server/src/com/vaadin/ui/AbstractField.java | 17 +++++++++-------- .../abstractfield/AbsFieldValueConversionError.java | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java index 6a52d6b849..b96e331889 100644 --- a/server/src/com/vaadin/ui/AbstractField.java +++ b/server/src/com/vaadin/ui/AbstractField.java @@ -783,15 +783,16 @@ public abstract class AbstractField extends AbstractComponent implements ConversionException e) { String conversionError = getConversionError(); - if (dataSourceType != null) { - conversionError = conversionError.replace("{0}", - dataSourceType.getSimpleName()); - } - if (e != null) { - conversionError = conversionError.replace("{1}", - e.getLocalizedMessage()); + if (conversionError != null) { + if (dataSourceType != null) { + conversionError = conversionError.replace("{0}", + dataSourceType.getSimpleName()); + } + if (e != null) { + conversionError = conversionError.replace("{1}", + e.getLocalizedMessage()); + } } - return conversionError; } diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionError.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionError.java index ad762f8931..887f1b8ff3 100644 --- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionError.java +++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionError.java @@ -54,6 +54,21 @@ public class AbsFieldValueConversionError extends TestCase { } + public void testNullConversionMessages() { + TextField tf = new TextField(); + tf.setConverter(new StringToIntegerConverter()); + tf.setPropertyDataSource(new MethodProperty(paulaBean, "age")); + tf.setConversionError(null); + tf.setValue("abc"); + try { + tf.validate(); + fail(); + } catch (InvalidValueException e) { + Assert.assertEquals(null, e.getMessage()); + } + + } + public void testDefaultConversionErrorMessage() { TextField tf = new TextField(); tf.setConverter(new StringToIntegerConverter()); -- cgit v1.2.3 From 26b5b672df0aa3bdefdced81ed4619c11f3e945a Mon Sep 17 00:00:00 2001 From: Henrik Paul Date: Tue, 26 Nov 2013 14:49:12 +0200 Subject: Timeout redirect timer is reset on server activity (#12446) Change-Id: Iec2e3de627bc1cf5c7d39bf98715b1bf343e7519 --- WebContent/WEB-INF/web.xml | 15 ++++ .../com/vaadin/client/ApplicationConnection.java | 4 +- .../ui/TimeoutRedirectResetsOnActivity.java | 74 +++++++++++++++++++ .../ui/TimeoutRedirectResetsOnActivityTest.java | 85 ++++++++++++++++++++++ 4 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivity.java create mode 100644 uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 8a917966a1..f98b7c78d1 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -76,6 +76,16 @@ true + + + VaadinApplicationRunnerWithTimeoutRedirect + com.vaadin.launcher.ApplicationRunnerServlet + + VaadinApplicationRunnerWithPush com.vaadin.launcher.ApplicationRunnerServlet @@ -116,6 +126,11 @@ /run/* + + VaadinApplicationRunnerWithTimeoutRedirect + /12446/* + + VaadinApplicationRunnerWithPush /run-push/* diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index f95cec4fbc..a87fa3e342 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -64,7 +64,6 @@ import com.google.gwt.user.client.Window.ClosingHandler; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConfiguration.ErrorMessage; -import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent; import com.vaadin.client.ResourceLoader.ResourceLoadEvent; import com.vaadin.client.ResourceLoader.ResourceLoadListener; import com.vaadin.client.communication.HasJavaScriptConnectorHelper; @@ -1417,6 +1416,9 @@ public class ApplicationConnection { if (meta.containsKey("timedRedirect")) { final ValueMap timedRedirect = meta .getValueMap("timedRedirect"); + if (redirectTimer != null) { + redirectTimer.cancel(); + } redirectTimer = new Timer() { @Override public void run() { diff --git a/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivity.java b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivity.java new file mode 100644 index 0000000000..2c649c9ca8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivity.java @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2013 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.ui; + +import com.vaadin.server.CustomizedSystemMessages; +import com.vaadin.server.SystemMessages; +import com.vaadin.server.SystemMessagesInfo; +import com.vaadin.server.SystemMessagesProvider; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; + +public class TimeoutRedirectResetsOnActivity extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + setupTimout(request); + + addComponent(new Button("clicky", new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + // NOOP + } + })); + } + + private void setupTimout(VaadinRequest request) { + request.getService().setSystemMessagesProvider( + new SystemMessagesProvider() { + @Override + public SystemMessages getSystemMessages( + SystemMessagesInfo systemMessagesInfo) { + CustomizedSystemMessages msgs = new CustomizedSystemMessages(); + msgs.setSessionExpiredMessage(null); + msgs.setSessionExpiredCaption(null); + msgs.setSessionExpiredNotificationEnabled(true); + msgs.setSessionExpiredURL("http://example.com/"); + return msgs; + } + }); + /* + * NOTE: in practice, this means a timeout after 25 seconds, because of + * implementation details in + * com.vaadin.server.communication.MetadataWriter + */ + getSession().getSession().setMaxInactiveInterval(10); + } + + @Override + protected String getTestDescription() { + return "The timeout redirect timer should reset if there's activity between the client and server."; + } + + @Override + @SuppressWarnings("boxing") + protected Integer getTicketNumber() { + return 12446; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java new file mode 100644 index 0000000000..272bacb8d5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2013 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.ui; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class TimeoutRedirectResetsOnActivityTest extends MultiBrowserTest { + @Test + public void verifyRedirectWorks() throws Exception { + setDebug(true); + openTestURL(); + + long startTime = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTime < 30000) { + clickTheButton(); + Thread.sleep(1000); + } + + assertTrue("button disappeared before timeout", buttonIsStillThere()); + + Thread.sleep(30000); + assertTrue("no redirection occurred within 30 seconds", + !buttonIsStillThere()); + } + + private boolean buttonIsStillThere() { + try { + return getButton() != null; + } catch (NoSuchElementException e) { + return false; + } + } + + private void clickTheButton() { + getButton().click(); + } + + private WebElement getButton() { + /* + * For some reason, the vaadinElement() method doesn't work when tests + * are run outside of "/run/" and "/run-push/" contexts. The given error + * message says that the generated Vaadin path doesn't match any + * elements, but when that selector is put into the recorder, the + * recorder finds it. + * + * XPath works fine. + */ + /*- + return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]"); + */ + return getDriver().findElement( + By.xpath("//div[contains(@class,'v-button')]")); + } + + @Override + protected String getDeploymentPath() { + /* + * AbstractTB3Test assumes only /run/ and /run-push/ contexts, so this + * method needs some overriding. + */ + return "/12446/" + + TimeoutRedirectResetsOnActivity.class.getCanonicalName() + + "?restartApplication&debug"; + } +} -- cgit v1.2.3 From d45785d6763f269b4e00460ace07ab47c712b5ca Mon Sep 17 00:00:00 2001 From: Felype Santiago Ferreira Date: Mon, 28 Oct 2013 11:50:18 +0200 Subject: Fixes right click selection focus issues in Tree. (#12618) Change-Id: I1057424fc8956b05e15a92c32e48a767e9fc8df9 --- .../com/vaadin/client/ui/tree/TreeConnector.java | 20 ++++++- .../components/tree/TreeScrollingOnRightClick.java | 53 +++++++++++++++++ .../tree/TreeScrollingOnRightClickTest.java | 69 ++++++++++++++++++++++ 3 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClick.java create mode 100644 uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClickTest.java diff --git a/client/src/com/vaadin/client/ui/tree/TreeConnector.java b/client/src/com/vaadin/client/ui/tree/TreeConnector.java index ef016c31b7..7560a0f56b 100644 --- a/client/src/com/vaadin/client/ui/tree/TreeConnector.java +++ b/client/src/com/vaadin/client/ui/tree/TreeConnector.java @@ -18,6 +18,7 @@ package com.vaadin.client.ui.tree; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Set; import com.google.gwt.aria.client.Roles; import com.google.gwt.dom.client.Element; @@ -136,9 +137,24 @@ public class TreeConnector extends AbstractComponentConnector implements getWidget().lastSelection = getWidget().getNodeByKey( getWidget().lastSelection.key); } + if (getWidget().focusedNode != null) { - getWidget().setFocusedNode( - getWidget().getNodeByKey(getWidget().focusedNode.key)); + + Set selectedIds = getWidget().selectedIds; + + // If the focused node is not between the selected nodes, we need to + // refresh the focused node to prevent an undesired scroll. #12618. + if (!selectedIds.isEmpty() + && !selectedIds.contains(getWidget().focusedNode.key)) { + String keySelectedId = selectedIds.iterator().next(); + + TreeNode nodeToSelect = getWidget().getNodeByKey(keySelectedId); + + getWidget().setFocusedNode(nodeToSelect); + } else { + getWidget().setFocusedNode( + getWidget().getNodeByKey(getWidget().focusedNode.key)); + } } if (getWidget().lastSelection == null diff --git a/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClick.java b/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClick.java new file mode 100644 index 0000000000..8a2b263006 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClick.java @@ -0,0 +1,53 @@ +package com.vaadin.tests.components.tree; + +import com.vaadin.event.ItemClickEvent; +import com.vaadin.event.MouseEvents; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Tree; + +/** + * Test for #12618: Trying to select item with right click in Tree causes focus + * issues. + */ +@SuppressWarnings("serial") +public class TreeScrollingOnRightClick extends AbstractTestUI { + + public static final String TREE_ID = "my-tree"; + + @Override + protected void setup(VaadinRequest request) { + final Tree tree = new Tree(); + tree.setId(TREE_ID); + tree.setSizeUndefined(); + + // Add item click listener for right click selection + tree.addItemClickListener(new ItemClickEvent.ItemClickListener() { + @SuppressWarnings("deprecation") + @Override + public void itemClick(ItemClickEvent event) { + if (event.getButton() == MouseEvents.ClickEvent.BUTTON_RIGHT) { + tree.select(event.getItemId()); + } + } + }); + + // Add some items + for (int i = 0; i < 200; i++) { + tree.addItem(String.format("Node %s", i)); + } + + addComponent(tree); + } + + @Override + protected String getTestDescription() { + return "Right clicking on items should not scroll Tree."; + } + + @Override + protected Integer getTicketNumber() { + return 12618; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClickTest.java b/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClickTest.java new file mode 100644 index 0000000000..76ab1b3fdb --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClickTest.java @@ -0,0 +1,69 @@ +/* + * Copyright 2000-2013 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.tree; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * + * @since 7.1.9 + * @author Vaadin Ltd + */ +public class TreeScrollingOnRightClickTest extends MultiBrowserTest { + + @Test + public void testScrollingOnRightClick() throws Throwable { + openTestURL(); + + // Focus tree + WebElement tree = getDriver().findElement( + By.id(TreeScrollingOnRightClick.TREE_ID)); + tree.click(); + + // Move selection down 50 items + for (int down = 0; down < 50; down++) { + tree.sendKeys(Keys.ARROW_DOWN); + } + + Thread.sleep(1000); + + // Get location of item 40 + Point item40Location = getTreeNode("Node 40").getLocation(); + + // Right click on item 45 + WebElement item45 = getTreeNode("Node 45"); + new Actions(getDriver()).moveToElement(item45).contextClick(item45) + .perform(); + + // Ensure location of item 40 is still the same (no scrolling) + Point item40Location2 = getTreeNode("Node 40").getLocation(); + assertEquals(item40Location.getY(), item40Location2.getY()); + } + + private WebElement getTreeNode(String caption) { + return getDriver().findElement( + By.xpath("//span[text() = '" + caption + "']")); + } +} -- cgit v1.2.3