aboutsummaryrefslogtreecommitdiffstats
path: root/uitest/src/com/vaadin/tests
diff options
context:
space:
mode:
authorPatrik Lindström <patrik@vaadin.com>2013-10-11 14:23:52 +0300
committerPatrik Lindström <patrik@vaadin.com>2013-10-11 14:27:29 +0300
commitdf9a1192efeb49285cb1c4fc100bb60b5a77ac14 (patch)
treea89aea53ffd89943f8672a5ef8943da6579bdb92 /uitest/src/com/vaadin/tests
parentc2b81b20ca3a981b775ac5f16506861724119df4 (diff)
parent4cb304d8eb63ce0045a2742bd9c945af4f12aa66 (diff)
downloadvaadin-framework-df9a1192efeb49285cb1c4fc100bb60b5a77ac14.tar.gz
vaadin-framework-df9a1192efeb49285cb1c4fc100bb60b5a77ac14.zip
Merge remote-tracking branch 'origin/7.1' into testbench4
Change-Id: I58fe3b4126b61ec342ee06c18ce49a7fa7d4fd3d
Diffstat (limited to 'uitest/src/com/vaadin/tests')
-rw-r--r--uitest/src/com/vaadin/tests/VerifyBrowserVersion.java10
-rw-r--r--uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java66
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateFieldTestTest.java118
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.html10
-rw-r--r--uitest/src/com/vaadin/tests/components/label/LabelModes.html27
-rw-r--r--uitest/src/com/vaadin/tests/components/label/LabelModesTest.java30
-rw-r--r--uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.html54
-rw-r--r--uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.java70
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsg.java66
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsgTest.java49
-rw-r--r--uitest/src/com/vaadin/tests/components/panel/PanelChangeContentsTest.java53
-rw-r--r--uitest/src/com/vaadin/tests/components/slider/SliderDisable.java62
-rw-r--r--uitest/src/com/vaadin/tests/components/slider/SliderDisableTest.java36
-rw-r--r--uitest/src/com/vaadin/tests/components/table/EmptyTable.java58
-rw-r--r--uitest/src/com/vaadin/tests/components/table/EmptyTableTest.java44
-rw-r--r--uitest/src/com/vaadin/tests/components/table/ShowLastItem.html (renamed from uitest/src/com/vaadin/tests/push/PushFromInit.html)24
-rw-r--r--uitest/src/com/vaadin/tests/components/table/ShowLastItem.java66
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableMoveFocusWithSelection.java125
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableMoveFocusWithSelectionTest.java75
-rw-r--r--uitest/src/com/vaadin/tests/components/tabsheet/TabSheetHotKeysWithModifiers.java50
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/UIAccessTest.java204
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/UiAccess.html166
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/UiAccess.java361
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/UiAccessPush.html41
-rw-r--r--uitest/src/com/vaadin/tests/dd/DnDOnSubtree.html51
-rw-r--r--uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java53
-rw-r--r--uitest/src/com/vaadin/tests/integration/AbstractServletIntegrationTest.java63
-rw-r--r--uitest/src/com/vaadin/tests/integration/IntegrationTestRunner.java54
-rw-r--r--uitest/src/com/vaadin/tests/integration/ServletIntegrationStreamingUI.java30
-rw-r--r--uitest/src/com/vaadin/tests/integration/ServletIntegrationStreamingUITest.java21
-rwxr-xr-xuitest/src/com/vaadin/tests/integration/ServletIntegrationUI.java (renamed from uitest/src/com/vaadin/tests/integration/IntegrationTestUI.java)3
-rw-r--r--uitest/src/com/vaadin/tests/integration/ServletIntegrationUITest.java20
-rw-r--r--uitest/src/com/vaadin/tests/integration/ServletIntegrationWebsocketUI.java45
-rw-r--r--uitest/src/com/vaadin/tests/integration/ServletIntegrationWebsocketUITest.java21
-rw-r--r--uitest/src/com/vaadin/tests/push/BarInUIDL.html42
-rw-r--r--uitest/src/com/vaadin/tests/push/BarInUIDL.java3
-rw-r--r--uitest/src/com/vaadin/tests/push/BarInUIDLTest.java45
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPush.html88
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPush.java63
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushStreaming.java23
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushStreamingTest.java19
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushTest.java92
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushWebsocket.java24
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushWebsocketTest.java29
-rw-r--r--uitest/src/com/vaadin/tests/push/EnableDisablePush.html97
-rw-r--r--uitest/src/com/vaadin/tests/push/EnableDisablePush.java60
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfiguration.html130
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfiguration.java117
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurationTest.java181
-rw-r--r--uitest/src/com/vaadin/tests/push/PushFromInit.java15
-rw-r--r--uitest/src/com/vaadin/tests/push/PushFromInitTest.java50
-rw-r--r--uitest/src/com/vaadin/tests/push/PushReattachedComponent.html47
-rw-r--r--uitest/src/com/vaadin/tests/push/PushTransportAnnotation.html46
-rw-r--r--uitest/src/com/vaadin/tests/push/StreamingPush.html88
-rw-r--r--uitest/src/com/vaadin/tests/push/TogglePush.html91
-rw-r--r--uitest/src/com/vaadin/tests/push/TogglePush.java15
-rw-r--r--uitest/src/com/vaadin/tests/push/TogglePushInInit.html69
-rw-r--r--uitest/src/com/vaadin/tests/push/TogglePushTest.java112
-rw-r--r--uitest/src/com/vaadin/tests/push/TrackMessageSizeUI.java (renamed from uitest/src/com/vaadin/tests/push/TrackMessageSizeUnitTests.java)2
-rw-r--r--uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java30
-rw-r--r--uitest/src/com/vaadin/tests/push/TrackMessageSizeUnitTests.html26
-rw-r--r--uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java793
-rw-r--r--uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java42
-rw-r--r--uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java69
-rw-r--r--uitest/src/com/vaadin/tests/tb3/ParallelScheduler.java69
-rw-r--r--uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java135
-rw-r--r--uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java400
-rw-r--r--uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java35
-rw-r--r--uitest/src/com/vaadin/tests/tb3/SimpleMultiBrowserTest.java50
-rw-r--r--uitest/src/com/vaadin/tests/tb3/TB3Runner.java154
-rw-r--r--uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java238
-rw-r--r--uitest/src/com/vaadin/tests/tb3/WebsocketTest.java60
72 files changed, 4434 insertions, 1441 deletions
diff --git a/uitest/src/com/vaadin/tests/VerifyBrowserVersion.java b/uitest/src/com/vaadin/tests/VerifyBrowserVersion.java
index 022a343196..1b21f08aa7 100644
--- a/uitest/src/com/vaadin/tests/VerifyBrowserVersion.java
+++ b/uitest/src/com/vaadin/tests/VerifyBrowserVersion.java
@@ -9,9 +9,13 @@ public class VerifyBrowserVersion extends TestBase {
@Override
protected void setup() {
WebBrowser browser = getBrowser();
- addComponent(new Label(browser.getBrowserApplication()));
- addComponent(new Label("Touch device? "
- + (browser.isTouchDevice() ? "YES" : "No")));
+ Label userAgent = new Label(browser.getBrowserApplication());
+ userAgent.setId("userAgent");
+ addComponent(userAgent);
+ Label touchDevice = new Label("Touch device? "
+ + (browser.isTouchDevice() ? "YES" : "No"));
+ touchDevice.setId("touchDevice");
+ addComponent(touchDevice);
}
@Override
diff --git a/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java b/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java
new file mode 100644
index 0000000000..6704f55226
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import com.vaadin.tests.tb3.AbstractTB3Test.BrowserUtil;
+
+public class VerifyBrowserVersionTest extends MultiBrowserTest {
+
+ private Map<DesiredCapabilities, String> expectedUserAgent = new HashMap<DesiredCapabilities, String>();
+
+ {
+ expectedUserAgent
+ .put(BrowserUtil.firefox(24),
+ "Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0");
+ expectedUserAgent
+ .put(BrowserUtil.ie(8),
+ "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
+ expectedUserAgent
+ .put(BrowserUtil.ie(9),
+ "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
+ expectedUserAgent
+ .put(BrowserUtil.ie(10),
+ "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)");
+ expectedUserAgent
+ .put(BrowserUtil.ie(11),
+ "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko");
+ expectedUserAgent
+ .put(BrowserUtil.chrome(29),
+ "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36");
+ expectedUserAgent
+ .put(BrowserUtil.opera(12),
+ "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.15");
+
+ }
+
+ @Test
+ public void verifyUserAgent() {
+ openTestURL();
+ Assert.assertEquals(
+ expectedUserAgent.get(getDesiredCapabilities()),
+ vaadinElementById("userAgent").getText());
+ Assert.assertEquals("Touch device? No",
+ vaadinElementById("touchDevice").getText());
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldTestTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldTestTest.java
new file mode 100644
index 0000000000..557201e803
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldTestTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.datefield;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Dimension;
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class DateFieldTestTest extends MultiBrowserTest {
+
+ @Test
+ public void testMakingRequired() throws InterruptedException {
+ setDebug(true);
+ openTestURL();
+ Thread.sleep(1000);
+ menu("Component");
+ menuSub("State");
+ menu("Required");
+ assertNoErrorNotification();
+ }
+
+ private void assertNoErrorNotification() {
+ try {
+ getDriver().findElement(
+ By.xpath("//div[contains(@class, 'v-Notification') ]"));
+ Assert.fail("Error notification shown!");
+ } catch (NoSuchElementException e) {
+ // As expected
+ }
+ }
+
+ @Test
+ public void testValueAfterOpeningPopupInRequiredField()
+ throws InterruptedException {
+ setDebug(true);
+ openTestURL();
+ Thread.sleep(1000);
+ menu("Component");
+ menuSub("State");
+ menu("Required");
+
+ menu("Component");
+ menuSub("Features");
+ menuSub("Resolution");
+ menu("Month");
+
+ menu("Component");
+ menuSub("Listeners");
+ menu("Value change listener");
+
+ String inputtedValue = "2/12";
+ getInput().sendKeys(inputtedValue);
+
+ openPopup();
+ closePopup();
+ String actual = getInput().getAttribute("value");
+ Assert.assertEquals(inputtedValue, actual);
+ assertNoErrorNotification();
+
+ }
+
+ private void openPopup() throws InterruptedException {
+ Dimension size = getInput().getSize();
+ new Actions(getDriver()).moveToElement(getInput(), 0, 0)
+ .moveByOffset(size.getWidth() + 5, size.getHeight() / 2)
+ .click();
+ // This fails in Opera for some weird reason
+ // getDriver().findElement(By.className("v-datefield-button")).click();
+ }
+
+ private WebElement getInput() {
+ return getDriver().findElement(By.xpath("//input"));
+ }
+
+ private void closePopup() {
+ getDriver().findElement(By.tagName("body")).click();
+ }
+
+ /**
+ * @since
+ * @param string
+ */
+ private void menuSub(String string) {
+ getDriver().findElement(
+ By.xpath("//span[text() = '" + string + "']")).click();
+ new Actions(getDriver()).moveByOffset(100, 0).build().perform();
+ }
+
+ /**
+ * @since
+ * @param string
+ */
+ private void menu(String string) {
+ getDriver().findElement(
+ By.xpath("//span[text() = '" + string + "']")).click();
+
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.html b/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.html
index 77c610f211..75c19945b0 100644
--- a/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.html
+++ b/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.html
@@ -52,6 +52,11 @@
<td></td>
</tr>
<tr>
+ <td>pause</td>
+ <td>300</td>
+ <td></td>
+</tr>
+<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentsdatefieldDynamicallyChangeDateRange::/VVerticalLayout[0]/Slot[0]/VPopupCalendar[0]#popupButton</td>
<td>14,16</td>
@@ -87,6 +92,11 @@
<td></td>
</tr>
<tr>
+ <td>pause</td>
+ <td>300</td>
+ <td></td>
+</tr>
+<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentsdatefieldDynamicallyChangeDateRange::/VVerticalLayout[0]/Slot[0]/VPopupCalendar[0]#popupButton</td>
<td>14,15</td>
diff --git a/uitest/src/com/vaadin/tests/components/label/LabelModes.html b/uitest/src/com/vaadin/tests/components/label/LabelModes.html
deleted file mode 100644
index 356688b456..0000000000
--- a/uitest/src/com/vaadin/tests/components/label/LabelModes.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.components.label.LabelModes?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>screenCapture</td>
- <td></td>
- <td>labelmodes</td>
-</tr>
-
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/components/label/LabelModesTest.java b/uitest/src/com/vaadin/tests/components/label/LabelModesTest.java
new file mode 100644
index 0000000000..efad615510
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/label/LabelModesTest.java
@@ -0,0 +1,30 @@
+/*
+ * 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.label;
+
+import org.junit.Test;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class LabelModesTest extends MultiBrowserTest {
+
+ @Test
+ public void testLabelModes() throws Exception {
+ openTestURL();
+ compareScreen("labelmodes");
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.html b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.html
new file mode 100644
index 0000000000..046cac0e30
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.html
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>OptionGroupRetainFocusKeyboardValueChange</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">OptionGroupRetainFocusKeyboardValueChange</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/OptionGroupRetainFocusKeyboardValueChange?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runOptionGroupRetainFocusKeyboardValueChange::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VOptionGroup[0]/domChild[0]/domChild[0]</td>
+ <td>space</td>
+</tr>
+<!-- The element 'A' should be selected and focused -->
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td></td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runOptionGroupRetainFocusKeyboardValueChange::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VOptionGroup[0]/domChild[0]/domChild[0]</td>
+ <td>down</td>
+</tr>
+<!-- The element 'B' should be selected and focused, the caption of first element is changed from 'A' to 'A+' -->
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td></td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runOptionGroupRetainFocusKeyboardValueChange::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VOptionGroup[0]/domChild[1]/domChild[0]</td>
+ <td>down</td>
+</tr>
+<!-- Elements 'B' and 'C' should be swapped; 'C' selected but not focused -->
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.java b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.java
new file mode 100644
index 0000000000..570a300cb3
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.java
@@ -0,0 +1,70 @@
+/*
+ * 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.optiongroup;
+
+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.OptionGroup;
+
+/**
+ * Testcase for #10451
+ *
+ * @author Vaadin Ltd
+ */
+public class OptionGroupRetainFocusKeyboardValueChange extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final OptionGroup optiongroup = new OptionGroup();
+ optiongroup.addItem(1);
+ optiongroup.addItem(2);
+ optiongroup.addItem(3);
+ optiongroup.setItemCaption(1, "A");
+ optiongroup.setItemCaption(2, "B");
+ optiongroup.setItemCaption(3, "C");
+ optiongroup.setImmediate(true);
+
+ optiongroup.addValueChangeListener(new ValueChangeListener() {
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ if (optiongroup.isSelected(2)) {
+ optiongroup.setItemCaption(1, "A+");
+ } else if (optiongroup.isSelected(3)) {
+ optiongroup.removeItem(2);
+ optiongroup.addItem(2);
+ optiongroup.setItemCaption(2, "B");
+ }
+ }
+ });
+
+ addComponent(optiongroup);
+
+ optiongroup.focus();
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "OptionGroup should retain focus after it's value being changed with keyboard";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 10451;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsg.java b/uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsg.java
new file mode 100644
index 0000000000..030bfa693e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsg.java
@@ -0,0 +1,66 @@
+package com.vaadin.tests.components.orderedlayout;
+
+import com.vaadin.server.UserError;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.TextField;
+
+public class HorizontalLayoutFullsizeContentWithErrorMsg extends AbstractTestUI {
+
+ static final String FIELD_ID = "f";
+ static final String BUTTON_ID = "b";
+ private TextField tf;
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12564;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server.
+ * VaadinRequest)
+ */
+ @Override
+ protected void setup(VaadinRequest request) {
+ HorizontalLayout hl = new HorizontalLayout();
+ hl.setWidth("500px");
+
+ tf = new TextField();
+ tf.setId(FIELD_ID);
+ tf.setWidth("100%");
+ hl.addComponent(tf);
+ hl.setExpandRatio(tf, 1);
+ hl.setComponentAlignment(tf, Alignment.MIDDLE_CENTER);
+
+ Button toggleError = new Button("Toggle error");
+ toggleError.setId(BUTTON_ID);
+ toggleError.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ tf.setComponentError(tf.getComponentError() == null ? new UserError(
+ "foo") : null);
+ }
+ });
+ hl.addComponent(toggleError);
+
+ addComponent(hl);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription()
+ */
+ @Override
+ protected String getTestDescription() {
+ return "TextField should remain at same level vertically, horizontally width should adjust to fit error indicator.";
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsgTest.java b/uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsgTest.java
new file mode 100644
index 0000000000..24ebf24688
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsgTest.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.components.orderedlayout;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Point;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class HorizontalLayoutFullsizeContentWithErrorMsgTest extends
+ MultiBrowserTest {
+
+ @Test
+ public void test() {
+ openTestURL();
+ WebElement element = getDriver().findElement(
+ By.id(HorizontalLayoutFullsizeContentWithErrorMsg.FIELD_ID));
+ Point location = element.getLocation();
+
+ WebElement errorToggleButton = getDriver().findElement(
+ By.id(HorizontalLayoutFullsizeContentWithErrorMsg.BUTTON_ID));
+
+ errorToggleButton.click();
+
+ Assert.assertEquals(location, element.getLocation());
+
+ errorToggleButton.click();
+
+ Assert.assertEquals(location, element.getLocation());
+
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/panel/PanelChangeContentsTest.java b/uitest/src/com/vaadin/tests/components/panel/PanelChangeContentsTest.java
new file mode 100644
index 0000000000..5bc505dbc8
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/panel/PanelChangeContentsTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.panel;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class PanelChangeContentsTest extends MultiBrowserTest {
+
+ @Test
+ public void testReattachComponentUsingPush() {
+ setPush(true);
+ openTestURL();
+
+ Assert.assertEquals(
+ "stats",
+ vaadinElement(
+ "/VVerticalLayout[0]/Slot[1]/VPanel[0]/VVerticalLayout[0]/Slot[0]/VLabel[0]")
+ .getText());
+ vaadinElement(
+ "/VVerticalLayout[0]/Slot[0]/VHorizontalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]")
+ .click();
+ Assert.assertEquals(
+ "companies",
+ vaadinElement(
+ "/VVerticalLayout[0]/Slot[1]/VPanel[0]/VVerticalLayout[0]/Slot[0]/VLabel[0]")
+ .getText());
+ vaadinElement(
+ "/VVerticalLayout[0]/Slot[0]/VHorizontalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]")
+ .click();
+ Assert.assertEquals(
+ "stats",
+ vaadinElement(
+ "/VVerticalLayout[0]/Slot[1]/VPanel[0]/VVerticalLayout[0]/Slot[0]/VLabel[0]")
+ .getText());
+
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/slider/SliderDisable.java b/uitest/src/com/vaadin/tests/components/slider/SliderDisable.java
new file mode 100644
index 0000000000..bd1d175119
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/slider/SliderDisable.java
@@ -0,0 +1,62 @@
+/*
+ * 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.slider;
+
+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.Slider;
+import com.vaadin.ui.VerticalLayout;
+
+public class SliderDisable extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ VerticalLayout content = new VerticalLayout();
+ content.setMargin(true);
+ content.setSpacing(true);
+
+ final Slider slider = new Slider(0, 5);
+ slider.setWidth(200, Unit.PIXELS);
+ slider.setValue(1.0D);
+
+ Button disableButton = new Button("Disable slider");
+ disableButton.setId("disableButton");
+ disableButton.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ slider.setEnabled(false);
+ }
+ });
+
+ content.addComponent(slider);
+ content.addComponent(disableButton);
+ setContent(content);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "The apparent value of the slider should not change when the slider is disabled";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12676;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/slider/SliderDisableTest.java b/uitest/src/com/vaadin/tests/components/slider/SliderDisableTest.java
new file mode 100644
index 0000000000..f6ec3dac3b
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/slider/SliderDisableTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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.slider;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class SliderDisableTest extends MultiBrowserTest {
+ @Test
+ public void disableSlider() throws IOException {
+ openTestURL();
+ WebElement element = vaadinElement("/VVerticalLayout[0]/Slot[0]/VSlider[0]/domChild[2]/domChild[0]");
+ new Actions(driver).dragAndDropBy(element, 112, 0).perform();
+ compareScreen("enabled");
+ vaadinElementById("disableButton").click();
+ compareScreen("disabled");
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/table/EmptyTable.java b/uitest/src/com/vaadin/tests/components/table/EmptyTable.java
new file mode 100644
index 0000000000..d6c30efa5a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/EmptyTable.java
@@ -0,0 +1,58 @@
+/*
+ * 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.table;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Table;
+
+public class EmptyTable extends AbstractTestUI {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server.
+ * VaadinRequest)
+ */
+ @Override
+ protected void setup(VaadinRequest request) {
+ Table table = new Table("Table");
+ table.addContainerProperty("testColumn", String.class, null);
+ table.setPageLength(0); // disable paging
+ addComponent(table);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription()
+ */
+ @Override
+ protected String getTestDescription() {
+ return "Empty Table should not cause JS exception";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber()
+ */
+ @Override
+ protected Integer getTicketNumber() {
+ return 11189;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/EmptyTableTest.java b/uitest/src/com/vaadin/tests/components/table/EmptyTableTest.java
new file mode 100644
index 0000000000..229dc23b9a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/EmptyTableTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.table;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.NoSuchElementException;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class EmptyTableTest extends MultiBrowserTest {
+
+ @Test
+ public void test() {
+ setDebug(true);
+ openTestURL();
+
+ ensureNoErrors();
+ }
+
+ private void ensureNoErrors() {
+ try {
+ getDriver().findElement(By.className("v-Notification"));
+ } catch (NoSuchElementException e) {
+ return;
+ }
+ Assert.fail("Error notification was shown!");
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/PushFromInit.html b/uitest/src/com/vaadin/tests/components/table/ShowLastItem.html
index d009eb3baf..c9c93198fa 100644
--- a/uitest/src/com/vaadin/tests/push/PushFromInit.html
+++ b/uitest/src/com/vaadin/tests/components/table/ShowLastItem.html
@@ -3,7 +3,6 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="" />
<title>New Test</title>
</head>
<body>
@@ -12,19 +11,24 @@
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
- <td>open</td>
- <td>/run-push/com.vaadin.tests.push.PushFromInit?debug&amp;restartApplication</td>
- <td></td>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.table.ShowLastItem?restartApplication</td>
+ <td></td>
</tr>
<tr>
- <td>waitForText</td>
- <td>vaadin=runpushcomvaadintestspushPushFromInit::PID_SLog_row_1</td>
- <td>1. Logged in init</td>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstableShowLastItem::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
</tr>
<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushPushFromInit::PID_SLog_row_0</td>
- <td>2. Logged from background thread started in init</td>
+ <td>pause</td>
+ <td>1000</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>row-20-fully-visible</td>
</tr>
</tbody></table>
diff --git a/uitest/src/com/vaadin/tests/components/table/ShowLastItem.java b/uitest/src/com/vaadin/tests/components/table/ShowLastItem.java
new file mode 100644
index 0000000000..6d6f744918
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/ShowLastItem.java
@@ -0,0 +1,66 @@
+package com.vaadin.tests.components.table;
+
+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.Table;
+
+public class ShowLastItem extends AbstractTestUI {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server.
+ * VaadinRequest)
+ */
+ @Override
+ protected void setup(VaadinRequest request) {
+ final Table table = new Table();
+ table.setHeight("210px");
+
+ table.addContainerProperty("Col", String.class, "");
+
+ for (int i = 0; i < 20; i++) {
+ table.addItem(i).getItemProperty("Col")
+ .setValue("row " + String.valueOf(i));
+ }
+
+ Button addItemBtn = new Button("Add item", new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ Object itemId = "row " + table.getItemIds().size();
+
+ table.addItem(itemId).getItemProperty("Col")
+ .setValue(String.valueOf(itemId));
+
+ table.setCurrentPageFirstItemIndex(table.getItemIds().size() - 1);
+ }
+ });
+
+ addComponent(table);
+ addComponent(addItemBtn);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription()
+ */
+ @Override
+ protected String getTestDescription() {
+ return "Show last item in Table by using setCurrentPageFirstItemId";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber()
+ */
+ @Override
+ protected Integer getTicketNumber() {
+ return 12407;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/TableMoveFocusWithSelection.java b/uitest/src/com/vaadin/tests/components/table/TableMoveFocusWithSelection.java
new file mode 100644
index 0000000000..20170efa13
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableMoveFocusWithSelection.java
@@ -0,0 +1,125 @@
+/*
+ * 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.table;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.vaadin.event.LayoutEvents.LayoutClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickListener;
+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.Table;
+import com.vaadin.ui.VerticalLayout;
+
+public class TableMoveFocusWithSelection extends AbstractTestUI {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server.
+ * VaadinRequest)
+ */
+ @Override
+ protected void setup(VaadinRequest request) {
+ final Table t = new Table();
+ t.setImmediate(true);
+ t.setId("test-table");
+ t.setSizeFull();
+ t.setSelectable(true);
+ t.addContainerProperty("layout", VerticalLayout.class, null);
+ t.addContainerProperty("string", String.class, null);
+
+ for (int i = 0; i < 100; i++) {
+ t.addItem(i);
+ final VerticalLayout l = new VerticalLayout();
+ l.setId("row-" + i);
+ l.setHeight(20, Unit.PIXELS);
+ l.setData(i);
+ l.addLayoutClickListener(new LayoutClickListener() {
+ @Override
+ public void layoutClick(LayoutClickEvent event) {
+ if (t.isMultiSelect()) {
+ Set<Object> values = new HashSet<Object>(
+ (Set<Object>) t.getValue());
+ values.add(l.getData());
+ t.setValue(values);
+ } else {
+ t.setValue(l.getData());
+ }
+ }
+ });
+ t.getContainerProperty(i, "layout").setValue(l);
+ t.getContainerProperty(i, "string").setValue("Item #" + i);
+ }
+ addComponent(t);
+
+ // Select mode
+ Button toggleSelectMode = new Button(
+ t.isMultiSelect() ? "Press to use single select"
+ : "Press to use multi select");
+ toggleSelectMode.setId("toggle-mode");
+ toggleSelectMode.addClickListener(new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ t.setMultiSelect(!t.isMultiSelect());
+
+ event.getButton().setCaption(
+ t.isMultiSelect() ? "Press to use single select"
+ : "Press to use multi select");
+ }
+ });
+
+ addComponent(toggleSelectMode);
+
+ Button select5210 = new Button("Select row 5-10",
+ new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ t.setValue(Arrays.asList(5, 6, 7, 8, 9, 10));
+ }
+ });
+ select5210.setId("select-510");
+ addComponent(select5210);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription()
+ */
+ @Override
+ protected String getTestDescription() {
+ return "Changing selection in single select mode should move focus";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber()
+ */
+ @Override
+ protected Integer getTicketNumber() {
+ return 12540;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/TableMoveFocusWithSelectionTest.java b/uitest/src/com/vaadin/tests/components/table/TableMoveFocusWithSelectionTest.java
new file mode 100644
index 0000000000..b38705eeb6
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableMoveFocusWithSelectionTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.table;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Tests if table focus is moved correctly to the selected item
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TableMoveFocusWithSelectionTest extends MultiBrowserTest {
+
+ @Test
+ public void selectUnfocusedTableAndAssumeSelectionGetsFocus() {
+
+ openTestURL();
+
+ // Click on row 5
+ getDriver().findElement(By.id("row-5")).click();
+
+ // Ensure row 5 gets focused
+ WebElement row5TableRow = getDriver().findElement(
+ By.xpath("//div[@id='row-5']/../../.."));
+ String row5StyleName = row5TableRow.getAttribute("class");
+ assertTrue(row5StyleName.contains("v-table-focus"));
+ }
+
+ @Test
+ public void focusShouldStayOnUserSelectedRowIfSelectionChangesServerSide() {
+
+ openTestURL();
+
+ // Select multiselect
+ getDriver().findElement(By.id("toggle-mode")).click();
+
+ // Click on row 7
+ getDriver().findElement(By.id("row-7")).click();
+
+ // Select row 5-10 server side
+ getDriver().findElement(By.id("select-510")).click();
+
+ // Ensure row 7 is still focused
+ WebElement row7TableRow = getDriver().findElement(
+ By.xpath("//div[@id='row-7']/../../.."));
+ String row7StyleName = row7TableRow.getAttribute("class");
+ assertTrue(row7StyleName.contains("v-table-focus"));
+ }
+
+ @Override
+ protected Class<?> getUIClass() {
+ // FIXME Remove when this is done automatically
+ return TableMoveFocusWithSelection.class;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetHotKeysWithModifiers.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetHotKeysWithModifiers.java
new file mode 100644
index 0000000000..c0b30ff68d
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetHotKeysWithModifiers.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.components.tabsheet;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+
+public class TabSheetHotKeysWithModifiers extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ TabSheet tabSheet = new TabSheet();
+ tabSheet.setWidth("500px");
+ tabSheet.setHeight("500px");
+ tabSheet.addTab(new Label("Tab 1"), "Tab 1").setClosable(true);
+ tabSheet.addTab(new Label("Tab 2"), "Tab 2").setClosable(true);
+ tabSheet.addTab(new Label("Tab 3"), "Tab 3").setClosable(true);
+ setContent(tabSheet);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Hot keys (left and right arrow keys and the delete key) should be ignored when they are pressed simultaneously with modifier keys";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12178;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/ui/UIAccessTest.java b/uitest/src/com/vaadin/tests/components/ui/UIAccessTest.java
new file mode 100644
index 0000000000..9db2c2f0d3
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/ui/UIAccessTest.java
@@ -0,0 +1,204 @@
+/*
+ * 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.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class UIAccessTest extends MultiBrowserTest {
+ @Test
+ public void testThreadLocals() {
+ setPush(true);
+ openTestURL();
+ getCurrentInstanceWhenPushingButton().click();
+ waitUntil(ExpectedConditions.textToBePresentInElement(
+ vaadinLocatorById("Log_row_0"), "1."));
+ Assert.assertEquals("0. Current UI matches in beforeResponse? true",
+ vaadinElementById("Log_row_1").getText());
+ Assert.assertEquals(
+ "1. Current session matches in beforeResponse? true",
+ vaadinElementById("Log_row_0").getText());
+
+ }
+
+ @Test
+ public void testAccessMethod() throws Exception {
+ openTestURL();
+
+ vaadinElement(
+ "/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]")
+ .click();
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]"))
+ .click();
+ assertTrue(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_2"))
+ .getText()
+ .matches(
+ "^0\\. Access from UI thread future is done[\\s\\S] false$"));
+ assertEquals(
+ "1. Access from UI thread is run",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_1"))
+ .getText());
+ assertTrue(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_0"))
+ .getText()
+ .matches(
+ "^2\\. beforeClientResponse future is done[\\s\\S] true$"));
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]"))
+ .click();
+ assertEquals(
+ "0. Initial background message",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_1"))
+ .getText());
+ assertTrue(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_0"))
+ .getText()
+ .matches("^1\\. Thread has current response[\\s\\S] false$"));
+ for (int second = 0;; second++) {
+ if (second >= 30) {
+ fail("timeout");
+ }
+ try {
+ if ("0. Initial background message"
+ .equals(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_2"))
+ .getText())) {
+ break;
+ }
+ } catch (Exception e) {
+ }
+ Thread.sleep(1000);
+ }
+
+ assertTrue(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_0"))
+ .getText()
+ .matches(
+ "^2\\. Thread got lock, inital future done[\\s\\S] true$"));
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]"))
+ .click();
+ assertEquals(
+ "0. Throwing exception in access",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_2"))
+ .getText());
+ assertTrue(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_1"))
+ .getText().matches("^1\\. firstFuture is done[\\s\\S] true$"));
+ assertEquals(
+ "2. Got exception from firstFuture: java.lang.RuntimeException: Catch me if you can",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_0"))
+ .getText());
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]"))
+ .click();
+ assertEquals(
+ "0. future was cancled, should not start",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_0"))
+ .getText());
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[4]/VButton[0]/domChild[0]/domChild[0]"))
+ .click();
+ assertEquals(
+ "0. Waiting for thread to start",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_2"))
+ .getText());
+ assertEquals(
+ "1. Thread started, waiting for interruption",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_1"))
+ .getText());
+ assertEquals(
+ "2. I was interrupted",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_0"))
+ .getText());
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]"))
+ .click();
+ assertTrue(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_3"))
+ .getText()
+ .matches("^0\\. accessSynchronously has request[\\s\\S] true$"));
+ assertEquals(
+ "1. Test value in accessSynchronously: Set before accessSynchronosly",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_2"))
+ .getText());
+ assertTrue(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_1"))
+ .getText()
+ .matches(
+ "^2\\. has request after accessSynchronously[\\s\\S] true$"));
+ assertEquals(
+ "3. Test value after accessSynchornously: Set in accessSynchronosly",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_0"))
+ .getText());
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[6]/VButton[0]/domChild[0]/domChild[0]"))
+ .click();
+ assertTrue(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_3"))
+ .getText().matches("^0\\. access has request[\\s\\S] false$"));
+ assertEquals(
+ "1. Test value in access: Set before access",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_2"))
+ .getText());
+ assertTrue(driver
+ .findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_1"))
+ .getText()
+ .matches("^2\\. has request after access[\\s\\S] true$"));
+ assertEquals(
+ "3. Test value after access: Set before run pending",
+ driver.findElement(
+ By.vaadin("runcomvaadintestscomponentsuiUIAccess::PID_SLog_row_0"))
+ .getText());
+
+ }
+
+ private WebElement getCurrentInstanceWhenPushingButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[7]/VButton[0]");
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/ui/UiAccess.html b/uitest/src/com/vaadin/tests/components/ui/UiAccess.html
deleted file mode 100644
index 613691623c..0000000000
--- a/uitest/src/com/vaadin/tests/components/ui/UiAccess.html
+++ /dev/null
@@ -1,166 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.components.ui.UiAccess?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
- <td>exact:0. Access from UI thread future is done? false</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
- <td>1. Access from UI thread is run</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td>exact:2. beforeClientResponse future is done? true</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
- <td>0. Initial background message</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td>exact:1. Thread has current response? false</td>
-</tr>
-<tr>
- <td>waitForText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
- <td>0. Initial background message</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td>exact:2. Thread got lock, inital future done? true</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
- <td>0. Throwing exception in access</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
- <td>exact:1. firstFuture is done? true</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td>2. Got exception from firstFuture: java.lang.RuntimeException: Catch me if you can</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td>0. future was cancled, should not start</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[4]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
- <td>0. Waiting for thread to start</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
- <td>1. Thread started, waiting for interruption</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td>2. I was interrupted</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_3</td>
- <td>0. accessSynchronously has request? true</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
- <td>1. Test value in accessSynchronously: Set before accessSynchronosly</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
- <td>2. has request after accessSynchronously? true</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td>3. Test value after accessSynchornously: Set in accessSynchronosly</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[6]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_3</td>
- <td>0. access has request? false</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
- <td>1. Test value in access: Set before access</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
- <td>2. has request after access? true</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td>3. Test value after access: Set before run pending</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/components/ui/UiAccess.java b/uitest/src/com/vaadin/tests/components/ui/UiAccess.java
deleted file mode 100644
index 09f2fd8816..0000000000
--- a/uitest/src/com/vaadin/tests/components/ui/UiAccess.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * 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 java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.locks.ReentrantLock;
-
-import com.vaadin.server.VaadinRequest;
-import com.vaadin.server.VaadinService;
-import com.vaadin.server.VaadinSession;
-import com.vaadin.shared.communication.PushMode;
-import com.vaadin.tests.components.AbstractTestUIWithLog;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.ui.UI;
-import com.vaadin.util.CurrentInstance;
-
-public class UiAccess extends AbstractTestUIWithLog {
-
- private volatile boolean checkCurrentInstancesBeforeResponse = false;
-
- private Future<Void> checkFromBeforeClientResponse;
-
- private class CurrentInstanceTestType {
- private String value;
-
- public CurrentInstanceTestType(String value) {
- this.value = value;
- }
-
- @Override
- public String toString() {
- return value;
- }
- }
-
- @Override
- protected void setup(VaadinRequest request) {
- addComponent(new Button("Access from UI thread",
- new Button.ClickListener() {
-
- @Override
- public void buttonClick(ClickEvent event) {
- log.clear();
- // Ensure beforeClientResponse is invoked
- markAsDirty();
- checkFromBeforeClientResponse = access(new Runnable() {
- @Override
- public void run() {
- log("Access from UI thread is run");
- }
- });
- log("Access from UI thread future is done? "
- + checkFromBeforeClientResponse.isDone());
- }
- }));
- addComponent(new Button("Access from background thread",
- new Button.ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- log.clear();
- final CountDownLatch latch = new CountDownLatch(1);
-
- new Thread() {
- @Override
- public void run() {
- final boolean threadHasCurrentResponse = VaadinService
- .getCurrentResponse() != null;
- // session is locked by request thread at this
- // point
- final Future<Void> initialFuture = access(new Runnable() {
- @Override
- public void run() {
- log("Initial background message");
- log("Thread has current response? "
- + threadHasCurrentResponse);
- }
- });
-
- // Let request thread continue
- latch.countDown();
-
- // Wait until thread can be locked
- while (!getSession().getLockInstance()
- .tryLock()) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- try {
- log("Thread got lock, inital future done? "
- + initialFuture.isDone());
- setPollInterval(-1);
- } finally {
- getSession().unlock();
- }
- }
- }.start();
-
- // Wait for thread to do initialize before continuing
- try {
- latch.await();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
-
- setPollInterval(3000);
- }
- }));
- addComponent(new Button("Access throwing exception",
- new Button.ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- log.clear();
- final Future<Void> firstFuture = access(new Runnable() {
- @Override
- public void run() {
- log("Throwing exception in access");
- throw new RuntimeException(
- "Catch me if you can");
- }
- });
- access(new Runnable() {
- @Override
- public void run() {
- log("firstFuture is done? "
- + firstFuture.isDone());
- try {
- firstFuture.get();
- log("Should not get here");
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- } catch (ExecutionException e) {
- log("Got exception from firstFuture: "
- + e.getMessage());
- }
- }
- });
- }
- }));
- addComponent(new Button("Cancel future before started",
- new Button.ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- log.clear();
- Future<Void> future = access(new Runnable() {
- @Override
- public void run() {
- log("Should not get here");
- }
- });
- future.cancel(false);
- log("future was cancled, should not start");
- }
- }));
- addComponent(new Button("Cancel running future",
- new Button.ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- log.clear();
- final ReentrantLock interruptLock = new ReentrantLock();
-
- final Future<Void> future = access(new Runnable() {
- @Override
- public void run() {
- log("Waiting for thread to start");
- while (!interruptLock.isLocked()) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- log("Premature interruption");
- throw new RuntimeException(e);
- }
- }
-
- log("Thread started, waiting for interruption");
- try {
- interruptLock.lockInterruptibly();
- } catch (InterruptedException e) {
- log("I was interrupted");
- }
- }
- });
-
- new Thread() {
- @Override
- public void run() {
- interruptLock.lock();
- // Wait until UI thread has started waiting for
- // the lock
- while (!interruptLock.hasQueuedThreads()) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-
- future.cancel(true);
- }
- }.start();
- }
- }));
- addComponent(new Button("CurrentInstance accessSynchronously values",
- new Button.ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- log.clear();
- // accessSynchronously should maintain values
- CurrentInstance.set(CurrentInstanceTestType.class,
- new CurrentInstanceTestType(
- "Set before accessSynchronosly"));
- accessSynchronously(new Runnable() {
- @Override
- public void run() {
- log.log("accessSynchronously has request? "
- + (VaadinService.getCurrentRequest() != null));
- log.log("Test value in accessSynchronously: "
- + CurrentInstance
- .get(CurrentInstanceTestType.class));
- CurrentInstance.set(
- CurrentInstanceTestType.class,
- new CurrentInstanceTestType(
- "Set in accessSynchronosly"));
- }
- });
- log.log("has request after accessSynchronously? "
- + (VaadinService.getCurrentRequest() != null));
- log("Test value after accessSynchornously: "
- + CurrentInstance
- .get(CurrentInstanceTestType.class));
- }
- }));
- addComponent(new Button("CurrentInstance access values",
- new Button.ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- log.clear();
- // accessSynchronously should maintain values
- CurrentInstance
- .setInheritable(CurrentInstanceTestType.class,
- new CurrentInstanceTestType(
- "Set before access"));
- access(new Runnable() {
- @Override
- public void run() {
- log.log("access has request? "
- + (VaadinService.getCurrentRequest() != null));
- log.log("Test value in access: "
- + CurrentInstance
- .get(CurrentInstanceTestType.class));
- CurrentInstance.setInheritable(
- CurrentInstanceTestType.class,
- new CurrentInstanceTestType(
- "Set in access"));
- }
- });
- CurrentInstance.setInheritable(
- CurrentInstanceTestType.class,
- new CurrentInstanceTestType(
- "Set before run pending"));
-
- getSession().getService().runPendingAccessTasks(
- getSession());
-
- log.log("has request after access? "
- + (VaadinService.getCurrentRequest() != null));
- log("Test value after access: "
- + CurrentInstance
- .get(CurrentInstanceTestType.class));
- }
- }));
-
- addComponent(new Button("CurrentInstance when pushing",
- new Button.ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- log.clear();
- if (getPushConfiguration().getPushMode() != PushMode.AUTOMATIC) {
- log("Can only test with automatic push enabled");
- return;
- }
-
- final VaadinSession session = getSession();
- new Thread() {
- @Override
- public void run() {
- // Pretend this isn't a Vaadin thread
- CurrentInstance.clearAll();
-
- /*
- * Get explicit lock to ensure the (implicit)
- * push does not happen during normal request
- * handling.
- */
- session.lock();
- try {
- access(new Runnable() {
- @Override
- public void run() {
- checkCurrentInstancesBeforeResponse = true;
- // Trigger beforeClientResponse
- markAsDirty();
- }
- });
- } finally {
- session.unlock();
- }
- }
- }.start();
- }
- }));
- }
-
- @Override
- public void beforeClientResponse(boolean initial) {
- if (checkFromBeforeClientResponse != null) {
- log("beforeClientResponse future is done? "
- + checkFromBeforeClientResponse.isDone());
- checkFromBeforeClientResponse = null;
- }
- if (checkCurrentInstancesBeforeResponse) {
- UI currentUI = UI.getCurrent();
- VaadinSession currentSession = VaadinSession.getCurrent();
-
- log("Current UI matches in beforeResponse? " + (currentUI == this));
- log("Current session matches in beforeResponse? "
- + (currentSession == getSession()));
- checkCurrentInstancesBeforeResponse = false;
- }
- }
-
- @Override
- protected String getTestDescription() {
- return "Test for various ways of using UI.access";
- }
-
- @Override
- protected Integer getTicketNumber() {
- return Integer.valueOf(11897);
- }
-
-}
diff --git a/uitest/src/com/vaadin/tests/components/ui/UiAccessPush.html b/uitest/src/com/vaadin/tests/components/ui/UiAccessPush.html
deleted file mode 100644
index bc29534ee4..0000000000
--- a/uitest/src/com/vaadin/tests/components/ui/UiAccessPush.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.components.ui.UiAccess?restartApplication&amp;transport=websocket</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[7]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>waitForNotText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
- <td>exact:1. Current session matches in beforeResponse? true</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
- <td>exact:0. Current UI matches in beforeResponse? true</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/dd/DnDOnSubtree.html b/uitest/src/com/vaadin/tests/dd/DnDOnSubtree.html
new file mode 100644
index 0000000000..844636cb02
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/dd/DnDOnSubtree.html
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <link rel="selenium.base" href="http://localhost:8888/"/>
+ <title>DnDOnSubtree</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+ <thead>
+ <tr>
+ <td rowspan="1" colspan="3">New Test</td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.dd.DDTest8?restartApplication</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>drag</td>
+ <td>vaadin=runcomvaadintestsddDDTest8::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTree[0]#n[3]</td>
+ <td>11,8</td>
+ </tr>
+ <!-- Drop on Bar5, which is a subtree target -->
+ <tr>
+ <td>drop</td>
+ <td>vaadin=runcomvaadintestsddDDTest8::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTree[0]#n[6]</td>
+ <td>34,9</td>
+ </tr>
+ <tr>
+ <td>mouseClick</td>
+ <td>
+ vaadin=runcomvaadintestsddDDTest8::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTree[0]#n[5]/expand
+ </td>
+ <td>10,8</td>
+ </tr>
+ <!-- Assert that the dragged & dropped node is now a child of Bar5 -->
+ <tr>
+ <td>assertElementPresent</td>
+ <td>
+ vaadin=runcomvaadintestsddDDTest8::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTree[0]#n[5]/n[0]
+ </td>
+ <td></td>
+ </tr>
+ </tbody>
+</table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java b/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java
new file mode 100644
index 0000000000..5f4ae41361
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.integration;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized.Parameters;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.tests.tb3.PrivateTB3Configuration;
+
+/**
+ * Base class for integration tests. Integration tests use the
+ * {@literal deployment.url} parameter to determine the base deployment url
+ * (http://hostname:123)
+ *
+ * @author Vaadin Ltd
+ */
+@RunWith(IntegrationTestRunner.class)
+public abstract class AbstractIntegrationTest extends
+ PrivateTB3Configuration {
+ @Override
+ protected String getBaseURL() {
+ String deploymentUrl = System.getProperty("deployment.url");
+ if (deploymentUrl == null || deploymentUrl.equals("")) {
+ throw new RuntimeException(
+ "Deployment url must be given as deployment.url");
+ }
+
+ return deploymentUrl;
+ }
+
+ @Parameters
+ public static Collection<DesiredCapabilities> getBrowsersForTest() {
+ return Collections.singleton(BrowserUtil.firefox(17));
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/integration/AbstractServletIntegrationTest.java b/uitest/src/com/vaadin/tests/integration/AbstractServletIntegrationTest.java
new file mode 100644
index 0000000000..f736a126a5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/integration/AbstractServletIntegrationTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.integration;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+/**
+ * Base class for servlet integration tests. Automatically prepends "/demo" to
+ * the deployment path
+ *
+ * @author Vaadin Ltd
+ */
+public abstract class AbstractServletIntegrationTest extends
+ AbstractIntegrationTest {
+
+ @Test
+ public void runTest() throws IOException, AssertionError {
+ openTestURL();
+ compareScreen("initial");
+
+ WebElement cell = vaadinElement(getTableCell(getTable(), 0, 1));
+ testBenchElement(cell).click(51, 13);
+
+ compareScreen("finland");
+ }
+
+ private String getTableCell(String tableLocator, int row, int col) {
+ return tableLocator
+ + "/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild["
+ + row + "]/domChild[" + col + "]/domChild[0]";
+ }
+
+ protected String getTable() {
+ return "/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.tb3.AbstractTB3Test#getDeploymentPath()
+ */
+ @Override
+ protected String getDeploymentPath() {
+ return "/demo" + super.getDeploymentPath();
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/integration/IntegrationTestRunner.java b/uitest/src/com/vaadin/tests/integration/IntegrationTestRunner.java
new file mode 100644
index 0000000000..f5042b54b6
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/integration/IntegrationTestRunner.java
@@ -0,0 +1,54 @@
+/*
+ * 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.integration;
+
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+
+import com.vaadin.tests.tb3.TB3Runner;
+
+/**
+ * JUnit runner for integration tests. Replaces the actual method name with the
+ * server-name property when generating the test name.
+ *
+ * @author Vaadin Ltd
+ */
+public class IntegrationTestRunner extends TB3Runner {
+
+ private Class<?> testClass;
+
+ public IntegrationTestRunner(Class<?> klass) throws InitializationError {
+ super(klass);
+ testClass = klass;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.junit.runners.BlockJUnit4ClassRunner#testName(org.junit.runners.model
+ * .FrameworkMethod)
+ */
+ @Override
+ protected String testName(FrameworkMethod method) {
+ if (AbstractIntegrationTest.class.isAssignableFrom(testClass)) {
+ return System.getProperty("server-name");
+ } else {
+ return super.testName(method);
+ }
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/integration/ServletIntegrationStreamingUI.java b/uitest/src/com/vaadin/tests/integration/ServletIntegrationStreamingUI.java
new file mode 100644
index 0000000000..0d92fb1bb8
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/integration/ServletIntegrationStreamingUI.java
@@ -0,0 +1,30 @@
+/*
+ * 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.integration;
+
+import com.vaadin.annotations.Push;
+import com.vaadin.shared.ui.ui.Transport;
+
+/**
+ * Server test which uses streaming
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+@Push(transport = Transport.STREAMING)
+public class ServletIntegrationStreamingUI extends ServletIntegrationUI {
+
+}
diff --git a/uitest/src/com/vaadin/tests/integration/ServletIntegrationStreamingUITest.java b/uitest/src/com/vaadin/tests/integration/ServletIntegrationStreamingUITest.java
new file mode 100644
index 0000000000..36a946bfa3
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/integration/ServletIntegrationStreamingUITest.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.integration;
+
+public class ServletIntegrationStreamingUITest extends
+ AbstractServletIntegrationTest {
+ // Uses the test method declared in the super class
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/integration/IntegrationTestUI.java b/uitest/src/com/vaadin/tests/integration/ServletIntegrationUI.java
index 0e6cb19b30..6aec2c8e2a 100755
--- a/uitest/src/com/vaadin/tests/integration/IntegrationTestUI.java
+++ b/uitest/src/com/vaadin/tests/integration/ServletIntegrationUI.java
@@ -11,7 +11,8 @@ import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
-public class IntegrationTestUI extends UI {
+public class ServletIntegrationUI extends UI {
+
@Override
protected void init(VaadinRequest request) {
VerticalLayout layout = new VerticalLayout();
diff --git a/uitest/src/com/vaadin/tests/integration/ServletIntegrationUITest.java b/uitest/src/com/vaadin/tests/integration/ServletIntegrationUITest.java
new file mode 100644
index 0000000000..25ffdac4a2
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/integration/ServletIntegrationUITest.java
@@ -0,0 +1,20 @@
+/*
+ * 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.integration;
+
+public class ServletIntegrationUITest extends AbstractServletIntegrationTest {
+ // Uses the test method declared in the super class
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/integration/ServletIntegrationWebsocketUI.java b/uitest/src/com/vaadin/tests/integration/ServletIntegrationWebsocketUI.java
new file mode 100644
index 0000000000..905b80fd85
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/integration/ServletIntegrationWebsocketUI.java
@@ -0,0 +1,45 @@
+/*
+ * 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.integration;
+
+import com.vaadin.annotations.Push;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.ui.Transport;
+
+/**
+ * Server test which uses websockets
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+@Push(transport = Transport.WEBSOCKET)
+public class ServletIntegrationWebsocketUI extends ServletIntegrationUI {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.tests.integration.IntegrationTestUI#init(com.vaadin.server
+ * .VaadinRequest)
+ */
+ @Override
+ protected void init(VaadinRequest request) {
+ super.init(request);
+ // Ensure no fallback is used
+ getPushConfiguration().setFallbackTransport(Transport.WEBSOCKET);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/integration/ServletIntegrationWebsocketUITest.java b/uitest/src/com/vaadin/tests/integration/ServletIntegrationWebsocketUITest.java
new file mode 100644
index 0000000000..f2e7a6f2d0
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/integration/ServletIntegrationWebsocketUITest.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.integration;
+
+public class ServletIntegrationWebsocketUITest extends
+ AbstractServletIntegrationTest {
+ // Uses the test method declared in the super class
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/BarInUIDL.html b/uitest/src/com/vaadin/tests/push/BarInUIDL.html
deleted file mode 100644
index 66f03158b6..0000000000
--- a/uitest/src/com/vaadin/tests/push/BarInUIDL.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://localhost:8888/" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run-push/com.vaadin.tests.push.BarInUIDL?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBarInUIDL::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBarInUIDL::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]</td>
- <td>Thank you for clicking | bar</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBarInUIDL::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBarInUIDL::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VLabel[0]</td>
- <td>Thank you for clicking | bar</td>
-</tr>
-
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/push/BarInUIDL.java b/uitest/src/com/vaadin/tests/push/BarInUIDL.java
index 7e414cc89d..bc05f7c306 100644
--- a/uitest/src/com/vaadin/tests/push/BarInUIDL.java
+++ b/uitest/src/com/vaadin/tests/push/BarInUIDL.java
@@ -16,12 +16,15 @@
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.tests.components.AbstractTestUI;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
+@Push(transport = Transport.STREAMING)
public class BarInUIDL extends AbstractTestUI {
/*
diff --git a/uitest/src/com/vaadin/tests/push/BarInUIDLTest.java b/uitest/src/com/vaadin/tests/push/BarInUIDLTest.java
new file mode 100644
index 0000000000..840d653e1e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/BarInUIDLTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class BarInUIDLTest extends MultiBrowserTest {
+ @Test
+ public void sendBarInUIDL() {
+ openTestURL();
+ getButton().click();
+ Assert.assertEquals(
+ "Thank you for clicking | bar",
+ vaadinElement(
+ "/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]")
+ .getText());
+ getButton().click();
+ Assert.assertEquals(
+ "Thank you for clicking | bar",
+ vaadinElement(
+ "/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VLabel[0]")
+ .getText());
+ }
+
+ private WebElement getButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]");
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/BasicPush.html b/uitest/src/com/vaadin/tests/push/BasicPush.html
deleted file mode 100644
index 173ec90674..0000000000
--- a/uitest/src/com/vaadin/tests/push/BasicPush.html
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://localhost:8888/" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run-push/com.vaadin.tests.push.BasicPush?restartApplication&amp;debug</td>
- <td></td>
-</tr>
-<!--Test client initiated push -->
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]</td>
- <td>0</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]</td>
- <td>1</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<!--Test server initiated push-->
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VLabel[0]</td>
- <td>0</td>
-</tr>
-<tr>
- <td>pause</td>
- <td>3000</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VLabel[0]</td>
- <td>1</td>
-</tr>
-<tr>
- <td>pause</td>
- <td>3000</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VLabel[0]</td>
- <td>2</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/push/BasicPush.java b/uitest/src/com/vaadin/tests/push/BasicPush.java
index b80d287a1d..d6c45a2ed0 100644
--- a/uitest/src/com/vaadin/tests/push/BasicPush.java
+++ b/uitest/src/com/vaadin/tests/push/BasicPush.java
@@ -1,20 +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 java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
-import com.vaadin.annotations.Widgetset;
+import com.vaadin.annotations.Push;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.tests.widgetset.TestingWidgetSet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
-@Widgetset(TestingWidgetSet.NAME)
+@Push
public class BasicPush extends AbstractTestUI {
private ObjectProperty<Integer> counter = new ObjectProperty<Integer>(0);
@@ -23,18 +36,7 @@ public class BasicPush extends AbstractTestUI {
private final Timer timer = new Timer(true);
- private final TimerTask task = new TimerTask() {
-
- @Override
- public void run() {
- access(new Runnable() {
- @Override
- public void run() {
- counter2.setValue(counter2.getValue() + 1);
- }
- });
- }
- };
+ private TimerTask task;
@Override
protected void setup(VaadinRequest request) {
@@ -65,11 +67,37 @@ public class BasicPush extends AbstractTestUI {
lbl.setCaption("Server counter (updates each 3s by server thread) :");
addComponent(lbl);
- addComponent(new Button("Reset", new Button.ClickListener() {
+ addComponent(new Button("Start timer", new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
counter2.setValue(0);
+ if (task != null) {
+ task.cancel();
+ }
+ task = new TimerTask() {
+
+ @Override
+ public void run() {
+ access(new Runnable() {
+ @Override
+ public void run() {
+ counter2.setValue(counter2.getValue() + 1);
+ }
+ });
+ }
+ };
+ timer.scheduleAtFixedRate(task, 3000, 3000);
+ }
+ }));
+
+ addComponent(new Button("Stop timer", new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ if (task != null) {
+ task.cancel();
+ task = null;
+ }
}
}));
}
@@ -94,7 +122,6 @@ public class BasicPush extends AbstractTestUI {
@Override
public void attach() {
super.attach();
- timer.scheduleAtFixedRate(task, new Date(), 3000);
}
@Override
diff --git a/uitest/src/com/vaadin/tests/push/BasicPushStreaming.java b/uitest/src/com/vaadin/tests/push/BasicPushStreaming.java
index 37a8afd819..f9dc78dd43 100644
--- a/uitest/src/com/vaadin/tests/push/BasicPushStreaming.java
+++ b/uitest/src/com/vaadin/tests/push/BasicPushStreaming.java
@@ -1,12 +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 com.vaadin.annotations.Push;
+import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.ui.ui.Transport;
@Push(transport = Transport.STREAMING)
public class BasicPushStreaming extends BasicPush {
@Override
- protected void setup(com.vaadin.server.VaadinRequest request) {
- addComponent(new PushConfigurator(this));
+ public void init(VaadinRequest request) {
+ super.init(request);
+ // Don't use fallback so we can easier detect if streaming fails
+ getPushConfiguration().setFallbackTransport(Transport.STREAMING);
+
}
}
diff --git a/uitest/src/com/vaadin/tests/push/BasicPushStreamingTest.java b/uitest/src/com/vaadin/tests/push/BasicPushStreamingTest.java
new file mode 100644
index 0000000000..67730f72c8
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/BasicPushStreamingTest.java
@@ -0,0 +1,19 @@
+/*
+ * 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 BasicPushStreamingTest extends BasicPushTest {
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/BasicPushTest.java b/uitest/src/com/vaadin/tests/push/BasicPushTest.java
new file mode 100644
index 0000000000..57af8524bc
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/BasicPushTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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 org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public abstract class BasicPushTest extends MultiBrowserTest {
+
+ @Test
+ public void testPush() {
+ openTestURL();
+
+ // Test client initiated push
+ Assert.assertEquals(0, getClientCounter());
+ getIncrementButton().click();
+ Assert.assertEquals(
+ "Client counter not incremented by button click", 1,
+ getClientCounter());
+ getIncrementButton().click();
+ getIncrementButton().click();
+ getIncrementButton().click();
+ Assert.assertEquals(
+ "Four clicks should have incremented counter to 4", 4,
+ getClientCounter());
+
+ // Test server initiated push
+ getServerCounterStartButton().click();
+ try {
+ Assert.assertEquals(0, getServerCounter());
+ sleep(3000);
+ int serverCounter = getServerCounter();
+ if (serverCounter < 1) {
+ // No push has happened
+ Assert.fail("No push has occured within 3s");
+ }
+ sleep(3000);
+ if (getServerCounter() <= serverCounter) {
+ // No push has happened
+ Assert.fail("Only one push took place within 6s");
+
+ }
+ } finally {
+ // Avoid triggering push assertions
+ getServerCounterStopButton().click();
+ }
+ }
+
+ private int getServerCounter() {
+ return Integer.parseInt(getServerCounterElement().getText());
+ }
+
+ private int getClientCounter() {
+ return Integer.parseInt(getClientCounterElement().getText());
+ }
+
+ private WebElement getServerCounterElement() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VLabel[0]");
+ }
+
+ private WebElement getServerCounterStartButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]");
+ }
+
+ private WebElement getServerCounterStopButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[6]/VButton[0]/domChild[0]/domChild[0]");
+ }
+
+ private WebElement getIncrementButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]");
+ }
+
+ private WebElement getClientCounterElement() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]");
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/BasicPushWebsocket.java b/uitest/src/com/vaadin/tests/push/BasicPushWebsocket.java
index 6fc27e8974..96793a90f8 100644
--- a/uitest/src/com/vaadin/tests/push/BasicPushWebsocket.java
+++ b/uitest/src/com/vaadin/tests/push/BasicPushWebsocket.java
@@ -1,8 +1,32 @@
+/*
+ * 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;
@Push(transport = Transport.WEBSOCKET)
public class BasicPushWebsocket extends BasicPush {
+
+ @Override
+ public void init(VaadinRequest request) {
+ super.init(request);
+ // Don't use fallback so we can easier detect if websocket fails
+ getPushConfiguration().setFallbackTransport(Transport.WEBSOCKET);
+ }
+
}
diff --git a/uitest/src/com/vaadin/tests/push/BasicPushWebsocketTest.java b/uitest/src/com/vaadin/tests/push/BasicPushWebsocketTest.java
new file mode 100644
index 0000000000..ae4e64ad6b
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/BasicPushWebsocketTest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.Collection;
+
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.tests.tb3.WebsocketTest;
+
+public class BasicPushWebsocketTest extends BasicPushTest {
+ @Override
+ public Collection<DesiredCapabilities> getBrowsersToTest() {
+ return WebsocketTest.getWebsocketBrowsers();
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/EnableDisablePush.html b/uitest/src/com/vaadin/tests/push/EnableDisablePush.html
deleted file mode 100644
index 87dfa8428f..0000000000
--- a/uitest/src/com/vaadin/tests/push/EnableDisablePush.html
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="" />
-<title>EnableDisablePush</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">EnableDisablePush</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run/EnableDisablePush?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runEnableDisablePush::PID_SLog_row_0</td>
- <td>1. Push enabled</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runEnableDisablePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runEnableDisablePush::PID_SLog_row_0</td>
- <td>3. Push disabled</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runEnableDisablePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runEnableDisablePush::PID_SLog_row_0</td>
- <td>5. Poll enabled</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runEnableDisablePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runEnableDisablePush::PID_SLog_row_0</td>
- <td>7. Push enabled</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runEnableDisablePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runEnableDisablePush::PID_SLog_row_0</td>
- <td>9. Poll disabled</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runEnableDisablePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runEnableDisablePush::PID_SLog_row_0</td>
- <td>11. Push disabled, polling enabled</td>
-</tr>
-<tr>
- <td>pause</td>
- <td>3500</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runEnableDisablePush::PID_SLog_row_0</td>
- <td>16. Polling disabled, push enabled</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runEnableDisablePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runEnableDisablePush::PID_SLog_row_0</td>
- <td>18. Push disabled</td>
-</tr>
-
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/push/EnableDisablePush.java b/uitest/src/com/vaadin/tests/push/EnableDisablePush.java
index 1911c66c2d..50dab43667 100644
--- a/uitest/src/com/vaadin/tests/push/EnableDisablePush.java
+++ b/uitest/src/com/vaadin/tests/push/EnableDisablePush.java
@@ -1,19 +1,74 @@
package com.vaadin.tests.push;
+import static org.junit.Assert.assertEquals;
+
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.communication.PushMode;
import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.tb3.MultiBrowserTest;
import com.vaadin.tests.util.Log;
import com.vaadin.ui.Button;
import com.vaadin.ui.UIDetachedException;
public class EnableDisablePush extends AbstractTestUI {
+ public static class EnableDisablePushTest extends MultiBrowserTest {
+ @Test
+ public void testEnablePushWhenUsingPolling() throws Exception {
+ openTestURL();
+
+ assertEquals("1. Push enabled", getLogRow(0));
+
+ getDisablePushButton().click();
+ assertEquals("3. Push disabled", getLogRow(0));
+
+ getEnablePollButton().click();
+ assertEquals("5. Poll enabled", getLogRow(0));
+
+ getEnablePushButton().click();
+ assertEquals("7. Push enabled", getLogRow(0));
+
+ getDisablePollButton().click();
+ assertEquals("9. Poll disabled", getLogRow(0));
+
+ getDisablePushButtonAndReenableFromBackground().click();
+ Thread.sleep(2500);
+ assertEquals("16. Polling disabled, push enabled", getLogRow(0));
+
+ getDisablePushButton().click();
+ assertEquals("18. Push disabled", getLogRow(0));
+ }
+
+ private WebElement getDisablePushButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]");
+ }
+
+ private WebElement getEnablePushButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]");
+ }
+
+ private WebElement getDisablePollButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]");
+ }
+
+ private WebElement getEnablePollButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VButton[0]");
+ }
+
+ private WebElement getDisablePushButtonAndReenableFromBackground() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VButton[0]");
+ }
+
+ }
+
private int c = 0;
private Log log = new Log(15);
@@ -27,7 +82,7 @@ public class EnableDisablePush extends AbstractTestUI {
try {
while (true) {
- TimeUnit.MILLISECONDS.sleep(1000);
+ TimeUnit.MILLISECONDS.sleep(500);
access(new Runnable() {
@Override
@@ -42,6 +97,9 @@ public class EnableDisablePush extends AbstractTestUI {
}
}
});
+ if (c == 3) {
+ return;
+ }
}
} catch (InterruptedException e) {
} catch (UIDetachedException e) {
diff --git a/uitest/src/com/vaadin/tests/push/PushConfiguration.html b/uitest/src/com/vaadin/tests/push/PushConfiguration.html
deleted file mode 100644
index c3786b1cc1..0000000000
--- a/uitest/src/com/vaadin/tests/push/PushConfiguration.html
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://localhost:8888/" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<!--Websocket-->
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.push.PushConfigurationTest?debug&amp;restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertNotText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<tr>
- <td>select</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[1]/VNativeSelect[0]/domChild[0]</td>
- <td>label=WEBSOCKET</td>
-</tr>
-<tr>
- <td>assertNotText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<tr>
- <td>select</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]</td>
- <td>label=AUTOMATIC</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[5]/VLabel[0]/domChild[0]</td>
- <td>*fallbackTransport: streaming*transport: websocket*</td>
-</tr>
-<tr>
- <td>assertNotText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<tr>
- <td>waitForText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<!--Use debug console to verify we used the correct transport type-->
-<tr>
- <td>assertTextPresent</td>
- <td>Push connection established using websocket</td>
- <td></td>
-</tr>
-<tr>
- <td>assertTextNotPresent</td>
- <td>Push connection established using streaming</td>
- <td>Push connection established using streaming</td>
-</tr>
-<tr>
- <td>select</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]</td>
- <td>label=DISABLED</td>
-</tr>
-<!--Streaming-->
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.push.PushConfigurationTest?debug&amp;restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertNotText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<tr>
- <td>select</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[1]/VNativeSelect[0]/domChild[0]</td>
- <td>label=STREAMING</td>
-</tr>
-<tr>
- <td>assertNotText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<tr>
- <td>select</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]</td>
- <td>label=AUTOMATIC</td>
-</tr>
-<tr>
- <td>assertNotText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[5]/VLabel[0]/domChild[0]</td>
- <td>*fallbackTransport: streaming*transport: streaming*</td>
-</tr>
-<tr>
- <td>waitForText</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<!--Use debug console to verify we used the correct transport type-->
-<tr>
- <td>assertTextNotPresent</td>
- <td>Push connection established using websocket</td>
- <td></td>
-</tr>
-<tr>
- <td>assertTextPresent</td>
- <td>Push connection established using streaming</td>
- <td></td>
-</tr>
-<tr>
- <td>select</td>
- <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]</td>
- <td>label=DISABLED</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/push/PushConfiguration.java b/uitest/src/com/vaadin/tests/push/PushConfiguration.java
new file mode 100644
index 0000000000..a7ba4e43ba
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/PushConfiguration.java
@@ -0,0 +1,117 @@
+/*
+ * 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.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Label;
+
+public class PushConfiguration extends AbstractTestUI {
+
+ private ObjectProperty<Integer> counter = new ObjectProperty<Integer>(0);
+
+ private ObjectProperty<Integer> counter2 = new ObjectProperty<Integer>(0);
+
+ private final Timer timer = new Timer(true);
+
+ private final TimerTask task = new TimerTask() {
+
+ @Override
+ public void run() {
+ access(new Runnable() {
+ @Override
+ public void run() {
+ counter2.setValue(counter2.getValue() + 1);
+ }
+ });
+ }
+ };
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ addComponent(new PushConfigurator(this));
+ spacer();
+
+ /*
+ * Client initiated push.
+ */
+ Label lbl = new Label(counter);
+ lbl.setCaption("Client counter (click 'increment' to update):");
+ addComponent(lbl);
+
+ addComponent(new Button("Increment", new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ counter.setValue(counter.getValue() + 1);
+ }
+ }));
+
+ spacer();
+
+ /*
+ * Server initiated push.
+ */
+ lbl = new Label(counter2);
+ lbl.setCaption("Server counter (updates each 1s by server thread) :");
+ addComponent(lbl);
+
+ addComponent(new Button("Reset", new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ counter2.setValue(0);
+ }
+ }));
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "This test tests the very basic operations of push. "
+ + "It tests that client initiated changes are "
+ + "recieved back to the client as well as server "
+ + "initiated changes are correctly updated to the client.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11494;
+ }
+
+ private void spacer() {
+ addComponent(new Label("<hr/>", ContentMode.HTML));
+ }
+
+ @Override
+ public void attach() {
+ super.attach();
+ timer.scheduleAtFixedRate(task, new Date(), 1000);
+ }
+
+ @Override
+ public void detach() {
+ super.detach();
+ timer.cancel();
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java
index b57e9732cc..1f8c4c0e38 100644
--- a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java
@@ -1,102 +1,111 @@
+/*
+ * 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.Date;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import com.vaadin.data.util.ObjectProperty;
-import com.vaadin.server.VaadinRequest;
-import com.vaadin.shared.ui.label.ContentMode;
-import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.ui.Label;
-
-public class PushConfigurationTest extends AbstractTestUI {
-
- private ObjectProperty<Integer> counter = new ObjectProperty<Integer>(0);
-
- private ObjectProperty<Integer> counter2 = new ObjectProperty<Integer>(0);
-
- private final Timer timer = new Timer(true);
-
- private final TimerTask task = new TimerTask() {
-
- @Override
- public void run() {
- access(new Runnable() {
- @Override
- public void run() {
- counter2.setValue(counter2.getValue() + 1);
- }
- });
- }
- };
-
- @Override
- protected void setup(VaadinRequest request) {
- addComponent(new PushConfigurator(this));
- spacer();
-
- /*
- * Client initiated push.
- */
- Label lbl = new Label(counter);
- lbl.setCaption("Client counter (click 'increment' to update):");
- addComponent(lbl);
-
- addComponent(new Button("Increment", new Button.ClickListener() {
+import org.junit.Assert;
+import org.junit.Test;
+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.tests.tb3.WebsocketTest;
+
+public class PushConfigurationTest extends WebsocketTest {
+
+ @Test
+ public void testWebsocketAndStreaming() {
+ setDebug(true);
+ openTestURL();
+ // Websocket
+ int counter = getServerCounter();
+ assertGreaterOrEqual("Counter should be >= 1. Was: " + counter,
+ counter, 1);
+ new Select(getTransportSelect()).selectByVisibleText("WEBSOCKET");
+ new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC");
+ Assert.assertTrue(vaadinElement(
+ "/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[5]/VLabel[0]/domChild[0]")
+ .getText()
+ .matches(
+ "^[\\s\\S]*fallbackTransport: streaming[\\s\\S]*transport: websocket[\\s\\S]*$"));
+ counter = getServerCounter();
+ final int waitCounter = counter + 2;
+ waitUntil(new ExpectedCondition<Boolean>() {
@Override
- public void buttonClick(ClickEvent event) {
- counter.setValue(counter.getValue() + 1);
+ public Boolean apply(WebDriver input) {
+ return (getServerCounter() >= waitCounter);
}
- }));
-
- spacer();
-
- /*
- * Server initiated push.
- */
- lbl = new Label(counter2);
- lbl.setCaption("Server counter (updates each 1s by server thread) :");
- addComponent(lbl);
-
- addComponent(new Button("Reset", new Button.ClickListener() {
-
- @Override
- public void buttonClick(ClickEvent event) {
- counter2.setValue(0);
+ });
+
+ // Use debug console to verify we used the correct transport type
+ Assert.assertTrue(driver.getPageSource().contains(
+ "Push connection established using websocket"));
+ Assert.assertFalse(driver.getPageSource().contains(
+ "Push connection established using streaming"));
+
+ new Select(getPushModeSelect()).selectByVisibleText("DISABLED");
+
+ // Streaming
+ driver.get(getTestUrl());
+ Assert.assertEquals(1, getServerCounter());
+
+ new Select(getTransportSelect()).selectByVisibleText("STREAMING");
+ new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC");
+ Assert.assertTrue(vaadinElement(
+ "/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[5]/VLabel[0]/domChild[0]")
+ .getText()
+ .matches(
+ "^[\\s\\S]*fallbackTransport: streaming[\\s\\S]*transport: streaming[\\s\\S]*$"));
+
+ counter = getServerCounter();
+ for (int second = 0;; second++) {
+ if (second >= 5) {
+ Assert.fail("timeout");
}
- }));
- }
+ if (getServerCounter() >= (counter + 2)) {
+ break;
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ // Use debug console to verify we used the correct transport type
+ Assert.assertFalse(driver.getPageSource().contains(
+ "Push connection established using websocket"));
+ Assert.assertTrue(driver.getPageSource().contains(
+ "Push connection established using streaming"));
- @Override
- protected String getTestDescription() {
- return "This test tests the very basic operations of push. "
- + "It tests that client initiated changes are "
- + "recieved back to the client as well as server "
- + "initiated changes are correctly updated to the client.";
}
- @Override
- protected Integer getTicketNumber() {
- return 11494;
+ private WebElement getPushModeSelect() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]");
}
- private void spacer() {
- addComponent(new Label("<hr/>", ContentMode.HTML));
+ private WebElement getTransportSelect() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[1]/VNativeSelect[0]/domChild[0]");
}
- @Override
- public void attach() {
- super.attach();
- timer.scheduleAtFixedRate(task, new Date(), 1000);
+ private int getServerCounter() {
+ return Integer.parseInt(getServerCounterElement().getText());
}
- @Override
- public void detach() {
- super.detach();
- timer.cancel();
+ private WebElement getServerCounterElement() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]");
}
-}
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/PushFromInit.java b/uitest/src/com/vaadin/tests/push/PushFromInit.java
index 4b442de499..cb084f1232 100644
--- a/uitest/src/com/vaadin/tests/push/PushFromInit.java
+++ b/uitest/src/com/vaadin/tests/push/PushFromInit.java
@@ -1,3 +1,18 @@
+/*
+ * 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;
diff --git a/uitest/src/com/vaadin/tests/push/PushFromInitTest.java b/uitest/src/com/vaadin/tests/push/PushFromInitTest.java
new file mode 100644
index 0000000000..3c1bc1b610
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/PushFromInitTest.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 org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class PushFromInitTest extends MultiBrowserTest {
+ @Test
+ public void testPushFromInit() {
+ openTestURL();
+
+ for (int second = 0;; second++) {
+ if (second >= 30) {
+ Assert.fail("timeout");
+ }
+ try {
+ if ("1. Logged in init".equals(vaadinElementById(
+ "Log_row_1").getText())) {
+ break;
+ }
+ } catch (Exception e) {
+ }
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ Assert.assertEquals(
+ "2. Logged from background thread started in init",
+ vaadinElementById("Log_row_0").getText());
+
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/PushReattachedComponent.html b/uitest/src/com/vaadin/tests/push/PushReattachedComponent.html
deleted file mode 100644
index e1f6a5f048..0000000000
--- a/uitest/src/com/vaadin/tests/push/PushReattachedComponent.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://192.168.2.162:8888/" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run-push/com.vaadin.tests.components.panel.PanelChangeContents?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestscomponentspanelPanelChangeContents::/VVerticalLayout[0]/Slot[1]/VPanel[0]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
- <td>stats</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestscomponentspanelPanelChangeContents::/VVerticalLayout[0]/Slot[0]/VHorizontalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestscomponentspanelPanelChangeContents::/VVerticalLayout[0]/Slot[1]/VPanel[0]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
- <td>companies</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestscomponentspanelPanelChangeContents::/VVerticalLayout[0]/Slot[0]/VHorizontalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestscomponentspanelPanelChangeContents::/VVerticalLayout[0]/Slot[1]/VPanel[0]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
- <td>stats</td>
-</tr>
-
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/push/PushTransportAnnotation.html b/uitest/src/com/vaadin/tests/push/PushTransportAnnotation.html
deleted file mode 100644
index 854dd458bb..0000000000
--- a/uitest/src/com/vaadin/tests/push/PushTransportAnnotation.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://localhost:8888/" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.push.BasicPushStreaming?debug&amp;restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>waitForTextPresent</td>
- <td>Push connection established using streaming</td>
- <td></td>
-</tr>
-<tr>
- <td>assertTextNotPresent</td>
- <td>Push connection established using websocket</td>
- <td></td>
-</tr>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.push.BasicPushWebsocket?debug&amp;restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertTextNotPresent</td>
- <td>Push connection established using streaming</td>
- <td></td>
-</tr>
-<tr>
- <td>waitForTextPresent</td>
- <td>Push connection established using websocket</td>
- <td></td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/push/StreamingPush.html b/uitest/src/com/vaadin/tests/push/StreamingPush.html
deleted file mode 100644
index cf94a09c63..0000000000
--- a/uitest/src/com/vaadin/tests/push/StreamingPush.html
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://localhost:8888/" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run-push/com.vaadin.tests.push.BasicPush?restartApplication&amp;debug&amp;transport=streaming</td>
- <td></td>
-</tr>
-<!--Test client initiated push -->
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]</td>
- <td>0</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]</td>
- <td>1</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]</td>
- <td>4</td>
-</tr>
-<!--Test server initiated push-->
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VLabel[0]</td>
- <td>0</td>
-</tr>
-<tr>
- <td>pause</td>
- <td>3000</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VLabel[0]</td>
- <td>1</td>
-</tr>
-<tr>
- <td>pause</td>
- <td>3000</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushBasicPush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VLabel[0]</td>
- <td>2</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/push/TogglePush.html b/uitest/src/com/vaadin/tests/push/TogglePush.html
deleted file mode 100644
index b752d2120c..0000000000
--- a/uitest/src/com/vaadin/tests/push/TogglePush.html
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run-push/com.vaadin.tests.push.TogglePush?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>pause</td>
- <td>2000</td>
- <td></td>
-</tr>
-<!--Push is enabled, so text gets updated-->
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
- <td>Counter has been updated 1 times</td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
- <td>61,6</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>pause</td>
- <td>2000</td>
- <td></td>
-</tr>
-<!--Push is disabled, so text is not updated-->
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
- <td>Counter has been updated 1 times</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<!--Direct update is visible, and includes previous update-->
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
- <td>Counter has been updated 3 times</td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
- <td>61,3</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>pause</td>
- <td>2000</td>
- <td></td>
-</tr>
-<!--Push is enabled again, so text gets updated-->
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
- <td>Counter has been updated 4 times</td>
-</tr>
-
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/push/TogglePush.java b/uitest/src/com/vaadin/tests/push/TogglePush.java
index c0bdc54ee0..6ec8903d65 100644
--- a/uitest/src/com/vaadin/tests/push/TogglePush.java
+++ b/uitest/src/com/vaadin/tests/push/TogglePush.java
@@ -1,3 +1,18 @@
+/*
+ * 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.Timer;
diff --git a/uitest/src/com/vaadin/tests/push/TogglePushInInit.html b/uitest/src/com/vaadin/tests/push/TogglePushInInit.html
deleted file mode 100644
index c735f225e1..0000000000
--- a/uitest/src/com/vaadin/tests/push/TogglePushInInit.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://localhost:8071/" />
-<title>TogglePushInInit</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">TogglePushInInit</td></tr>
-</thead><tbody>
-<!--Open with push disabled-->
-<tr>
- <td>open</td>
- <td>/run-push/com.vaadin.tests.push.TogglePush?restartApplication&push=disabled</td>
- <td></td>
-</tr>
-<tr>
- <td>assertValue</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
- <td>off</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>pause</td>
- <td>2000</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
- <td>Counter has been updated 0 times</td>
-</tr>
-<!--Open with push enabled-->
-<tr>
- <td>open</td>
- <td>/run-push/com.vaadin.tests.push.TogglePush?restartApplication&amp;push=enabled</td>
- <td></td>
-</tr>
-<tr>
- <td>assertValue</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
- <td>on</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>pause</td>
- <td>2000</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runpushcomvaadintestspushTogglePush::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
- <td>Counter has been updated 1 times</td>
-</tr>
-
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/push/TogglePushTest.java b/uitest/src/com/vaadin/tests/push/TogglePushTest.java
new file mode 100644
index 0000000000..68d6f52b9f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/TogglePushTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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 org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class TogglePushTest extends MultiBrowserTest {
+
+ @Test
+ public void togglePushInInit() {
+ setPush(true);
+ String url = getTestUrl();
+
+ // Open with push disabled
+ driver.get(addParameter(url, "push=disabled"));
+
+ Assert.assertFalse(getPushToggle().isSelected());
+
+ getDelayedCounterUpdateButton().click();
+ sleep(2000);
+ Assert.assertEquals("Counter has been updated 0 times",
+ getCounterText());
+
+ // Open with push enabled
+ driver.get(addParameter(url, "push=enabled"));
+ Assert.assertTrue(getPushToggle().isSelected());
+
+ getDelayedCounterUpdateButton().click();
+ sleep(2000);
+ Assert.assertEquals("Counter has been updated 1 times",
+ getCounterText());
+
+ }
+
+ private String addParameter(String url, String queryParameter) {
+ if (url.contains("?")) {
+ return url + "&" + queryParameter;
+ } else {
+ return url + "?" + queryParameter;
+ }
+ }
+
+ @Test
+ public void togglePush() {
+ setPush(true);
+ openTestURL();
+ getDelayedCounterUpdateButton().click();
+ sleep(2000);
+
+ // Push is enabled, so text gets updated
+ Assert.assertEquals("Counter has been updated 1 times",
+ getCounterText());
+
+ // Disable push
+ getPushToggle().click();
+ getDelayedCounterUpdateButton().click();
+ sleep(2000);
+ // Push is disabled, so text is not updated
+ Assert.assertEquals("Counter has been updated 1 times",
+ getCounterText());
+
+ getDirectCounterUpdateButton().click();
+ // Direct update is visible, and includes previous update
+ Assert.assertEquals("Counter has been updated 3 times",
+ getCounterText());
+
+ // Re-enable push
+ getPushToggle().click();
+ getDelayedCounterUpdateButton().click();
+ sleep(2000);
+
+ // Push is enabled again, so text gets updated
+ Assert.assertEquals("Counter has been updated 4 times",
+ getCounterText());
+ }
+
+ private WebElement getDirectCounterUpdateButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]");
+ }
+
+ private WebElement getPushToggle() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]");
+ }
+
+ private WebElement getDelayedCounterUpdateButton() {
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]");
+ }
+
+ private String getCounterText() {
+ return vaadinElement(
+ "/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]")
+ .getText();
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUnitTests.java b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUI.java
index 062698edf5..67715339da 100644
--- a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUnitTests.java
+++ b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUI.java
@@ -35,7 +35,7 @@ import com.vaadin.ui.JavaScriptFunction;
// Load vaadinPush.js so that jQueryVaadin is defined
@JavaScript("vaadin://vaadinPush.js")
-public class TrackMessageSizeUnitTests extends AbstractTestUIWithLog {
+public class TrackMessageSizeUI extends AbstractTestUIWithLog {
private String testMethod = "function testSequence(expected, data) {\n"
+ " var request = {trackMessageLength: true, messageDelimiter: '|'};\n"
diff --git a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java
new file mode 100644
index 0000000000..f904675b5e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java
@@ -0,0 +1,30 @@
+/*
+ * 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 class TrackMessageSizeUITest extends MultiBrowserTest {
+ @Test
+ public void runTests() {
+ openTestURL();
+ Assert.assertEquals("1. All tests run",
+ vaadinElementById("Log_row_0").getText());
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUnitTests.html b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUnitTests.html
deleted file mode 100644
index 89dd7d4e78..0000000000
--- a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUnitTests.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://192.168.2.162:8888/" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.push.TrackMessageSizeUnitTests?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestspushTrackMessageSizeUnitTests::PID_SLog_row_0</td>
- <td>1. All tests run</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
new file mode 100644
index 0000000000..1967891a7a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
@@ -0,0 +1,793 @@
+/*
+ * 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;
+
+import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.logging.Logger;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Platform;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.remote.BrowserType;
+import org.openqa.selenium.remote.DesiredCapabilities;
+import org.openqa.selenium.remote.RemoteWebDriver;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+import com.vaadin.server.LegacyApplication;
+import com.vaadin.server.UIProvider;
+import com.vaadin.testbench.TestBench;
+import com.vaadin.testbench.TestBenchTestCase;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.UI;
+
+/**
+ * Base class for TestBench 3+ tests. All TB3+ tests in the project should
+ * extend this class.
+ *
+ * Provides:
+ * <ul>
+ * <li>Helpers for browser selection</li>
+ * <li>Hub connection setup and teardown</li>
+ * <li>Automatic generation of URL for a given test on the development server
+ * using {@link #getUIClass()} or by automatically finding an enclosing UI class
+ * and based on requested features, e.g. {@link #isDebug()}, {@link #isPush()}</li>
+ * <li>Generic helpers for creating TB3+ tests</li>
+ * </ul>
+ *
+ * @author Vaadin Ltd
+ */
+@RunWith(value = TB3Runner.class)
+public abstract class AbstractTB3Test extends TestBenchTestCase {
+ /**
+ * Height of the screenshots we want to capture
+ */
+ private static final int SCREENSHOT_HEIGHT = 850;
+
+ /**
+ * Width of the screenshots we want to capture
+ */
+ private static final int SCREENSHOT_WIDTH = 1500;
+
+ private DesiredCapabilities desiredCapabilities;
+
+ private boolean debug = false;
+
+ private boolean push = false;
+ {
+ // Default browser to run on unless setDesiredCapabilities is called
+ desiredCapabilities = BrowserUtil.firefox(24);
+ }
+
+ /**
+ * Connect to the hub using a remote web driver, set the canvas size and
+ * opens the initial URL as specified by {@link #getTestUrl()}
+ *
+ * @throws Exception
+ */
+ @Before
+ public void setup() throws Exception {
+ setupDriver();
+ }
+
+ /**
+ * Creates and configure the web driver to be used for the test. By default
+ * creates a remote web driver which connects to {@link #getHubURL()} and
+ * selects a browser based on {@link #getDesiredCapabilities()}.
+ *
+ * This method MUST call {@link #setDriver(WebDriver)} with the newly
+ * generated driver.
+ *
+ * @throws Exception
+ * If something goes wrong
+ */
+ protected void setupDriver() throws Exception {
+ DesiredCapabilities capabilities = getDesiredCapabilities();
+
+ WebDriver dr = TestBench.createDriver(new RemoteWebDriver(new URL(
+ getHubURL()), capabilities));
+ setDriver(dr);
+
+ int w = SCREENSHOT_WIDTH;
+ int h = SCREENSHOT_HEIGHT;
+
+ if (BrowserUtil.isIE8(capabilities)) {
+ // IE8 gets size wrong, who would have guessed...
+ w += 4;
+ h += 4;
+ }
+ try {
+ testBench().resizeViewPortTo(w, h);
+ } catch (UnsupportedOperationException e) {
+ // Opera does not support this...
+ }
+
+ }
+
+ /**
+ * Opens the given test (defined by {@link #getTestUrl(boolean, boolean)},
+ * optionally with debug window and/or push
+ *
+ * @param debug
+ * @param push
+ */
+ protected void openTestURL() {
+ driver.get(getTestUrl());
+ }
+
+ /**
+ * Returns the full URL to be used for the test
+ *
+ * @return the full URL for the test
+ */
+ protected String getTestUrl() {
+ String baseUrl = getBaseURL();
+ if (baseUrl.endsWith("/")) {
+ baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
+ }
+
+ return baseUrl + getDeploymentPath();
+ }
+
+ /**
+ *
+ * @return the location (URL) of the TB hub
+ */
+ protected String getHubURL() {
+ return "http://" + getHubHostname() + ":4444/wd/hub";
+ }
+
+ /**
+ * Used for building the hub URL to use for the test
+ *
+ * @return the host name of the TestBench hub
+ */
+ protected abstract String getHubHostname();
+
+ /**
+ * Used to determine what URL to initially open for the test
+ *
+ * @return the host name of development server
+ */
+ protected abstract String getDeploymentHostname();
+
+ /**
+ * Used to determine what port the test is running on
+ *
+ * @return The port teh test is running on, by default 8888
+ */
+ protected abstract String getDeploymentPort();
+
+ /**
+ * Produces a collection of browsers to run the test on. This method is
+ * executed by the test runner when determining how many test methods to
+ * invoke and with what parameters. For each returned value a test method is
+ * ran and before running that,
+ * {@link #setDesiredCapabilities(DesiredCapabilities)} is invoked with the
+ * value returned by this method.
+ *
+ * This method is not static to allow overriding it in sub classes. By
+ * default runs the test only on Firefox
+ *
+ * @return The browsers to run the test on
+ */
+ public Collection<DesiredCapabilities> getBrowsersToTest() {
+ return Collections.singleton(BrowserUtil.firefox(17));
+
+ }
+
+ /**
+ * Used to determine which capabilities should be used when setting up a
+ * {@link WebDriver} for this test. Typically set by a test runner or left
+ * at its default (Firefox 24). If you want to run a test on a single
+ * browser other than Firefox 24 you can override this method.
+ *
+ * @return the requested browser capabilities
+ */
+ protected DesiredCapabilities getDesiredCapabilities() {
+ return desiredCapabilities;
+ }
+
+ /**
+ * Sets the requested browser capabilities (typically browser name and
+ * version)
+ *
+ * @param desiredCapabilities
+ */
+ public void setDesiredCapabilities(DesiredCapabilities desiredCapabilities) {
+ this.desiredCapabilities = desiredCapabilities;
+ }
+
+ /**
+ * Shuts down the driver after the test has been completed
+ *
+ * @throws Exception
+ */
+ @After
+ public void tearDown() throws Exception {
+ if (driver != null) {
+ driver.quit();
+ }
+ driver = null;
+ }
+
+ /**
+ * Finds an element based on the part of a TB2 style locator following the
+ * :: (e.g. vaadin=runLabelModes::PID_Scheckboxaction-Enabled/domChild[0] ->
+ * PID_Scheckboxaction-Enabled/domChild[0]).
+ *
+ * @param vaadinLocator
+ * The part following :: of the vaadin locator string
+ * @return
+ */
+ protected WebElement vaadinElement(String vaadinLocator) {
+ return driver.findElement(vaadinLocator(vaadinLocator));
+ }
+
+ /**
+ * Find a Vaadin element based on its id given using Component.setId
+ *
+ * @param id
+ * The id to locate
+ * @return
+ */
+ public WebElement vaadinElementById(String id) {
+ return driver.findElement(vaadinLocatorById(id));
+ }
+
+ /**
+ * Finds a {@link By} locator based on the part of a TB2 style locator
+ * following the :: (e.g.
+ * vaadin=runLabelModes::PID_Scheckboxaction-Enabled/domChild[0] ->
+ * PID_Scheckboxaction-Enabled/domChild[0]).
+ *
+ * @param vaadinLocator
+ * The part following :: of the vaadin locator string
+ * @return
+ */
+ public org.openqa.selenium.By vaadinLocator(String vaadinLocator) {
+ String base = getApplicationId(getDeploymentPath());
+
+ base += "::";
+ return com.vaadin.testbench.By.vaadin(base + vaadinLocator);
+ }
+
+ /**
+ * Constructs a {@link By} locator for the id given using Component.setId
+ *
+ * @param id
+ * The id to locate
+ * @return a locator for the given id
+ */
+ public By vaadinLocatorById(String id) {
+ return vaadinLocator("PID_S" + id);
+ }
+
+ /**
+ * Waits a short while for the given condition to become true. Use e.g. as
+ * {@link #waitUntil(ExpectedConditions.textToBePresentInElement(by, text))}
+ *
+ * @param condition
+ * the condition to wait for to become true
+ */
+ protected void waitUntil(ExpectedCondition<Boolean> condition) {
+ new WebDriverWait(driver, 10).until(condition);
+ }
+
+ /**
+ * Waits a short while for the given condition to become false. Use e.g. as
+ * {@link #waitUntilNot(ExpectedConditions.textToBePresentInElement(by,
+ * text))}
+ *
+ * @param condition
+ * the condition to wait for to become false
+ */
+ protected void waitUntilNot(ExpectedCondition<Boolean> condition) {
+ new WebDriverWait(driver, 10).until(ExpectedConditions.not(condition));
+ }
+
+ /**
+ * For tests extending {@link AbstractTestUIWithLog}, returns the element
+ * for the Nth log row
+ *
+ * @param rowNr
+ * The log row to retrieve
+ * @return the Nth log row
+ */
+ protected WebElement getLogRowElement(int rowNr) {
+ return vaadinElementById("Log_row_" + rowNr);
+ }
+
+ /**
+ * For tests extending {@link AbstractTestUIWithLog}, returns the text in
+ * the Nth log row
+ *
+ * @param rowNr
+ * The log row to retrieve text for
+ * @return the text in the log row
+ */
+ protected String getLogRow(int rowNr) {
+ return getLogRowElement(rowNr).getText();
+ }
+
+ /**
+ * Asserts that {@literal a} is &gt;= {@literal b}
+ *
+ * @param message
+ * The message to include in the {@link AssertionError}
+ * @param a
+ * @param b
+ * @throws AssertionError
+ * If comparison fails
+ */
+ public static final <T> void assertGreaterOrEqual(String message,
+ Comparable<T> a, T b) throws AssertionError {
+ if (a.compareTo(b) >= 0) {
+ return;
+ }
+
+ throw new AssertionError(decorate(message, a, b));
+ }
+
+ /**
+ * Asserts that {@literal a} is &gt; {@literal b}
+ *
+ * @param message
+ * The message to include in the {@link AssertionError}
+ * @param a
+ * @param b
+ * @throws AssertionError
+ * If comparison fails
+ */
+ public static final <T> void assertGreater(String message, Comparable<T> a,
+ T b) throws AssertionError {
+ if (a.compareTo(b) > 0) {
+ return;
+ }
+ throw new AssertionError(decorate(message, a, b));
+ }
+
+ /**
+ * Asserts that {@literal a} is &lt;= {@literal b}
+ *
+ * @param message
+ * The message to include in the {@link AssertionError}
+ * @param a
+ * @param b
+ * @throws AssertionError
+ * If comparison fails
+ */
+ public static final <T> void assertLessThanOrEqual(String message,
+ Comparable<T> a, T b) throws AssertionError {
+ if (a.compareTo(b) <= 0) {
+ return;
+ }
+
+ throw new AssertionError(decorate(message, a, b));
+ }
+
+ /**
+ * Asserts that {@literal a} is &lt; {@literal b}
+ *
+ * @param message
+ * The message to include in the {@link AssertionError}
+ * @param a
+ * @param b
+ * @throws AssertionError
+ * If comparison fails
+ */
+ public static final <T> void assertLessThan(String message,
+ Comparable<T> a, T b) throws AssertionError {
+ if (a.compareTo(b) < 0) {
+ return;
+ }
+ throw new AssertionError(decorate(message, a, b));
+ }
+
+ private static <T> String decorate(String message, Comparable<T> a, T b) {
+ message = message.replace("{0}", a.toString());
+ message = message.replace("{1}", b.toString());
+ return message;
+ }
+
+ /**
+ * Returns the path that should be used for the test. The path contains the
+ * full path (appended to hostname+port) and must start with a slash.
+ *
+ * @param push
+ * true if "?debug" should be added
+ * @param debug
+ * true if /run-push should be used instead of /run
+ *
+ * @return The URL path to the UI class to test
+ */
+ protected String getDeploymentPath() {
+ Class<?> uiClass = getUIClass();
+ if (uiClass != null) {
+ return getDeploymentPath(uiClass);
+ }
+ throw new IllegalArgumentException("Unable to determine path for "
+ + getClass().getCanonicalName());
+
+ }
+
+ /**
+ * Returns the UI class the current test is connected to (or in special
+ * cases UIProvider or LegacyApplication). Uses the enclosing class if the
+ * test class is a static inner class to a UI class.
+ *
+ * Test which are not enclosed by a UI class must implement this method and
+ * return the UI class they want to test.
+ *
+ * Note that this method will update the test name to the enclosing class to
+ * be compatible with TB2 screenshot naming
+ *
+ * @return the UI class the current test is connected to
+ */
+ protected Class<?> getUIClass() {
+ try {
+ // Convention: SomeUITest uses the SomeUI UI class
+ String uiClassName = getClass().getName().replaceFirst("Test$", "");
+ Class<?> cls = Class.forName(uiClassName);
+ if (isSupportedRunnerClass(cls)) {
+ return cls;
+ }
+ } catch (Exception e) {
+ }
+ Class<?> enclosingClass = getClass().getEnclosingClass();
+ if (enclosingClass != null) {
+ if (UI.class.isAssignableFrom(enclosingClass)) {
+ Logger.getLogger(getClass().getName())
+ .severe("Test is an static inner class to the UI. This will no longer be supported in the future. The test should be named UIClassTest and reside in the same package as the UI");
+ return enclosingClass;
+ }
+ }
+ throw new RuntimeException(
+ "Could not determine UI class. Ensure the test is named UIClassTest and is in the same package as the UIClass");
+ }
+
+ /**
+ * @return true if the given class is supported by ApplicationServletRunner
+ */
+ @SuppressWarnings("deprecation")
+ private boolean isSupportedRunnerClass(Class<?> cls) {
+ if (UI.class.isAssignableFrom(cls)) {
+ return true;
+ }
+ if (UIProvider.class.isAssignableFrom(cls)) {
+ return true;
+ }
+ if (LegacyApplication.class.isAssignableFrom(cls)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns whether to run the test in debug mode (with the debug console
+ * open) or not
+ *
+ * @return true to run with the debug window open, false by default
+ */
+ protected final boolean isDebug() {
+ return debug;
+ }
+
+ /**
+ * Sets whether to run the test in debug mode (with the debug console open)
+ * or not.
+ *
+ * @param debug
+ * true to open debug window, false otherwise
+ */
+ protected final void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ /**
+ * Returns whether to run the test with push enabled (using /run-push) or
+ * not. Note that push tests can and should typically be created using @Push
+ * on the UI instead of overriding this method
+ *
+ * @return true if /run-push is used, false otherwise
+ */
+ protected final boolean isPush() {
+ return push;
+ }
+
+ /**
+ * Sets whether to run the test with push enabled (using /run-push) or not.
+ * Note that push tests can and should typically be created using @Push on
+ * the UI instead of overriding this method
+ *
+ * @param push
+ * true to use /run-push in the test, false otherwise
+ */
+ protected final void setPush(boolean push) {
+ this.push = push;
+ }
+
+ /**
+ * Returns the path for the given UI class when deployed on the test server.
+ * The path contains the full path (appended to hostname+port) and must
+ * start with a slash.
+ *
+ * This method takes into account {@link #isPush()} and {@link #isDebug()}
+ * when the path is generated.
+ *
+ * @param uiClass
+ * @param push
+ * true if "?debug" should be added
+ * @param debug
+ * true if /run-push should be used instead of /run
+ * @return The path to the given UI class
+ */
+ private String getDeploymentPath(Class<?> uiClass) {
+ String runPath = "/run";
+ if (isPush()) {
+ runPath = "/run-push";
+ }
+
+ if (UI.class.isAssignableFrom(uiClass)) {
+ return runPath + "/" + uiClass.getCanonicalName()
+ + (isDebug() ? "?debug" : "");
+ } else if (LegacyApplication.class.isAssignableFrom(uiClass)) {
+ return runPath + "/" + uiClass.getCanonicalName()
+ + "?restartApplication" + (isDebug() ? "&debug" : "");
+ } else {
+ throw new IllegalArgumentException(
+ "Unable to determine path for enclosing class "
+ + uiClass.getCanonicalName());
+ }
+ }
+
+ /**
+ * Used to determine what URL to initially open for the test
+ *
+ * @return The base URL for the test. Does not include a trailing slash.
+ */
+ protected String getBaseURL() {
+ return "http://" + getDeploymentHostname() + ":" + getDeploymentPort();
+ }
+
+ /**
+ * Generates the application id based on the URL in a way compatible with
+ * VaadinServletService.
+ *
+ * @param pathWithQueryParameters
+ * The path part of the URL, possibly still containing query
+ * parameters
+ * @return The application ID string used in Vaadin locators
+ */
+ private String getApplicationId(String pathWithQueryParameters) {
+ // Remove any possible URL parameters
+ String pathWithoutQueryParameters = pathWithQueryParameters.replaceAll(
+ "\\?.*", "");
+ if ("".equals(pathWithoutQueryParameters)) {
+ return "ROOT";
+ }
+
+ // Retain only a-z and numbers
+ return pathWithoutQueryParameters.replaceAll("[^a-zA-Z0-9]", "");
+ }
+
+ /**
+ * Helper method for sleeping X ms in a test. Catches and ignores
+ * InterruptedExceptions
+ *
+ * @param timeoutMillis
+ * Number of ms to wait
+ */
+ protected void sleep(int timeoutMillis) {
+ try {
+ Thread.sleep(timeoutMillis);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Provides helper method for selecting the browser to run on
+ *
+ * @author Vaadin Ltd
+ */
+ public static class BrowserUtil {
+ /**
+ * Gets the capabilities for Safari of the given version
+ *
+ * @param version
+ * the major version
+ * @return an object describing the capabilities required for running a
+ * test on the given Safari version
+ */
+ public static DesiredCapabilities safari(int version) {
+ DesiredCapabilities c = DesiredCapabilities.safari();
+ c.setVersion("" + version);
+ return c;
+ }
+
+ /**
+ * Gets the capabilities for Chrome of the given version
+ *
+ * @param version
+ * the major version
+ * @return an object describing the capabilities required for running a
+ * test on the given Chrome version
+ */
+ public static DesiredCapabilities chrome(int version) {
+ DesiredCapabilities c = DesiredCapabilities.chrome();
+ c.setVersion("" + version);
+ c.setPlatform(Platform.XP);
+ return c;
+ }
+
+ /**
+ * Gets the capabilities for Opera of the given version
+ *
+ * @param version
+ * the major version
+ * @return an object describing the capabilities required for running a
+ * test on the given Opera version
+ */
+ public static DesiredCapabilities opera(int version) {
+ DesiredCapabilities c = DesiredCapabilities.opera();
+ c.setVersion("" + version);
+ c.setPlatform(Platform.XP);
+ return c;
+ }
+
+ /**
+ * Gets the capabilities for Firefox of the given version
+ *
+ * @param version
+ * the major version
+ * @return an object describing the capabilities required for running a
+ * test on the given Firefox version
+ */
+ public static DesiredCapabilities firefox(int version) {
+ DesiredCapabilities c = DesiredCapabilities.firefox();
+ c.setVersion("" + version);
+ c.setPlatform(Platform.XP);
+ return c;
+ }
+
+ /**
+ * Gets the capabilities for Internet Explorer of the given version
+ *
+ * @param version
+ * the major version
+ * @return an object describing the capabilities required for running a
+ * test on the given Internet Explorer version
+ */
+ public static DesiredCapabilities ie(int version) {
+ DesiredCapabilities c = DesiredCapabilities.internetExplorer();
+ c.setVersion("" + version);
+ return c;
+ }
+
+ /**
+ * Checks if the given capabilities refer to Internet Explorer 8
+ *
+ * @param capabilities
+ * @return true if the capabilities refer to IE8, false otherwise
+ */
+ public static boolean isIE8(DesiredCapabilities capabilities) {
+ return BrowserType.IE.equals(capabilities.getBrowserName())
+ && "8".equals(capabilities.getVersion());
+ }
+
+ /**
+ * Returns a human readable identifier of the given browser. Used for
+ * test naming and screenshots
+ *
+ * @param capabilities
+ * @return a human readable string describing the capabilities
+ */
+ public static String getBrowserIdentifier(
+ DesiredCapabilities capabilities) {
+ String browserName = capabilities.getBrowserName();
+
+ if (BrowserType.IE.equals(browserName)) {
+ return "InternetExplorer";
+ } else if (BrowserType.FIREFOX.equals(browserName)) {
+ return "Firefox";
+ } else if (BrowserType.CHROME.equals(browserName)) {
+ return "Chrome";
+ } else if (BrowserType.SAFARI.equals(browserName)) {
+ return "Safari";
+ } else if (BrowserType.OPERA.equals(browserName)) {
+ return "Opera";
+ }
+
+ return browserName;
+ }
+
+ /**
+ * Returns a human readable identifier of the platform described by the
+ * given capabilities. Used mainly for screenshots
+ *
+ * @param capabilities
+ * @return a human readable string describing the platform
+ */
+ public static String getPlatform(DesiredCapabilities capabilities) {
+ if (capabilities.getPlatform() == Platform.WIN8
+ || capabilities.getPlatform() == Platform.WINDOWS
+ || capabilities.getPlatform() == Platform.VISTA
+ || capabilities.getPlatform() == Platform.XP) {
+ return "Windows";
+ } else if (capabilities.getPlatform() == Platform.MAC) {
+ return "Mac";
+ }
+ return capabilities.getPlatform().toString();
+ }
+
+ /**
+ * Returns a string which uniquely (enough) identifies this browser.
+ * Used mainly in screenshot names.
+ *
+ * @param capabilities
+ *
+ * @return a unique string for each browser
+ */
+ public static String getUniqueIdentifier(
+ DesiredCapabilities capabilities) {
+ return getUniqueIdentifier(getPlatform(capabilities),
+ getBrowserIdentifier(capabilities),
+ capabilities.getVersion());
+ }
+
+ /**
+ * Returns a string which uniquely (enough) identifies this browser.
+ * Used mainly in screenshot names.
+ *
+ * @param capabilities
+ *
+ * @return a unique string for each browser
+ */
+ public static String getUniqueIdentifier(
+ DesiredCapabilities capabilities, String versionOverride) {
+ return getUniqueIdentifier(getPlatform(capabilities),
+ getBrowserIdentifier(capabilities), versionOverride);
+ }
+
+ private static String getUniqueIdentifier(String platform,
+ String browser, String version) {
+ return platform + "_" + browser + "_" + version;
+ }
+
+ }
+
+ /**
+ * Called by the test runner whenever there is an exception in the test that
+ * will cause termination of the test
+ *
+ * @param t
+ * the throwable which caused the termination
+ */
+ public void onUncaughtException(Throwable t) {
+ // Do nothing by default
+
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java b/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java
new file mode 100644
index 0000000000..bd9027bec2
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.model.InitializationError;
+
+import com.vaadin.tests.tb3.AllTB3Tests.AllTB3TestsSuite;
+
+/**
+ * Test consisting of all TB3 tests except integration tests (classes extending
+ * AbstractTB3Test, excludes package com.vaadin.test.integration).
+ *
+ * @author Vaadin Ltd
+ */
+@RunWith(AllTB3TestsSuite.class)
+public class AllTB3Tests {
+
+ public static class AllTB3TestsSuite extends TB3TestSuite {
+
+ public AllTB3TestsSuite(Class<?> klass) throws InitializationError {
+ super(klass, AbstractTB3Test.class, "com.vaadin.tests",
+ new String[] { "com.vaadin.tests.integration" });
+ }
+
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java
new file mode 100644
index 0000000000..3553954ec0
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.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.tb3;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+/**
+ * Base class for tests which should be run on all supported browsers. The test
+ * is automatically launched for multiple browsers in parallel by the test
+ * runner.
+ *
+ * Sub classes can, but typically should not, restrict the browsers used by
+ * implementing a
+ *
+ * <pre>
+ * &#064;Parameters
+ * public static Collection&lt;DesiredCapabilities&gt; getBrowsersForTest() {
+ * }
+ * </pre>
+ *
+ * @author Vaadin Ltd
+ */
+public abstract class MultiBrowserTest extends PrivateTB3Configuration {
+
+ static List<DesiredCapabilities> allBrowsers = new ArrayList<DesiredCapabilities>();
+ static {
+ allBrowsers.add(BrowserUtil.ie(8));
+ allBrowsers.add(BrowserUtil.ie(9));
+ allBrowsers.add(BrowserUtil.ie(10));
+ allBrowsers.add(BrowserUtil.ie(11));
+ allBrowsers.add(BrowserUtil.firefox(24));
+ // Uncomment once we have the capability to run on Safari 6
+ // allBrowsers.add(safari(6));
+ allBrowsers.add(BrowserUtil.chrome(29));
+ allBrowsers.add(BrowserUtil.opera(12));
+
+ }
+
+ /**
+ * @return all supported browsers which are actively tested
+ */
+ public static List<DesiredCapabilities> getAllBrowsers() {
+ return allBrowsers;
+ }
+
+ @Override
+ public Collection<DesiredCapabilities> getBrowsersToTest() {
+ return allBrowsers;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/ParallelScheduler.java b/uitest/src/com/vaadin/tests/tb3/ParallelScheduler.java
new file mode 100644
index 0000000000..912d7d010e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/ParallelScheduler.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.tb3;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import org.junit.runners.model.RunnerScheduler;
+
+/**
+ * JUnit scheduler capable of running multiple tets in parallel. Each test is
+ * run in its own thread. Uses an {@link ExecutorService} to manage the threads.
+ *
+ * @author Vaadin Ltd
+ */
+public class ParallelScheduler implements RunnerScheduler {
+ private final List<Future<Object>> fResults = new ArrayList<Future<Object>>();
+ private ExecutorService fService;
+
+ /**
+ * Creates a parallel scheduler which will use the given executor service
+ * when submitting test jobs.
+ *
+ * @param service
+ * The service to use for tests
+ */
+ public ParallelScheduler(ExecutorService service) {
+ fService = service;
+ }
+
+ @Override
+ public void schedule(final Runnable childStatement) {
+ fResults.add(fService.submit(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ childStatement.run();
+ return null;
+ }
+ }));
+ }
+
+ @Override
+ public void finished() {
+ for (Future<Object> each : fResults) {
+ try {
+ each.get();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java
new file mode 100644
index 0000000000..09615f0b2e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-2013 Vaadind 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;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * Provides values for parameters which depend on where the test is run.
+ * Parameters should be configured in work/eclipse-run-selected-test.properties.
+ * A template is available in uitest/.
+ *
+ * @author Vaadin Ltd
+ */
+public abstract class PrivateTB3Configuration extends ScreenshotTB3Test {
+ private static final String HOSTNAME_PROPERTY = "com.vaadin.testbench.deployment.hostname";
+ private static final String PORT_PROPERTY = "com.vaadin.testbench.deployment.port";
+ private final Properties properties = new Properties();
+
+ public PrivateTB3Configuration() {
+ File file = new File("work", "eclipse-run-selected-test.properties");
+ if (file.exists()) {
+ try {
+ properties.load(new FileInputStream(file));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private String getProperty(String name) {
+ String property = properties.getProperty(name);
+ if (property == null) {
+ property = System.getProperty(name);
+ }
+
+ return property;
+ }
+
+ @Override
+ protected String getScreenshotDirectory() {
+ String screenshotDirectory = getProperty("com.vaadin.testbench.screenshot.directory");
+ if (screenshotDirectory == null) {
+ throw new RuntimeException(
+ "No screenshot directory defined. Use -Dcom.vaadin.testbench.screenshot.directory=<path>");
+ }
+ return screenshotDirectory;
+ }
+
+ @Override
+ protected String getHubHostname() {
+ return "tb3-hub.intra.itmill.com";
+ }
+
+ @Override
+ protected String getDeploymentHostname() {
+ String hostName = getProperty(HOSTNAME_PROPERTY);
+
+ if (hostName == null || "".equals(hostName)) {
+ hostName = findAutoHostname();
+ }
+
+ return hostName;
+ }
+
+ @Override
+ protected String getDeploymentPort() {
+ String port = getProperty(PORT_PROPERTY);
+
+ if (port == null || "".equals(port)) {
+ port = "8888";
+ }
+
+ return port;
+ }
+
+ /**
+ * Tries to automatically determine the IP address of the machine the test
+ * is running on.
+ *
+ * @return An IP address of one of the network interfaces in the machine.
+ * @throws RuntimeException
+ * if there was an error or no IP was found
+ */
+ private String findAutoHostname() {
+ try {
+ Enumeration<NetworkInterface> interfaces = NetworkInterface
+ .getNetworkInterfaces();
+ while (interfaces.hasMoreElements()) {
+ NetworkInterface current = interfaces.nextElement();
+ if (!current.isUp() || current.isLoopback()
+ || current.isVirtual()) {
+ continue;
+ }
+ Enumeration<InetAddress> addresses = current.getInetAddresses();
+ while (addresses.hasMoreElements()) {
+ InetAddress current_addr = addresses.nextElement();
+ if (current_addr.isLoopbackAddress()) {
+ continue;
+ }
+ String hostAddress = current_addr.getHostAddress();
+ if (hostAddress.startsWith("192.168.")) {
+ return hostAddress;
+ }
+ }
+ }
+ } catch (SocketException e) {
+ throw new RuntimeException("Could not enumerate ");
+ }
+
+ throw new RuntimeException(
+ "No compatible (192.168.*) ip address found.");
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java b/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java
new file mode 100644
index 0000000000..cbdae1a6c1
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java
@@ -0,0 +1,400 @@
+/*
+ * 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;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+import org.openqa.selenium.OutputType;
+import org.openqa.selenium.TakesScreenshot;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.Parameters;
+import com.vaadin.testbench.commands.TestBenchCommands;
+
+/**
+ * Base class which provides functionality for tests which use the automatic
+ * screenshot comparison function.
+ *
+ * @author Vaadin Ltd
+ */
+public abstract class ScreenshotTB3Test extends AbstractTB3Test {
+
+ private String screenshotBaseName;
+
+ @Rule
+ public TestRule watcher = new TestWatcher() {
+
+ @Override
+ protected void starting(org.junit.runner.Description description) {
+ Class<?> testClass = description.getTestClass();
+ // Runner adds [BrowserName] which we do not want to use in the
+ // screenshot name
+ String testMethod = description.getMethodName();
+ testMethod = testMethod.replaceAll("\\[.*\\]", "");
+
+ String className = testClass.getSimpleName();
+ screenshotBaseName = className + "-" + testMethod;
+ }
+
+ @Override
+ protected void failed(Throwable e, Description description) {
+
+ // Notify Teamcity of failed test
+ if (!System.getProperty("teamcity.version", "").equals("")) {
+ System.out.print("##teamcity[publishArtifacts '");
+ System.out.println(getScreenshotErrorBaseName()
+ + "* => screenshot-errors']");
+ }
+ }
+ };
+
+ /**
+ * Contains a list of screenshot identifiers for which
+ * {@link #compareScreen(String)} has failed during the test
+ */
+ private List<String> screenshotFailures = new ArrayList<String>();
+
+ /**
+ * Defines TestBench screen comparison parameters before each test run
+ */
+ @Before
+ public void setupScreenComparisonParameters() {
+ Parameters.setScreenshotErrorDirectory(getScreenshotErrorDirectory());
+ Parameters
+ .setScreenshotReferenceDirectory(getScreenshotReferenceDirectory());
+ }
+
+ /**
+ * Grabs a screenshot and compares with the reference image with the given
+ * identifier. Supports alternative references and will succeed if the
+ * screenshot matches at least one of the references.
+ *
+ * In case of a failed comparison this method stores the grabbed screenshots
+ * in the error directory as defined by
+ * {@link #getScreenshotErrorDirectory()}. It will also generate a html file
+ * in the same directory, comparing the screenshot with the first found
+ * reference.
+ *
+ * @param identifier
+ * @throws IOException
+ */
+ protected void compareScreen(String identifier) throws IOException {
+ if (identifier == null || identifier.isEmpty()) {
+ throw new IllegalArgumentException("Empty identifier not supported");
+ }
+
+ File mainReference = getScreenshotReferenceFile(identifier);
+
+ List<File> alternativeFiles = findReferenceAlternatives(mainReference);
+ List<File> failedReferenceAlternatives = new ArrayList<File>();
+
+ for (File file : alternativeFiles) {
+ if (testBench(driver).compareScreen(file)) {
+ break;
+ } else {
+ failedReferenceAlternatives.add(file);
+ }
+ }
+
+ File referenceToKeep = null;
+ if (failedReferenceAlternatives.size() != alternativeFiles.size()) {
+ // Matched one comparison but not all, remove all error images +
+ // HTML files
+ } else {
+ // All comparisons failed, keep the main error image + HTML
+ screenshotFailures.add(mainReference.getName());
+ referenceToKeep = mainReference;
+ }
+
+ // Remove all PNG/HTML files we no longer need (failed alternative
+ // references or all error files (PNG/HTML) if comparison succeeded)
+ for (File failedAlternative : failedReferenceAlternatives) {
+ File failurePng = getErrorFileFromReference(failedAlternative);
+ if (failedAlternative != referenceToKeep) {
+ // Delete png + HTML
+ String htmlFileName = failurePng.getName().replace(".png",
+ ".html");
+ File failureHtml = new File(failurePng.getParentFile(),
+ htmlFileName);
+
+ failurePng.delete();
+ failureHtml.delete();
+ }
+ }
+ }
+
+ /**
+ *
+ * @param referenceFile
+ * The reference image file (in the directory defined by
+ * {@link #getScreenshotReferenceDirectory()})
+ * @return the file name of the file generated in the directory defined by
+ * {@link #getScreenshotErrorDirectory()} if comparison with the
+ * given reference image fails.
+ */
+ private File getErrorFileFromReference(File referenceFile) {
+ return new File(referenceFile.getAbsolutePath().replace(
+ getScreenshotReferenceDirectory(),
+ getScreenshotErrorDirectory()));
+ }
+
+ /**
+ * Finds alternative references for the given files
+ *
+ * @param reference
+ * @return all references which should be considered when comparing with the
+ * given files, including the given reference
+ */
+ private List<File> findReferenceAlternatives(File reference) {
+ List<File> files = new ArrayList<File>();
+ files.add(reference);
+
+ File screenshotDir = reference.getParentFile();
+ String name = reference.getName();
+ // Remove ".png"
+ String nameBase = name.substring(0, name.length() - 4);
+ for (int i = 1;; i++) {
+ File file = new File(screenshotDir, nameBase + "_" + i + ".png");
+ if (file.exists()) {
+ files.add(file);
+ } else {
+ break;
+ }
+ }
+
+ return files;
+ }
+
+ /**
+ * @param testName
+ * @return the reference file name to use for the given browser, as
+ * described by {@literal capabilities}, and identifier
+ */
+ private File getScreenshotReferenceFile(String identifier) {
+ DesiredCapabilities capabilities = getDesiredCapabilities();
+
+ String originalName = getScreenshotReferenceName(identifier);
+ File exactVersionFile = new File(originalName);
+ if (exactVersionFile.exists()) {
+ return exactVersionFile;
+ }
+
+ String browserVersion = capabilities.getVersion();
+
+ if (browserVersion.matches("\\d+")) {
+ for (int version = Integer.parseInt(browserVersion); version > 0; version--) {
+ String fileName = getScreenshotReferenceName(identifier,
+ version);
+ File oldVersionFile = new File(fileName);
+ if (oldVersionFile.exists()) {
+ return oldVersionFile;
+ }
+ }
+ }
+
+ return exactVersionFile;
+ }
+
+ /**
+ * @return the base directory of 'reference' and 'errors' screenshots
+ */
+ protected abstract String getScreenshotDirectory();
+
+ /**
+ * @return the directory where reference images are stored (the 'reference'
+ * folder inside the screenshot directory)
+ */
+ private String getScreenshotReferenceDirectory() {
+ return getScreenshotDirectory() + "/reference";
+ }
+
+ /**
+ * @return the directory where comparison error images should be created
+ * (the 'errors' folder inside the screenshot directory)
+ */
+ private String getScreenshotErrorDirectory() {
+ return getScreenshotDirectory() + "/errors";
+ }
+
+ /**
+ * Checks if any screenshot comparisons failures occurred during the test
+ * and combines all comparison errors into one exception
+ *
+ * @throws IOException
+ * If there were failures during the test
+ */
+ @After
+ public void checkCompareFailures() throws IOException {
+ if (!screenshotFailures.isEmpty()) {
+ throw new IOException(
+ "The following screenshots did not match the reference: "
+ + screenshotFailures.toString());
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.tests.tb3.AbstractTB3Test#onUncaughtException(java.lang.Throwable
+ * )
+ */
+ @Override
+ public void onUncaughtException(Throwable cause) {
+ super.onUncaughtException(cause);
+ // Grab a "failure" screenshot and store in the errors folder for later
+ // analysis
+ try {
+ TestBenchCommands testBench = testBench();
+ if (testBench != null) {
+ testBench.disableWaitForVaadin();
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ try {
+ if (driver != null) {
+ BufferedImage screenshotImage = ImageIO
+ .read(new ByteArrayInputStream(
+ ((TakesScreenshot) driver)
+ .getScreenshotAs(OutputType.BYTES)));
+ ImageIO.write(screenshotImage, "png", new File(
+ getScreenshotFailureName()));
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ }
+
+ /**
+ * @return the name of a "failure" image which is stored in the folder
+ * defined by {@link #getScreenshotErrorDirectory()} when the test
+ * fails
+ */
+ private String getScreenshotFailureName() {
+ return getScreenshotErrorBaseName() + "-failure.png";
+ }
+
+ /**
+ * @return the base name used for screenshots. This is the first part of the
+ * screenshot file name, typically created as "testclass-testmethod"
+ */
+ public String getScreenshotBaseName() {
+ return screenshotBaseName;
+ }
+
+ /**
+ * Returns the name of the reference file based on the given parameters.
+ *
+ * @param testName
+ * @param capabilities
+ * @param identifier
+ * @return the full path of the reference
+ */
+ private String getScreenshotReferenceName(String identifier) {
+ return getScreenshotReferenceName(identifier, null);
+ }
+
+ /**
+ * Returns the name of the reference file based on the given parameters. The
+ * version given in {@literal capabilities} is used unless it is overridden
+ * by the {@literal versionOverride} parameter.
+ *
+ * @param testName
+ * @param capabilities
+ * @param identifier
+ * @return the full path of the reference
+ */
+ private String getScreenshotReferenceName(String identifier,
+ Integer versionOverride) {
+ String uniqueBrowserIdentifier;
+ if (versionOverride == null) {
+ uniqueBrowserIdentifier = BrowserUtil
+ .getUniqueIdentifier(getDesiredCapabilities());
+ } else {
+ uniqueBrowserIdentifier = BrowserUtil.getUniqueIdentifier(
+ getDesiredCapabilities(), "" + versionOverride);
+ }
+
+ // WindowMaximizeRestoreTest_Windows_InternetExplorer_8_window-1-moved-maximized-restored.png
+ return getScreenshotReferenceDirectory() + "/"
+ + getScreenshotBaseName() + "_" + uniqueBrowserIdentifier + "_"
+ + identifier + ".png";
+ }
+
+ /**
+ * Returns the base name of the screenshot in the error directory. This is a
+ * name so that all files matching {@link #getScreenshotErrorBaseName()}*
+ * are owned by this test instance (taking into account
+ * {@link #getDesiredCapabilities()}) and can safely be removed before
+ * running this test.
+ */
+ private String getScreenshotErrorBaseName() {
+ return getScreenshotReferenceName("dummy", null).replace(
+ getScreenshotReferenceDirectory(),
+ getScreenshotErrorDirectory()).replace("_dummy.png", "");
+ }
+
+ /**
+ * Removes any old screenshots related to this test from the errors
+ * directory before running the test
+ */
+ @Before
+ public void cleanErrorDirectory() {
+ // Remove any screenshots for this test from the error directory
+ // before running it. Leave unrelated files as-is
+ File errorDirectory = new File(getScreenshotErrorDirectory());
+
+ // Create errors directory if it does not exist
+ if (!errorDirectory.exists()) {
+ errorDirectory.mkdirs();
+ }
+
+ final String errorBase = getScreenshotErrorBaseName()
+ .replace("\\", "/");
+ File[] files = errorDirectory.listFiles(new FileFilter() {
+
+ @Override
+ public boolean accept(File pathname) {
+ String thisFile = pathname.getAbsolutePath().replace("\\", "/");
+ if (thisFile.startsWith(errorBase)) {
+ return true;
+ }
+ return false;
+ }
+ });
+ for (File f : files) {
+ f.delete();
+ }
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java b/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java
new file mode 100644
index 0000000000..c511b99e6e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.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.tb3;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.model.InitializationError;
+
+import com.vaadin.tests.integration.AbstractServletIntegrationTest;
+import com.vaadin.tests.tb3.ServletIntegrationTests.ServletIntegrationTestSuite;
+
+@RunWith(ServletIntegrationTestSuite.class)
+public class ServletIntegrationTests {
+
+ public static class ServletIntegrationTestSuite extends TB3TestSuite {
+ public ServletIntegrationTestSuite(Class<?> klass)
+ throws InitializationError {
+ super(klass, AbstractServletIntegrationTest.class,
+ "com.vaadin.tests.integration", new String[] {});
+ }
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/SimpleMultiBrowserTest.java b/uitest/src/com/vaadin/tests/tb3/SimpleMultiBrowserTest.java
new file mode 100644
index 0000000000..aeeed4198c
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/SimpleMultiBrowserTest.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.tb3;
+
+import org.junit.Test;
+
+/**
+ * A simple version of {@link MultiBrowserTest} which allows only one test
+ * method ({@link #test()}). Uses only the enclosing class name as test
+ * identifier (i.e. excludes "-test").
+ *
+ * This class is only provided as a helper for converting existing TB2 tests
+ * without renaming all screenshots. All new TB3+ tests should extend
+ * {@link MultiBrowserTest} directly instead of this.
+ *
+ * @author Vaadin Ltd
+ */
+@Deprecated
+public abstract class SimpleMultiBrowserTest extends MultiBrowserTest {
+
+ @Test
+ public abstract void test() throws Exception;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.tb3.ScreenshotTB3Test#getScreenshotBaseName()
+ */
+ @Override
+ public String getScreenshotBaseName() {
+ return super.getScreenshotBaseName().replaceFirst("-test$", "");
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/TB3Runner.java b/uitest/src/com/vaadin/tests/tb3/TB3Runner.java
new file mode 100644
index 0000000000..b612b17caa
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/TB3Runner.java
@@ -0,0 +1,154 @@
+/*
+ * 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;
+
+import java.lang.reflect.Method;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.junit.Test;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.Parameterized;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.tests.tb3.AbstractTB3Test.BrowserUtil;
+
+/**
+ * This runner is loosely based on FactoryTestRunner by Ted Young
+ * (http://tedyoung.me/2011/01/23/junit-runtime-tests-custom-runners/). The
+ * generated test names give information about the parameters used (unlike
+ * {@link Parameterized}).
+ *
+ * @since 7.1
+ */
+public class TB3Runner extends BlockJUnit4ClassRunner {
+
+ /**
+ * This is the total limit of actual JUnit test instances run in parallel
+ */
+ private static final int MAX_CONCURRENT_TESTS = 50;
+
+ /**
+ * This is static so it is shared by all tests running concurrently on the
+ * same machine and thus can limit the number of threads in use.
+ */
+ private static final ExecutorService service = Executors
+ .newFixedThreadPool(MAX_CONCURRENT_TESTS);
+
+ public TB3Runner(Class<?> klass) throws InitializationError {
+ super(klass);
+ setScheduler(new ParallelScheduler(service));
+ }
+
+ @Override
+ protected List<FrameworkMethod> computeTestMethods() {
+ List<FrameworkMethod> tests = new LinkedList<FrameworkMethod>();
+
+ if (!AbstractTB3Test.class.isAssignableFrom(getTestClass()
+ .getJavaClass())) {
+ throw new RuntimeException(getClass().getName() + " only supports "
+ + AbstractTB3Test.class.getName());
+ }
+
+ try {
+ AbstractTB3Test testClassInstance = (AbstractTB3Test) getTestClass()
+ .getOnlyConstructor().newInstance();
+ for (DesiredCapabilities capabilities : testClassInstance
+ .getBrowsersToTest()) {
+
+ // Find any methods marked with @Test.
+ for (FrameworkMethod m : getTestClass().getAnnotatedMethods(
+ Test.class)) {
+ tests.add(new TB3Method(m.getMethod(), capabilities));
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Error retrieving browsers to run on", e);
+ }
+
+ return tests;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.junit.runners.BlockJUnit4ClassRunner#withBefores(org.junit.runners
+ * .model.FrameworkMethod, java.lang.Object,
+ * org.junit.runners.model.Statement)
+ */
+ @Override
+ protected Statement withBefores(final FrameworkMethod method,
+ final Object target, Statement statement) {
+ if (!(method instanceof TB3Method)) {
+ throw new RuntimeException("Unexpected method type "
+ + method.getClass().getName() + ", expected TB3Method");
+ }
+ final TB3Method tb3method = (TB3Method) method;
+
+ // setDesiredCapabilities before running the real @Befores (which use
+ // capabilities)
+
+ final Statement realBefores = super.withBefores(method, target,
+ statement);
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ ((AbstractTB3Test) target)
+ .setDesiredCapabilities(tb3method.capabilities);
+ try {
+ realBefores.evaluate();
+ } catch (Throwable t) {
+ // Give the test a chance to e.g. produce an error
+ // screenshot before failing the test by re-throwing the
+ // exception
+ ((AbstractTB3Test) target).onUncaughtException(t);
+ throw t;
+ }
+ }
+ };
+ }
+
+ private static class TB3Method extends FrameworkMethod {
+ private DesiredCapabilities capabilities;
+
+ public TB3Method(Method method, DesiredCapabilities capabilities) {
+ super(method);
+ this.capabilities = capabilities;
+ }
+
+ @Override
+ public Object invokeExplosively(final Object target, Object... params)
+ throws Throwable {
+ // Executes the test method with the supplied parameters
+ return super.invokeExplosively(target);
+ }
+
+ @Override
+ public String getName() {
+ return String.format("%s[%s]", getMethod().getName(),
+ BrowserUtil.getUniqueIdentifier(capabilities));
+ }
+
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java
new file mode 100644
index 0000000000..e1c8edfd60
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java
@@ -0,0 +1,238 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Modifier;
+import java.net.JarURLConnection;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.jar.JarEntry;
+
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+
+/**
+ * Test suite which consists of all the TB3 tests passed in the constructor.
+ * Runs the tests in parallel using a {@link ParallelScheduler}
+ *
+ * @author Vaadin Ltd
+ */
+public class TB3TestSuite extends Suite {
+
+ /**
+ * This only restricts the number of test suites running concurrently. The
+ * number of tests to run concurrently are configured in {@link TB3Runner}.
+ */
+ private static final int MAX_CONCURRENT_TEST_SUITES = 20;
+
+ /**
+ * This is static so it is shared by all test suites running concurrently on
+ * the same machine and thus can limit the number of threads in use.
+ */
+ private final ExecutorService service = Executors
+ .newFixedThreadPool(MAX_CONCURRENT_TEST_SUITES);
+
+ public TB3TestSuite(Class<?> klass,
+ Class<? extends AbstractTB3Test> baseClass, String basePackage,
+ String[] ignorePackages) throws InitializationError {
+ super(klass, findTests(baseClass, basePackage, ignorePackages));
+ setScheduler(new ParallelScheduler(service));
+ }
+
+ /**
+ * Traverses the directory on the classpath (inside or outside a Jar file)
+ * specified by 'basePackage'. Collects all classes inside the location
+ * which can be assigned to 'baseClass' except for classes inside packages
+ * listed in 'ignoredPackages'.
+ *
+ * @param baseClass
+ * @param basePackage
+ * @param ignorePackages
+ * @return
+ */
+ private static Class<?>[] findTests(
+ Class<? extends AbstractTB3Test> baseClass, String basePackage,
+ String[] ignorePackages) {
+ try {
+ List<?> l = findClasses(baseClass, basePackage, ignorePackages);
+ return l.toArray(new Class[] {});
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Traverses the directory on the classpath (inside or outside a Jar file)
+ * specified by 'basePackage'. Collects all classes inside the location
+ * which can be assigned to 'baseClass' except for classes inside packages
+ * listed in 'ignoredPackages'.
+ *
+ * @param baseClass
+ * @param basePackage
+ * @param ignoredPackages
+ * @return
+ * @throws IOException
+ */
+ private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
+ String basePackage, String[] ignoredPackages) throws IOException {
+ List<Class<? extends T>> classes = new ArrayList<Class<? extends T>>();
+ String basePackageDirName = "/" + basePackage.replace('.', '/');
+ URL location = baseClass.getResource(basePackageDirName);
+ if (location.getProtocol().equals("file")) {
+ try {
+ File f = new File(location.toURI());
+ if (!f.exists()) {
+ throw new IOException("Directory " + f.toString()
+ + " does not exist");
+ }
+ findPackages(f, basePackage, baseClass, classes,
+ ignoredPackages);
+ } catch (URISyntaxException e) {
+ throw new IOException(e.getMessage());
+ }
+ } else if (location.getProtocol().equals("jar")) {
+ JarURLConnection juc = (JarURLConnection) location.openConnection();
+ findClassesInJar(juc, basePackage, baseClass, classes);
+ }
+
+ Collections.sort(classes, new Comparator<Class<? extends T>>() {
+
+ @Override
+ public int compare(Class<? extends T> o1, Class<? extends T> o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+
+ });
+ return classes;
+ }
+
+ /**
+ * Traverses the given directory and collects all classes which are inside
+ * the given 'javaPackage' and can be assigned to the given 'baseClass'. The
+ * found classes are added to 'result'.
+ *
+ * @param parent
+ * The directory to traverse
+ * @param javaPackage
+ * The java package which 'parent' contains
+ * @param baseClass
+ * The class which the target classes extend
+ * @param result
+ * The collection to which found classes are added
+ * @param ignoredPackages
+ * A collection of packages (including sub packages) to ignore
+ */
+ private static <T> void findPackages(File parent, String javaPackage,
+ Class<T> baseClass, Collection<Class<? extends T>> result,
+ String[] ignoredPackages) {
+ for (String ignoredPackage : ignoredPackages) {
+ if (javaPackage.equals(ignoredPackage)) {
+ return;
+ }
+ }
+
+ for (File file : parent.listFiles()) {
+ if (file.isDirectory()) {
+ findPackages(file, javaPackage + "." + file.getName(),
+ baseClass, result, ignoredPackages);
+ } else if (file.getName().endsWith(".class")) {
+ String fullyQualifiedClassName = javaPackage + "."
+ + file.getName().replace(".class", "");
+ addClassIfMatches(result, fullyQualifiedClassName, baseClass);
+ }
+ }
+
+ }
+
+ /**
+ * Traverses a Jar file using the given connection and collects all classes
+ * which are inside the given 'javaPackage' and can be assigned to the given
+ * 'baseClass'. The found classes are added to 'result'.
+ *
+ * @param javaPackage
+ * The java package containing the classes (classes may be in a
+ * sub package)
+ * @param baseClass
+ * The class which the target classes extend
+ * @param result
+ * The collection to which found classes are added
+ * @throws IOException
+ */
+ private static <T> void findClassesInJar(JarURLConnection juc,
+ String javaPackage, Class<T> baseClass,
+ Collection<Class<? extends T>> result) throws IOException {
+ String javaPackageDir = javaPackage.replace('.', '/');
+ Enumeration<JarEntry> ent = juc.getJarFile().entries();
+ while (ent.hasMoreElements()) {
+ JarEntry e = ent.nextElement();
+ if (e.getName().endsWith(".class")
+ && e.getName().startsWith(javaPackageDir)) {
+ String fullyQualifiedClassName = e.getName().replace('/', '.')
+ .replace(".class", "");
+ addClassIfMatches(result, fullyQualifiedClassName, baseClass);
+ }
+ }
+ }
+
+ /**
+ * Verifies that the class represented by 'fullyQualifiedClassName' can be
+ * loaded, assigned to 'baseClass' and is not an abstract or anonymous
+ * class.
+ *
+ * @param result
+ * The collection to add to
+ * @param fullyQualifiedClassName
+ * The candidate class
+ * @param baseClass
+ * The class 'fullyQualifiedClassName' should be assignable to
+ */
+ @SuppressWarnings("unchecked")
+ private static <T> void addClassIfMatches(
+ Collection<Class<? extends T>> result,
+ String fullyQualifiedClassName, Class<T> baseClass) {
+ try {
+ // Try to load the class
+
+ Class<?> c = Class.forName(fullyQualifiedClassName);
+ if (!baseClass.isAssignableFrom(c)) {
+ return;
+ }
+ if (!Modifier.isAbstract(c.getModifiers()) && !c.isAnonymousClass()) {
+ result.add((Class<? extends T>) c);
+ }
+ } catch (Exception e) {
+ // Could ignore that class cannot be loaded
+ e.printStackTrace();
+ } catch (LinkageError e) {
+ // Ignore. Client side classes will at least throw LinkageErrors
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/tb3/WebsocketTest.java b/uitest/src/com/vaadin/tests/tb3/WebsocketTest.java
new file mode 100644
index 0000000000..5c6ea329f5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/WebsocketTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+/**
+ * A {@link MultiBrowserTest} which restricts the tests to the browsers which
+ * support websocket
+ *
+ * @author Vaadin Ltd
+ */
+public abstract class WebsocketTest extends PrivateTB3Configuration {
+ private static List<DesiredCapabilities> websocketBrowsers = new ArrayList<DesiredCapabilities>();
+ static {
+ websocketBrowsers.addAll(MultiBrowserTest.getAllBrowsers());
+ websocketBrowsers.remove(BrowserUtil.ie(8));
+ websocketBrowsers.remove(BrowserUtil.ie(9));
+ }
+
+ /**
+ * @return All supported browsers which are actively tested and support
+ * websockets
+ */
+ public static Collection<DesiredCapabilities> getWebsocketBrowsers() {
+ return Collections.unmodifiableCollection(websocketBrowsers);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.tb3.AbstractTB3Test#getBrowserToRunOn()
+ */
+ @Override
+ public Collection<DesiredCapabilities> getBrowsersToTest() {
+ return getWebsocketBrowsers();
+ }
+}