summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenri Sara <hesara@vaadin.com>2014-07-07 14:09:42 +0300
committerHenri Sara <hesara@vaadin.com>2014-07-07 14:10:19 +0300
commitbe819fcbe19750fc0c390fbb55819376af047188 (patch)
treee35e6a889f2e261f645de1c1fb04f82b2fbda29c
parenta91d4ed98b86fbf61138723d5903c63867194d12 (diff)
parent8c36375edb9cadfec64a67f034d2a6828242df6f (diff)
downloadvaadin-framework-be819fcbe19750fc0c390fbb55819376af047188.tar.gz
vaadin-framework-be819fcbe19750fc0c390fbb55819376af047188.zip
Merge branch 'master' into 7.37.3.0.beta1
Change-Id: I0efe8538f2472d1a6cf5ec10aadcde13ed39f9ad
-rw-r--r--WebContent/VAADIN/themes/base/datefield/datefield.scss3
-rw-r--r--WebContent/VAADIN/themes/chameleon/common/common.scss11
-rw-r--r--WebContent/VAADIN/themes/runo/common/common.scss5
-rw-r--r--WebContent/WEB-INF/web.xml11
-rw-r--r--build.properties2
-rw-r--r--client/src/com/vaadin/client/Profiler.java28
-rw-r--r--server/src/com/vaadin/server/AbstractClientConnector.java118
-rw-r--r--server/src/com/vaadin/ui/ConnectorTracker.java2
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java2
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java22
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcButtonConnector.java123
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTest.java34
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTestAsync.java32
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpc.java56
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcButton.java30
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcServletTest.java35
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java43
17 files changed, 471 insertions, 86 deletions
diff --git a/WebContent/VAADIN/themes/base/datefield/datefield.scss b/WebContent/VAADIN/themes/base/datefield/datefield.scss
index d094235c0f..57a691211d 100644
--- a/WebContent/VAADIN/themes/base/datefield/datefield.scss
+++ b/WebContent/VAADIN/themes/base/datefield/datefield.scss
@@ -95,6 +95,9 @@
}
.#{$primaryStyleName}-popup {
background: #fff;
+ .v-ie9 &, .v-ie10 &, .v-ie11 & {
+ box-shadow: 0 2px 10px 0 rgba(0, 0, 0, .5);
+ }
}
.#{$primaryStyleName}-popupcalendar input.#{$primaryStyleName}-textfield {
-webkit-box-sizing: border-box;
diff --git a/WebContent/VAADIN/themes/chameleon/common/common.scss b/WebContent/VAADIN/themes/chameleon/common/common.scss
index b8233fc53b..7bee2f529c 100644
--- a/WebContent/VAADIN/themes/chameleon/common/common.scss
+++ b/WebContent/VAADIN/themes/chameleon/common/common.scss
@@ -91,8 +91,6 @@ $chameleon-line-height: 1.4;
.v-contextmenu,
.v-Notification,
.v-menubar-submenu {
- background: #fff url(../img/grad-light-top.png) repeat-x;
- background-color: rgba(255,255,255,.85);
border: 1px solid #adadad;
border-color: rgba(0,0,0,.4);
border-radius: 4px;
@@ -100,7 +98,14 @@ $chameleon-line-height: 1.4;
-moz-border-radius: 4px;
overflow: hidden;
}
-
+ .v-window,
+ .v-popupview-popup,
+ .v-filterselect-suggestpopup,
+ .v-datefield-popup,
+ .v-contextmenu,
+ .v-menubar-submenu{
+ background: rgba(232,232,232,.90) url(../img/grad-light-top.png) repeat-x;
+ }
.v-filterselect-suggestpopup,
.v-contextmenu,
.v-menubar-submenu {
diff --git a/WebContent/VAADIN/themes/runo/common/common.scss b/WebContent/VAADIN/themes/runo/common/common.scss
index c33b490411..207660c08e 100644
--- a/WebContent/VAADIN/themes/runo/common/common.scss
+++ b/WebContent/VAADIN/themes/runo/common/common.scss
@@ -41,9 +41,8 @@
.v-window
.v-datefield-popup,
.v-filterselect-suggestpopup,
-.v-menubar-menuitem,
-.v-slider-popup,
-.v-tooltip-text,
+.v-menubar-popup,
+.v-slider-feedback,
.v-popupview-popup,
.v-contextmenu {
box-shadow: 0 2px 5px 0 rgba(0,0,0, .28);
diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml
index 268fe1ea66..fb2ddbd998 100644
--- a/WebContent/WEB-INF/web.xml
+++ b/WebContent/WEB-INF/web.xml
@@ -44,6 +44,11 @@
<async-supported>true</async-supported>
</servlet>
<servlet>
+ <servlet-name>GwtRpcTest</servlet-name>
+ <servlet-class>com.vaadin.tests.widgetset.server.gwtrpc.GwtRpcServletTest</servlet-class>
+ </servlet>
+
+ <servlet>
<servlet-name>UI provider app</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
@@ -134,15 +139,19 @@
<param-value>false</param-value>
</init-param>
</servlet>
+
<servlet-mapping>
<servlet-name>Embed App 1</servlet-name>
<url-pattern>/embed1/*</url-pattern>
</servlet-mapping>
-
<servlet-mapping>
<servlet-name>Embed App 2</servlet-name>
<url-pattern>/embed2/*</url-pattern>
</servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>GwtRpcTest</servlet-name>
+ <url-pattern>/VAADIN/widgetsets/com.vaadin.tests.widgetset.TestingWidgetSet/GwtRpcTest/*</url-pattern>
+ </servlet-mapping>
<servlet-mapping>
<servlet-name>UI provider app</servlet-name>
diff --git a/build.properties b/build.properties
index a7871ad1ef..0c0e58cb53 100644
--- a/build.properties
+++ b/build.properties
@@ -5,6 +5,6 @@ vaadin.vendor=Vaadin Ltd
vaadin.url=http://vaadin.com
vaadin.java.version=1.6
vaadin.version=0.0.0.unversioned-development-build
-vaadin.sass.version=0.9.7
+vaadin.sass.version=0.9.8
gwt.version=2.6.0.vaadin3
commons-io.version=2.4
diff --git a/client/src/com/vaadin/client/Profiler.java b/client/src/com/vaadin/client/Profiler.java
index 2174e00de1..6c0967099f 100644
--- a/client/src/com/vaadin/client/Profiler.java
+++ b/client/src/com/vaadin/client/Profiler.java
@@ -1,12 +1,12 @@
/*
* Copyright 2000-2014 Vaadin Ltd.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -37,14 +37,14 @@ import com.vaadin.client.debug.internal.ProfilerSection.ProfilerResultConsumer;
* zero overhead unless enabled. To enable profiling, add
* <code>&lt;set-property name="vaadin.profiler" value="true" /&gt;</code> to
* your .gwt.xml file.
- *
+ *
* @author Vaadin Ltd
* @since 7.0.0
*/
public class Profiler {
/**
* Class to include using deferred binding to enable the profiling.
- *
+ *
* @author Vaadin Ltd
* @since 7.0.0
*/
@@ -101,7 +101,7 @@ public class Profiler {
/**
* Checks whether the profiling gathering is enabled.
- *
+ *
* @return <code>true</code> if the profiling is enabled, else
* <code>false</code>
*/
@@ -115,7 +115,7 @@ public class Profiler {
* Enters a named block. There should always be a matching invocation of
* {@link #leave(String)} when leaving the block. Calls to this method will
* be removed by the compiler unless profiling is enabled.
- *
+ *
* @param name
* the name of the entered block
*/
@@ -129,7 +129,7 @@ public class Profiler {
* Leaves a named block. There should always be a matching invocation of
* {@link #enter(String)} when entering the block. Calls to this method will
* be removed by the compiler unless profiling is enabled.
- *
+ *
* @param name
* the name of the left block
*/
@@ -178,7 +178,7 @@ public class Profiler {
* enabled because it will then remove a logger function that might have
* been included in the HTML page and that would leak memory unless removed.
* </p>
- *
+ *
* @since 7.0.2
*/
public static void initialize() {
@@ -281,7 +281,7 @@ public class Profiler {
/**
* Overridden in {@link EnabledProfiler} to make {@link #isEnabled()} return
* true if GWT.create returns that class.
- *
+ *
* @return <code>true</code> if the profiling is enabled, else
* <code>false</code>
*/
@@ -352,7 +352,7 @@ public class Profiler {
if (typeof $wnd.__gwtStatsEvent != 'function') {
if (typeof $wnd.vaadin.gwtStatsEvents != 'object') {
$wnd.vaadin.gwtStatsEvents = [];
- }
+ }
$wnd.__gwtStatsEvent = function(event) {
$wnd.vaadin.gwtStatsEvents.push(event);
return true;
@@ -369,9 +369,9 @@ public class Profiler {
if (typeof $wnd.vaadin.gwtStatsEvents == 'object') {
delete $wnd.vaadin.gwtStatsEvents;
if (typeof $wnd.__gwtStatsEvent == 'function') {
- $wnd.__gwtStatsEvent = function(){};
+ $wnd.__gwtStatsEvent = function() { return true; };
}
- }
+ }
}-*/;
private static native JsArray<GwtStatsEvent> clearEventsList()
@@ -385,7 +385,7 @@ public class Profiler {
* <p>
* <b>Warning!</b> This is internal API and should not be used by
* applications or add-ons.
- *
+ *
* @since 7.1.4
* @param profilerResultConsumer
* the consumer that gets profiler data
diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java
index bafecdabf4..03300b20e2 100644
--- a/server/src/com/vaadin/server/AbstractClientConnector.java
+++ b/server/src/com/vaadin/server/AbstractClientConnector.java
@@ -41,6 +41,7 @@ import com.vaadin.shared.communication.ClientRpc;
import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.communication.SharedState;
import com.vaadin.shared.ui.ComponentStateUtil;
+import com.vaadin.ui.Component;
import com.vaadin.ui.Component.Event;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.LegacyComponent;
@@ -339,31 +340,6 @@ public abstract class AbstractClientConnector implements ClientConnector,
}
}
- private static final class AllChildrenIterable implements
- Iterable<ClientConnector>, Serializable {
- private final ClientConnector connector;
-
- private AllChildrenIterable(ClientConnector connector) {
- this.connector = connector;
- }
-
- @Override
- public Iterator<ClientConnector> iterator() {
- CombinedIterator<ClientConnector> iterator = new CombinedIterator<ClientConnector>();
-
- if (connector instanceof HasComponents) {
- HasComponents hasComponents = (HasComponents) connector;
- iterator.addIterator(hasComponents.iterator());
- }
-
- Collection<Extension> extensions = connector.getExtensions();
- if (extensions.size() > 0) {
- iterator.addIterator(extensions.iterator());
- }
- return iterator;
- }
- }
-
private class RpcInvocationHandler implements InvocationHandler,
Serializable {
@@ -493,41 +469,6 @@ public abstract class AbstractClientConnector implements ClientConnector,
}
}
- private static final class CombinedIterator<T> implements Iterator<T>,
- Serializable {
-
- private final Collection<Iterator<? extends T>> iterators = new ArrayList<Iterator<? extends T>>();
-
- public void addIterator(Iterator<? extends T> iterator) {
- iterators.add(iterator);
- }
-
- @Override
- public boolean hasNext() {
- for (Iterator<? extends T> i : iterators) {
- if (i.hasNext()) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public T next() {
- for (Iterator<? extends T> i : iterators) {
- if (i.hasNext()) {
- return i.next();
- }
- }
- throw new NoSuchElementException();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
/**
* Get an Iterable for iterating over all child connectors, including both
* extensions and child components.
@@ -536,9 +477,62 @@ public abstract class AbstractClientConnector implements ClientConnector,
* the connector to get children for
* @return an Iterable giving all child connectors.
*/
- public static Iterable<ClientConnector> getAllChildrenIterable(
+ public static Iterable<? extends ClientConnector> getAllChildrenIterable(
final ClientConnector connector) {
- return new AllChildrenIterable(connector);
+
+ Collection<Extension> extensions = connector.getExtensions();
+ boolean hasComponents = connector instanceof HasComponents;
+ boolean hasExtensions = extensions.size() > 0;
+ if (!hasComponents && !hasExtensions) {
+ // If has neither component nor extensions, return immutable empty
+ // list as iterable.
+ return Collections.emptyList();
+ }
+ if (hasComponents && !hasExtensions) {
+ // only components
+ return (HasComponents) connector;
+ }
+ if (!hasComponents && hasExtensions) {
+ // only extensions
+ return extensions;
+ }
+
+ // combine the iterators of extensions and components to a new iterable.
+ final Iterator<Component> componentsIterator = ((HasComponents) connector)
+ .iterator();
+ final Iterator<Extension> extensionsIterator = extensions.iterator();
+ Iterable<? extends ClientConnector> combinedIterable = new Iterable<ClientConnector>() {
+
+ @Override
+ public Iterator<ClientConnector> iterator() {
+ return new Iterator<ClientConnector>() {
+
+ @Override
+ public boolean hasNext() {
+ return componentsIterator.hasNext()
+ || extensionsIterator.hasNext();
+ }
+
+ @Override
+ public ClientConnector next() {
+ if (componentsIterator.hasNext()) {
+ return componentsIterator.next();
+ }
+ if (extensionsIterator.hasNext()) {
+ return extensionsIterator.next();
+ }
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ };
+ }
+ };
+ return combinedIterable;
}
@Override
diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java
index c0f973106b..b5a0227d99 100644
--- a/server/src/com/vaadin/ui/ConnectorTracker.java
+++ b/server/src/com/vaadin/ui/ConnectorTracker.java
@@ -366,7 +366,7 @@ public class ConnectorTracker implements Serializable {
ClientConnector connector = stack.pop();
danglingConnectors.remove(connector);
- Iterable<ClientConnector> children = AbstractClientConnector
+ Iterable<? extends ClientConnector> children = AbstractClientConnector
.getAllChildrenIterable(connector);
for (ClientConnector child : children) {
stack.add(child);
diff --git a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
index e938a1cd37..63f79504ff 100644
--- a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
+++ b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
@@ -63,6 +63,8 @@ public class TestClassesSerializable extends TestCase {
"com\\.vaadin\\.sass.*", //
"com\\.vaadin\\.testbench.*", //
"com\\.vaadin\\.util\\.CurrentInstance\\$1", //
+ "com\\.vaadin\\.server\\.AbstractClientConnector\\$1", //
+ "com\\.vaadin\\.server\\.AbstractClientConnector\\$1\\$1", //
"com\\.vaadin\\.server\\.JsonCodec\\$1", //
"com\\.vaadin\\.server\\.communication\\.PushConnection", //
"com\\.vaadin\\.server\\.communication\\.AtmospherePushConnection", //
diff --git a/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java b/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java
index cf756034a1..c80a74599d 100644
--- a/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java
+++ b/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java
@@ -34,7 +34,7 @@ public class LocaleChangeTest extends MultiBrowserTest {
assertPopupOpen(true);
// Close the popup and change the locale.
- toggleDatePopup();
+ toggleDatePopupWorkaroundClosePopupIE();
assertPopupOpen(false);
driver.findElement(By.className("v-button")).click(); // Locale change.
@@ -55,6 +55,26 @@ public class LocaleChangeTest extends MultiBrowserTest {
driver.findElement(By.className("v-datefield-button")).click();
}
+ /*
+ * Work around bug reported in ticket #14086. Delete this method once fixed
+ * andd use toggleDatePopup() instead.
+ */
+ private void toggleDatePopupWorkaroundClosePopupIE() {
+ if (!BrowserUtil.isIE(getDesiredCapabilities())) {
+ driver.findElement(By.className("v-datefield-button")).click();
+ } else {
+ boolean popupOpen = driver.findElements(
+ By.className("v-datefield-popup")).size() == 1;
+ if (popupOpen) {
+ driver.findElement(
+ By.className("v-datefield-calendarpanel-day-selected"))
+ .click();
+ } else {
+ driver.findElement(By.className("v-datefield-button")).click();
+ }
+ }
+ }
+
private String getDateValue() {
return driver.findElement(By.className("v-datefield-textfield"))
.getAttribute("value");
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcButtonConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcButtonConnector.java
new file mode 100644
index 0000000000..43d96afd2b
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcButtonConnector.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.widgetset.client.gwtrpc;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.google.gwt.core.shared.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.Label;
+import com.vaadin.client.ui.AbstractComponentConnector;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.tests.widgetset.server.gwtrpc.GwtRpcButton;
+
+/**
+ * Dummy connector to test our Vaadin/GWT RPC bug. In a Vaadin environment with
+ * DevMode enabled, a pure GWT RPC call would throw an exception. See #11709.
+ *
+ * @author Vaadin Ltd
+ */
+@SuppressWarnings("serial")
+@Connect(GwtRpcButton.class)
+public class GwtRpcButtonConnector extends AbstractComponentConnector {
+
+ static Logger logger = Logger.getLogger(GwtRpcButtonConnector.class
+ .getName());
+ static {
+ logger.setLevel(Level.ALL);
+ }
+
+ @Override
+ public Button getWidget() {
+ return (Button) super.getWidget();
+ }
+
+ @Override
+ protected Button createWidget() {
+ return GWT.create(Button.class);
+ }
+
+ private void log(String message) {
+ logger.log(Level.INFO, message);
+ }
+
+ @Override
+ public void init() {
+ super.init();
+
+ log("GwtRpcButtonTestConnector init");
+
+ getWidget().setText("Click me");
+ getWidget().addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ doRPC();
+ }
+
+ });
+ }
+
+ /**
+ * The ID of the label in case the test is successful.
+ */
+ public static final String SUCCESS_LABEL_ID = "yes";
+
+ /**
+ * The ID of the label in case the test failed.
+ */
+ public static final String FAIL_LABEL_ID = "no";
+
+ /*
+ * Make an RPC to test our bug.
+ */
+ private void doRPC() {
+ log("GwtRpcButtonTestConnector onClick");
+
+ GwtRpcServiceTestAsync service = GWT.create(GwtRpcServiceTest.class);
+
+ service.giveMeThat("honey", "sugar", new AsyncCallback<String>() {
+
+ @Override
+ public void onSuccess(String result) {
+ showResult(result, SUCCESS_LABEL_ID);
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ showResult(caught.getMessage(), FAIL_LABEL_ID);
+ }
+
+ /*
+ * Show the result box.
+ */
+ private void showResult(String result, String labelID) {
+ DialogBox box = new DialogBox(true);
+ Label label = new Label(result);
+ label.getElement().setId(labelID);
+ box.add(label);
+ box.center();
+ box.show();
+ }
+
+ });
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTest.java b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTest.java
new file mode 100644
index 0000000000..16df928d77
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.widgetset.client.gwtrpc;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+/**
+ * Test GWT RPC in Vaadin DevMode.
+ *
+ * @author Vaadin Ltd
+ */
+@RemoteServiceRelativePath("GwtRpcTest")
+public interface GwtRpcServiceTest extends RemoteService {
+
+ /*
+ * Dummy method to verify if RPC works.
+ */
+ String giveMeThat(String that, String haveThis);
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTestAsync.java b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTestAsync.java
new file mode 100644
index 0000000000..93eda8ca34
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTestAsync.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.widgetset.client.gwtrpc;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+/**
+ * Test GWT RPC in Vaadin DevMode.
+ *
+ * @author Vaadin Ltd
+ */
+public interface GwtRpcServiceTestAsync {
+
+ /*
+ * Dummy async method to verify if RPC works.
+ */
+ void giveMeThat(String that, String haveThis, AsyncCallback<String> callback);
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpc.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpc.java
new file mode 100644
index 0000000000..c9f949c465
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpc.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.widgetset.server.gwtrpc;
+
+import com.vaadin.annotations.Widgetset;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.widgetset.TestingWidgetSet;
+
+/**
+ * Test the GWT RPC with Vaadin DevMode. See #11709.
+ *
+ * @author Vaadin Ltd
+ */
+@SuppressWarnings("serial")
+@Widgetset(TestingWidgetSet.NAME)
+public class GwtRpc extends AbstractTestUI {
+
+ /**
+ * Id of the button triggering the test case.
+ */
+ public final static String BUTTON_ID = "gwtRpcButton";
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ GwtRpcButton button = new GwtRpcButton();
+ button.setId(BUTTON_ID);
+ button.setCaption("Press me");
+
+ addComponent(button);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Cannot call RPC in development mode";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11709;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcButton.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcButton.java
new file mode 100644
index 0000000000..c04800713d
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcButton.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.widgetset.server.gwtrpc;
+
+import com.vaadin.ui.AbstractComponent;
+
+/**
+ * Dummy client connector to link with the client functionality where the GWT
+ * RPC is triggered.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+@SuppressWarnings("serial")
+public class GwtRpcButton extends AbstractComponent {
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcServletTest.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcServletTest.java
new file mode 100644
index 0000000000..df01b4dc81
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcServletTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.widgetset.server.gwtrpc;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+import com.vaadin.tests.widgetset.client.gwtrpc.GwtRpcServiceTest;
+
+/**
+ * Test GWT RPC in Vaadin DevMode.
+ *
+ * @author Vaadin Ltd
+ */
+@SuppressWarnings("serial")
+public class GwtRpcServletTest extends RemoteServiceServlet implements
+ GwtRpcServiceTest {
+
+ @Override
+ public String giveMeThat(String that, String haveThis) {
+ return "Take " + that + " for " + haveThis;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java
new file mode 100644
index 0000000000..d27884a13a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.widgetset.server.gwtrpc;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import com.vaadin.tests.widgetset.client.gwtrpc.GwtRpcButtonConnector;
+
+/**
+ * Test the GWT RPC with Vaadin DevMode. See #11709.
+ *
+ * @author Vaadin Ltd
+ */
+public class GwtRpcTest extends MultiBrowserTest {
+
+ @Test
+ public void testGwtRpc() {
+ openTestURL();
+
+ getDriver().findElement(By.id(GwtRpc.BUTTON_ID)).click();
+
+ By label = By.id(GwtRpcButtonConnector.SUCCESS_LABEL_ID);
+
+ waitForElementToBePresent(label);
+ getDriver().findElement(label);
+ }
+
+}