<dependency org="junit" name="junit" rev="4.11"
conf="build,ide -> default" />
-
+ <dependency org="com.jcraft" name="jsch" rev="0.1.50"
+ conf="ide, build->default" />
<dependency org="commons-codec" name="commons-codec"
rev="1.5" conf="build,ide->default" />
<dependency org="commons-io" name="commons-io" rev="2.2"
@Push
public class BasicPush extends AbstractTestUI {
+ public static final String CLIENT_COUNTER_ID = "clientCounter";
+
+ public static final String STOP_TIMER_ID = "stopTimer";
+
+ public static final String START_TIMER_ID = "startTimer";
+
+ public static final String SERVER_COUNTER_ID = "serverCounter";
+
+ public static final String INCREMENT_BUTTON_ID = "clientCounter";
+
private ObjectProperty<Integer> counter = new ObjectProperty<Integer>(0);
private ObjectProperty<Integer> counter2 = new ObjectProperty<Integer>(0);
*/
Label lbl = new Label(counter);
lbl.setCaption("Client counter (click 'increment' to update):");
+ lbl.setId(CLIENT_COUNTER_ID);
addComponent(lbl);
- addComponent(new Button("Increment", new Button.ClickListener() {
+ Button incrementButton = new Button("Increment",
+ new Button.ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- counter.setValue(counter.getValue() + 1);
- }
- }));
+ @Override
+ public void buttonClick(ClickEvent event) {
+ counter.setValue(counter.getValue() + 1);
+ }
+ });
+ incrementButton.setId(INCREMENT_BUTTON_ID);
+ addComponent(incrementButton);
spacer();
*/
lbl = new Label(counter2);
lbl.setCaption("Server counter (updates each 3s by server thread) :");
+ lbl.setId(SERVER_COUNTER_ID);
addComponent(lbl);
- 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() {
+ Button startTimer = new Button("Start timer",
+ new Button.ClickListener() {
@Override
- public void run() {
- access(new Runnable() {
+ public void buttonClick(ClickEvent event) {
+ counter2.setValue(0);
+ if (task != null) {
+ task.cancel();
+ }
+ task = new TimerTask() {
+
@Override
public void run() {
- counter2.setValue(counter2.getValue() + 1);
+ access(new Runnable() {
+ @Override
+ public void run() {
+ counter2.setValue(counter2.getValue() + 1);
+ }
+ });
}
- });
+ };
+ timer.scheduleAtFixedRate(task, 3000, 3000);
}
- };
- timer.scheduleAtFixedRate(task, 3000, 3000);
- }
- }));
+ });
+ startTimer.setId(START_TIMER_ID);
+ addComponent(startTimer);
- addComponent(new Button("Stop timer", new Button.ClickListener() {
+ Button stopTimer = new Button("Stop timer", new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
if (task != null) {
task = null;
}
}
- }));
+ });
+ stopTimer.setId(STOP_TIMER_ID);
+ addComponent(stopTimer);
}
@Override
import org.junit.Test;
import org.openqa.selenium.WebElement;
+import com.vaadin.tests.tb3.AbstractTB3Test;
import com.vaadin.tests.tb3.MultiBrowserTest;
public abstract class BasicPushTest extends MultiBrowserTest {
// Test client initiated push
Assert.assertEquals(0, getClientCounter());
getIncrementButton().click();
- Assert.assertEquals(
- "Client counter not incremented by button click", 1,
- getClientCounter());
+ 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());
+ Assert.assertEquals("Four clicks should have incremented counter to 4",
+ 4, getClientCounter());
// Test server initiated push
getServerCounterStartButton().click();
}
private int getServerCounter() {
- return Integer.parseInt(getServerCounterElement().getText());
+ return getServerCounter(this);
}
private int getClientCounter() {
- return Integer.parseInt(getClientCounterElement().getText());
+ return getClientCounter(this);
}
- private WebElement getServerCounterElement() {
- return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VLabel[0]");
+ public static int getClientCounter(AbstractTB3Test t) {
+ WebElement clientCounterElem = t
+ .vaadinElementById(BasicPush.CLIENT_COUNTER_ID);
+ return Integer.parseInt(clientCounterElem.getText());
}
- private WebElement getServerCounterStartButton() {
- return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]");
+ private WebElement getIncrementButton() {
+ return getIncrementButton(this);
}
private WebElement getServerCounterStopButton() {
- return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[6]/VButton[0]/domChild[0]/domChild[0]");
+ return getServerCounterStopButton(this);
}
- private WebElement getIncrementButton() {
- return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]");
+ private WebElement getServerCounterStartButton() {
+ return getServerCounterStartButton(this);
+ }
+
+ public static int getServerCounter(AbstractTB3Test t) {
+ WebElement serverCounterElem = t
+ .vaadinElementById(BasicPush.SERVER_COUNTER_ID);
+ return Integer.parseInt(serverCounterElem.getText());
}
- private WebElement getClientCounterElement() {
- return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]");
+ public static WebElement getServerCounterStartButton(AbstractTB3Test t) {
+ return t.vaadinElementById(BasicPush.START_TIMER_ID);
}
+
+ public static WebElement getServerCounterStopButton(AbstractTB3Test t) {
+ return t.vaadinElementById(BasicPush.STOP_TIMER_ID);
+ }
+
+ public static WebElement getIncrementButton(AbstractTB3Test t) {
+ return t.vaadinElementById(BasicPush.INCREMENT_BUTTON_ID);
+ }
+
}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+
+import com.vaadin.tests.tb3.MultiBrowserTestWithProxy;
+
+public abstract class PushReconnectTest extends MultiBrowserTestWithProxy {
+
+ @Test
+ public void testShortDisconnect() throws Exception {
+ setDebug(true);
+ openTestURL();
+ startTimer();
+ waitUntilServerCounterChanges();
+ disconnectProxy();
+ Thread.sleep(1000);
+ connectProxy();
+ waitUntilServerCounterChanges();
+ }
+
+ @Test
+ public void testUserActionWhileDisconnected() throws Exception {
+ setDebug(true);
+ openTestURL();
+ startTimer();
+ waitUntilServerCounterChanges();
+ disconnectProxy();
+ Assert.assertEquals(0, getClientCounter());
+ getIncrementClientCounterButton().click();
+ // No change while disconnected
+ Assert.assertEquals(0, getClientCounter());
+ Thread.sleep(1000);
+ connectProxy();
+ waitUntilServerCounterChanges();
+ // The change should have appeared when reconnected
+ Assert.assertEquals(1, getClientCounter());
+ }
+
+ @Test
+ public void testLongDisconnect() throws Exception {
+ setDebug(true);
+ openTestURL();
+ startTimer();
+ waitUntilServerCounterChanges();
+ disconnectProxy();
+ Thread.sleep(12000);
+ connectProxy();
+ waitUntilServerCounterChanges();
+ }
+
+ @Test
+ public void testMultipleDisconnects() throws Exception {
+ setDebug(true);
+ openTestURL();
+ startTimer();
+ waitUntilServerCounterChanges();
+ for (int i = 0; i < 5; i++) {
+ disconnectProxy();
+ Thread.sleep(1000);
+ connectProxy();
+ waitUntilServerCounterChanges();
+ }
+ }
+
+ @Test
+ public void testMultipleQuickReconnects() throws Exception {
+ setDebug(true);
+ openTestURL();
+ startTimer();
+ waitUntilServerCounterChanges();
+ for (int i = 0; i < 50; i++) {
+ disconnectProxy();
+ Thread.sleep(50);
+ connectProxy();
+ Thread.sleep(50);
+ }
+ waitUntilServerCounterChanges();
+ waitUntilServerCounterChanges();
+ }
+
+ private int getClientCounter() {
+ return BasicPushTest.getClientCounter(this);
+ }
+
+ private WebElement getIncrementClientCounterButton() {
+ return BasicPushTest.getIncrementButton(this);
+ }
+
+ private void waitUntilServerCounterChanges() {
+ final int counter = BasicPushTest.getServerCounter(this);
+ waitUntil(new ExpectedCondition<Boolean>() {
+
+ @Override
+ public Boolean apply(WebDriver input) {
+ return BasicPushTest.getServerCounter(PushReconnectTest.this) > counter;
+ }
+ });
+ }
+
+ private void startTimer() {
+ BasicPushTest.getServerCounterStartButton(this).click();
+ }
+
+}
--- /dev/null
+/*
+ * 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 StreamingReconnectTest extends PushReconnectTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return BasicPushStreaming.class;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.push;
+
+import java.util.List;
+
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.tests.tb3.WebsocketTest;
+
+public class WebsocketReconnectTest extends PushReconnectTest {
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ return WebsocketTest.getWebsocketBrowsers();
+ }
+
+ @Override
+ protected Class<?> getUIClass() {
+ return BasicPushWebsocket.class;
+ }
+
+}
*
* @return The port teh test is running on, by default 8888
*/
- protected abstract String getDeploymentPort();
+ protected abstract int getDeploymentPort();
/**
* Produces a collection of browsers to run the test on. This method is
--- /dev/null
+/*
+ * 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.concurrent.atomic.AtomicInteger;
+
+import org.junit.After;
+import org.junit.Before;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+public abstract class MultiBrowserTestWithProxy extends MultiBrowserTest {
+
+ private static AtomicInteger availablePort = new AtomicInteger(2000);
+ private Session proxySession;
+ private Integer proxyPort = null;
+
+ @Before
+ public void setupInitialProxy() throws JSchException {
+ connectProxy();
+ }
+
+ @After
+ public void teardownProxy() {
+ disconnectProxy();
+ }
+
+ protected Integer getProxyPort() {
+ if (proxyPort == null) {
+ // Assumes we can use any port >= 2000
+ proxyPort = availablePort.addAndGet(1);
+ }
+ return proxyPort;
+ }
+
+ /**
+ * Disconnects the proxy if active
+ */
+ protected void disconnectProxy() {
+ if (proxySession == null) {
+ return;
+ }
+ proxySession.disconnect();
+ proxySession = null;
+ }
+
+ /**
+ * Ensure the proxy is active. Does nothing if the proxy is already active.
+ */
+ protected void connectProxy() throws JSchException {
+ if (proxySession != null) {
+ return;
+ }
+
+ createProxy(getProxyPort());
+ }
+
+ private void createProxy(int proxyPort) throws JSchException {
+ JSch j = new JSch();
+ String keyFile = System.getProperty("sshkey.file");
+ if (keyFile == null) {
+ keyFile = "~/.ssh/id_rsa";
+ }
+ j.addIdentity(keyFile);
+ proxySession = j.getSession("localhost");
+ proxySession.setConfig("StrictHostKeyChecking", "no");
+ proxySession.setPortForwardingL("0.0.0.0", proxyPort,
+ super.getDeploymentHostname(), super.getDeploymentPort());
+ proxySession.connect();
+ }
+
+ @Override
+ protected String getBaseURL() {
+ return "http://" + getDeploymentHostname() + ":" + getProxyPort();
+ }
+
+}
}
@Override
- protected String getDeploymentPort() {
- String port = getProperty(PORT_PROPERTY);
+ protected int getDeploymentPort() {
+ String portString = getProperty(PORT_PROPERTY);
- if (port == null || "".equals(port)) {
- port = "8888";
+ int port = 8888;
+ if (portString != null && !"".equals(portString)) {
+ port = Integer.parseInt(portString);
}
return port;