summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBuild Agent <build@vaadin.com>2014-03-28 16:00:29 +0200
committerBuild Agent <build@vaadin.com>2014-03-28 16:00:29 +0200
commit6d94e30a42ee6f2c1c521537ca805558094bd8bc (patch)
tree625368c8ca7d5dae3b5c21495cbfb59a098744f9
parenta8c2c7b4a83b839dbf3b6540ed328793efb1dedd (diff)
parent29e7df26ad034eacdbf37fc03985873aabda6576 (diff)
downloadvaadin-framework-6d94e30a42ee6f2c1c521537ca805558094bd8bc.tar.gz
vaadin-framework-6d94e30a42ee6f2c1c521537ca805558094bd8bc.zip
Merge changes from origin/7.1
1f4ca4c Prevent resize for sorted column if not initialized (#12951) 437f4e9 Improved portlet configuration resolution. (#7814) 55a1b20 Added headers support for WebSphere Portal. (#13491) f979681 Fix VScrollTable to clear reported ranges (#13353) a473222 Added browser inclusion and exclusion for TB3Runner. 29e7df2 Makes combobox work with pasted texts. (#13214). Change-Id: Icdb5a633d1d9f7bf7004b4b45857d268ea674f50
-rw-r--r--client/src/com/vaadin/client/ui/VFilterSelect.java26
-rw-r--r--client/src/com/vaadin/client/ui/VScrollTable.java5
-rw-r--r--client/src/com/vaadin/client/ui/table/TableConnector.java4
-rw-r--r--server/src/com/vaadin/server/VaadinPortlet.java35
-rw-r--r--server/src/com/vaadin/server/VaadinPortletRequest.java18
-rw-r--r--server/src/com/vaadin/server/VaadinPortletService.java96
-rw-r--r--server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java52
-rw-r--r--server/tests/src/com/vaadin/server/VaadinPortletServiceTests.java151
-rw-r--r--uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRange.java93
-rw-r--r--uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java74
10 files changed, 505 insertions, 49 deletions
diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java
index 81762b3aef..b97eff0fbd 100644
--- a/client/src/com/vaadin/client/ui/VFilterSelect.java
+++ b/client/src/com/vaadin/client/ui/VFilterSelect.java
@@ -1148,6 +1148,32 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
popupOpener.addClickHandler(this);
setStyleName(CLASSNAME);
+
+ sinkEvents(Event.ONPASTE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.user.client.ui.Composite#onBrowserEvent(com.google.gwt
+ * .user.client.Event)
+ */
+ @Override
+ public void onBrowserEvent(Event event) {
+ super.onBrowserEvent(event);
+
+ if (event.getTypeInt() == Event.ONPASTE) {
+ if (textInputEnabled) {
+ Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+
+ @Override
+ public void execute() {
+ filterOptions(currentPage);
+ }
+ });
+ }
+ }
}
/**
diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java
index ad66355608..b2ba590d8e 100644
--- a/client/src/com/vaadin/client/ui/VScrollTable.java
+++ b/client/src/com/vaadin/client/ui/VScrollTable.java
@@ -326,13 +326,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
ArrayList<SelectionRange> ranges = new ArrayList<SelectionRange>(2);
int endOfFirstRange = row.getIndex() - 1;
- if (!(endOfFirstRange - startRow.getIndex() < 0)) {
+ if (endOfFirstRange >= startRow.getIndex()) {
// create range of first part unless its length is < 1
ranges.add(new SelectionRange(startRow, endOfFirstRange
- startRow.getIndex() + 1));
}
int startOfSecondRange = row.getIndex() + 1;
- if (!(getEndIndex() - startOfSecondRange < 0)) {
+ if (getEndIndex() >= startOfSecondRange) {
// create range of second part unless its length is < 1
VScrollTableRow startOfRange = scrollBody
.getRowByRowIndex(startOfSecondRange);
@@ -862,6 +862,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// Send the selected row ranges
client.updateVariable(paintableId, "selectedRanges",
ranges.toArray(new String[selectedRowRanges.size()]), false);
+ selectedRowRanges.clear();
// clean selectedRowKeys so that they don't contain excess values
for (Iterator<String> iterator = selectedRowKeys.iterator(); iterator
diff --git a/client/src/com/vaadin/client/ui/table/TableConnector.java b/client/src/com/vaadin/client/ui/table/TableConnector.java
index 1e19e76f1e..610f2f8010 100644
--- a/client/src/com/vaadin/client/ui/table/TableConnector.java
+++ b/client/src/com/vaadin/client/ui/table/TableConnector.java
@@ -303,7 +303,9 @@ public class TableConnector extends AbstractHasComponentsConnector implements
getWidget().tabIndex = getState().tabIndex;
getWidget().setProperTabIndex();
- getWidget().resizeSortedColumnForSortIndicator();
+ if (getWidget().initializedAndAttached) {
+ getWidget().resizeSortedColumnForSortIndicator();
+ }
// Remember this to detect situations where overflow hack might be
// needed during scrolling
diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java
index 6cf30e85e9..4c34b0aedb 100644
--- a/server/src/com/vaadin/server/VaadinPortlet.java
+++ b/server/src/com/vaadin/server/VaadinPortlet.java
@@ -159,6 +159,31 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
}
}
+ // Intentionally internal, will be refactored out in 7.2.
+ static class WebSpherePortalRequest extends VaadinHttpAndPortletRequest {
+
+ public WebSpherePortalRequest(PortletRequest request,
+ VaadinPortletService vaadinService) {
+ super(request, getServletRequest(request), vaadinService);
+ }
+
+ private static HttpServletRequest getServletRequest(
+ PortletRequest request) {
+ try {
+ Class<?> portletUtils = Class
+ .forName("com.ibm.ws.portletcontainer.portlet.PortletUtils");
+ Method getHttpServletRequest = portletUtils.getMethod(
+ "getHttpServletRequest", PortletRequest.class);
+
+ return (HttpServletRequest) getHttpServletRequest.invoke(null,
+ request);
+ } catch (Exception e) {
+ throw new IllegalStateException(
+ "WebSphere Portal request not detected.");
+ }
+ }
+ }
+
public static class VaadinLiferayRequest extends
VaadinHttpAndPortletRequest {
@@ -425,7 +450,10 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
return new VaadinLiferayRequest(request, getService());
} else if (isGateIn(request)) {
return new VaadinGateinRequest(request, getService());
+ } else if (isWebSphere(request)) {
+ return new WebSpherePortalRequest(request, getService());
} else {
+
return new VaadinPortletRequest(request, getService());
}
}
@@ -454,6 +482,13 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
return portalInfo.contains("gatein");
}
+ private static boolean isWebSphere(PortletRequest request) {
+ String portalInfo = request.getPortalContext().getPortalInfo()
+ .toLowerCase();
+
+ return portalInfo.contains("websphere portal");
+ }
+
private VaadinPortletResponse createVaadinResponse(PortletResponse response) {
return new VaadinPortletResponse(response, getService());
}
diff --git a/server/src/com/vaadin/server/VaadinPortletRequest.java b/server/src/com/vaadin/server/VaadinPortletRequest.java
index 9a1e0e7f07..eae367a992 100644
--- a/server/src/com/vaadin/server/VaadinPortletRequest.java
+++ b/server/src/com/vaadin/server/VaadinPortletRequest.java
@@ -23,6 +23,7 @@ import java.text.ParseException;
import java.util.Enumeration;
import javax.portlet.ClientDataRequest;
+import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletSession;
import javax.portlet.ResourceRequest;
@@ -191,6 +192,23 @@ public class VaadinPortletRequest extends PortletRequestWrapper implements
return getRequest().getPortalContext().getProperty(name);
}
+ /**
+ * Reads a portlet preference from the portlet of the request.
+ *
+ * @param name
+ * The name of the portlet preference. Cannot be
+ * <code>null</code>.
+ *
+ * @return The value of the portlet preference, <code>null</code> if the
+ * preference is not defined.
+ */
+ public String getPortletPreference(String name) {
+ PortletRequest request = getRequest();
+ PortletPreferences preferences = request.getPreferences();
+
+ return preferences.getValue(name, null);
+ }
+
@Override
public VaadinPortletService getService() {
return vaadinService;
diff --git a/server/src/com/vaadin/server/VaadinPortletService.java b/server/src/com/vaadin/server/VaadinPortletService.java
index 42cf479c56..dceeec8e91 100644
--- a/server/src/com/vaadin/server/VaadinPortletService.java
+++ b/server/src/com/vaadin/server/VaadinPortletService.java
@@ -81,11 +81,46 @@ public class VaadinPortletService extends VaadinService {
return portlet;
}
- private static String getPortalProperty(VaadinRequest request,
- String propertyName) {
+ private String getPortalProperty(VaadinRequest request, String propertyName) {
return ((VaadinPortletRequest) request).getPortalProperty(propertyName);
}
+ private String getParameter(VaadinRequest request, String name,
+ String defaultValue) {
+ VaadinPortletRequest portletRequest = (VaadinPortletRequest) request;
+
+ String preference = portletRequest.getPortletPreference(name);
+ if (preference != null) {
+ return preference;
+ }
+
+ String appOrSystemProperty = getAppOrSystemProperty(name, null);
+ if (appOrSystemProperty != null) {
+ return appOrSystemProperty;
+ }
+
+ String portalProperty = portletRequest.getPortalProperty(name);
+ if (portalProperty != null) {
+
+ // For backwards compatibility - automatically map old portal
+ // default widget set to default widget set
+ if (name.equals(Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET)) {
+ return mapDefaultWidgetset(portalProperty);
+ }
+
+ return portalProperty;
+ }
+
+ return defaultValue;
+ }
+
+ private String getAppOrSystemProperty(String name, String defaultValue) {
+ DeploymentConfiguration deploymentConfiguration = getDeploymentConfiguration();
+
+ return deploymentConfiguration.getApplicationOrSystemProperty(name,
+ defaultValue);
+ }
+
@Override
public String getConfiguredWidgetset(VaadinRequest request) {
@@ -94,22 +129,17 @@ public class VaadinPortletService extends VaadinService {
VaadinPortlet.PARAMETER_WIDGETSET, null);
if (widgetset == null) {
- // If no widgetset defined for the application, check the
- // portal property
- widgetset = getPortalProperty(request,
- VaadinPortlet.PORTAL_PARAMETER_VAADIN_WIDGETSET);
- if ("com.vaadin.portal.gwt.PortalDefaultWidgetSet"
- .equals(widgetset)) {
- // For backwards compatibility - automatically map old portal
- // default widget set to default widget set
- widgetset = VaadinPortlet.DEFAULT_WIDGETSET;
-
- }
+ widgetset = getParameter(request,
+ Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET,
+ Constants.DEFAULT_WIDGETSET);
}
- if (widgetset == null) {
- // If no widgetset defined for the portal, use the default
- widgetset = VaadinPortlet.DEFAULT_WIDGETSET;
+ return widgetset;
+ }
+
+ private String mapDefaultWidgetset(String widgetset) {
+ if ("com.vaadin.portal.gwt.PortalDefaultWidgetSet".equals(widgetset)) {
+ return Constants.DEFAULT_WIDGETSET;
}
return widgetset;
@@ -117,17 +147,8 @@ public class VaadinPortletService extends VaadinService {
@Override
public String getConfiguredTheme(VaadinRequest request) {
-
- // is the default theme defined by the portal?
- String themeName = getPortalProperty(request,
- Constants.PORTAL_PARAMETER_VAADIN_THEME);
-
- if (themeName == null) {
- // no, using the default theme defined by Vaadin
- themeName = VaadinPortlet.DEFAULT_THEME_NAME;
- }
-
- return themeName;
+ return getParameter(request, Constants.PORTAL_PARAMETER_VAADIN_THEME,
+ Constants.DEFAULT_THEME_NAME);
}
@Override
@@ -137,24 +158,25 @@ public class VaadinPortletService extends VaadinService {
@Override
public String getStaticFileLocation(VaadinRequest request) {
- String staticFileLocation = getPortalProperty(request,
- Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH);
- if (staticFileLocation != null) {
- return trimTrailingSlashes(staticFileLocation);
- } else {
- // default for Liferay
- return "/html";
- }
+ // /html is default for Liferay
+ String staticFileLocation = getParameter(request,
+ Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH, "/html");
+
+ return trimTrailingSlashes(staticFileLocation);
+ }
+
+ private PortletContext getPortletContext() {
+ return getPortlet().getPortletContext();
}
@Override
public String getMimeType(String resourceName) {
- return getPortlet().getPortletContext().getMimeType(resourceName);
+ return getPortletContext().getMimeType(resourceName);
}
@Override
public File getBaseDirectory() {
- PortletContext context = getPortlet().getPortletContext();
+ PortletContext context = getPortletContext();
String resultPath = context.getRealPath("/");
if (resultPath != null) {
return new File(resultPath);
diff --git a/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java b/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java
new file mode 100644
index 0000000000..6e40c57718
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java
@@ -0,0 +1,52 @@
+package com.vaadin.server;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class VaadinPortletRequestTests {
+
+ private PortletRequest request;
+ private VaadinPortletRequest sut;
+ private VaadinPortletService service;
+ private PortletPreferences preferences;
+
+ @Before
+ public void setup() {
+ request = mock(PortletRequest.class);
+ service = mock(VaadinPortletService.class);
+
+ sut = new VaadinPortletRequest(request, service);
+
+ preferences = mock(PortletPreferences.class);
+ when(request.getPreferences()).thenReturn(preferences);
+ }
+
+ @Test
+ public void portletPreferenceIsFetched() {
+ when(preferences.getValue(eq("foo"), anyString())).thenReturn("bar");
+
+ String value = sut.getPortletPreference("foo");
+
+ assertThat(value, is("bar"));
+ }
+
+ @Test
+ public void defaultValueForPortletPreferenceIsNull() {
+ when(preferences.getValue(anyString(), isNull(String.class))).thenReturn(null);
+
+ String value = sut.getPortletPreference("foo");
+
+ assertNull(value);
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/server/VaadinPortletServiceTests.java b/server/tests/src/com/vaadin/server/VaadinPortletServiceTests.java
index c54a6dddce..62befdc516 100644
--- a/server/tests/src/com/vaadin/server/VaadinPortletServiceTests.java
+++ b/server/tests/src/com/vaadin/server/VaadinPortletServiceTests.java
@@ -27,32 +27,165 @@ public class VaadinPortletServiceTests {
private VaadinPortletService sut;
private VaadinPortletRequest request;
+ private DeploymentConfiguration conf;
@Before
public void setup() throws ServiceException {
VaadinPortlet portlet = mock(VaadinPortlet.class);
- DeploymentConfiguration conf = mock(DeploymentConfiguration.class);
+ conf = mock(DeploymentConfiguration.class);
sut = new VaadinPortletService(portlet, conf);
request = mock(VaadinPortletRequest.class);
}
- private void mockRequestToReturnLocation(String location) {
- when(request.getPortalProperty(
- Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH))
+ private void mockFileLocationProperty(String location) {
+ mockPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH,
+ location);
+ }
+
+ private void mockPortalProperty(String name, String value) {
+ when(request.getPortalProperty(name)).thenReturn(value);
+ }
+
+ private void mockFileLocationPreference(String location) {
+ when(
+ request.getPortletPreference(Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH))
.thenReturn(location);
}
+ private void mockLocationDeploymentConfiguration(String location) {
+ when(
+ conf.getApplicationOrSystemProperty(
+ Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH, null))
+ .thenReturn(location);
+ }
+
+ private String getStaticFileLocation() {
+ return sut.getStaticFileLocation(request);
+ }
+
+ private String getTheme() {
+ return sut.getConfiguredTheme(request);
+ }
+
+ private void mockThemeProperty(String theme) {
+ mockPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_THEME, theme);
+ }
+
+ private void mockWidgetsetProperty(String widgetset) {
+ mockPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET,
+ widgetset);
+ }
+
+ private void mockWidgetsetConfiguration(String widgetset) {
+ when(
+ conf.getApplicationOrSystemProperty(
+ Constants.PARAMETER_WIDGETSET, null)).thenReturn(
+ widgetset);
+ }
+
+ @Test
+ public void preferencesOverrideDeploymentConfiguration() {
+ mockFileLocationPreference("prefs");
+ mockLocationDeploymentConfiguration("conf");
+
+ String location = getStaticFileLocation();
+
+ assertThat(location, is("prefs"));
+ }
+
+ @Test
+ public void deploymentConfigurationOverridesProperties() {
+ mockFileLocationPreference(null);
+ mockLocationDeploymentConfiguration("conf");
+ mockFileLocationProperty("props");
+
+ String location = getStaticFileLocation();
+
+ assertThat(location, is("conf"));
+ }
+
@Test
- public void trailingSlashesAreTrimmedFromStaticFileLocation()
- throws ServiceException {
+ public void defaultFileLocationIsSet() {
+ mockFileLocationPreference(null);
+ mockLocationDeploymentConfiguration(null);
+ mockFileLocationProperty(null);
+
+ String location = getStaticFileLocation();
- mockRequestToReturnLocation("/content////");
+ assertThat(location, is("/html"));
+ }
+
+ @Test
+ public void trailingSlashesAreTrimmedFromStaticFileLocation() {
+ mockFileLocationPreference("/content////");
- String staticFileLocation = sut
- .getStaticFileLocation(request);
+ String staticFileLocation = getStaticFileLocation();
assertThat(staticFileLocation, is("/content"));
}
+
+ @Test
+ public void themeCanBeOverridden() {
+ mockThemeProperty("foobar");
+
+ String theme = getTheme();
+
+ assertThat(theme, is("foobar"));
+ }
+
+ @Test
+ public void defaultThemeIsSet() {
+ mockThemeProperty(null);
+
+ String theme = getTheme();
+
+ assertThat(theme, is(Constants.DEFAULT_THEME_NAME));
+ }
+
+ private String getWidgetset() {
+ return sut.getConfiguredWidgetset(request);
+ }
+
+ @Test
+ public void defaultWidgetsetIsSet() {
+ mockWidgetsetProperty(null);
+ mockWidgetsetConfiguration(null);
+
+ String widgetset = getWidgetset();
+
+ assertThat(widgetset, is(Constants.DEFAULT_WIDGETSET));
+ }
+
+ @Test
+ public void configurationWidgetsetOverridesProperty() {
+ mockWidgetsetProperty("foo");
+ mockWidgetsetConfiguration("bar");
+
+ String widgetset = getWidgetset();
+
+ assertThat(widgetset, is("bar"));
+ }
+
+ @Test
+ public void oldDefaultWidgetsetIsMappedToDefaultWidgetset() {
+ mockWidgetsetConfiguration(null);
+ mockWidgetsetProperty("com.vaadin.portal.gwt.PortalDefaultWidgetSet");
+
+ String widgetset = getWidgetset();
+
+ assertThat(widgetset, is(Constants.DEFAULT_WIDGETSET));
+ }
+
+ @Test
+ public void oldDefaultWidgetSetIsNotMappedToDefaultWidgetset() {
+ mockWidgetsetConfiguration("com.vaadin.portal.gwt.PortalDefaultWidgetSet");
+ mockWidgetsetProperty(null);
+
+ String widgetset = getWidgetset();
+
+ assertThat(widgetset,
+ is("com.vaadin.portal.gwt.PortalDefaultWidgetSet"));
+ }
}
diff --git a/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRange.java b/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRange.java
new file mode 100644
index 0000000000..d54a8b467a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRange.java
@@ -0,0 +1,93 @@
+/*
+ * 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.Set;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.tb3.AbstractTB3Test.RunLocally;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Notification.Type;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * Test to see if selecting and deselecting a table row after select range has
+ * been removed.
+ *
+ * @since 7.1.13
+ * @author Vaadin Ltd
+ */
+@SuppressWarnings("serial")
+@RunLocally()
+public class AddSelectionToRemovedRange extends AbstractTestUI {
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void setup(VaadinRequest request) {
+ VerticalLayout layout = new VerticalLayout();
+ layout.setMargin(true);
+ layout.setSpacing(true);
+ setContent(layout);
+
+ final Table table = new Table();
+ table.setMultiSelect(true);
+ table.setSelectable(true);
+ table.addContainerProperty("value", String.class, "");
+
+ for (int i = 0; i < 100; i++) {
+ table.addItem(i);
+ table.getContainerProperty(i, "value").setValue("value " + i);
+ }
+
+ layout.addComponent(table);
+
+ Button button = new Button("Remove");
+ button.addClickListener(new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(Button.ClickEvent event) {
+ Set<Integer> selected = (Set<Integer>) table.getValue();
+
+ for (Integer item : selected) {
+ if (null == item) {
+ new Notification(
+ "ERROR",
+ "Table value has null in Set of selected items!",
+ Type.ERROR_MESSAGE).show(getPage());
+ }
+ table.removeItem(item);
+ }
+ }
+ });
+
+ layout.addComponent(button);
+
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Verify that VScrollTable does not return bad ranges when ";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 13353;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java b/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java
new file mode 100644
index 0000000000..f6a503db72
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.table;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class AddSelectionToRemovedRangeTest extends MultiBrowserTest {
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ return Collections.unmodifiableList(Arrays.asList(Browser.CHROME
+ .getDesiredCapabilities()));
+ }
+
+ @Override
+ protected DesiredCapabilities getDesiredCapabilities() {
+ DesiredCapabilities cap = new DesiredCapabilities(
+ super.getDesiredCapabilities());
+ cap.setCapability("requireWindowFocus", true);
+ return cap;
+ }
+
+ @Test
+ public void addAndRemoveItemToRemovedRange() throws IOException {
+ openTestURL();
+ List<WebElement> rows = driver.findElements(By
+ .className("v-table-cell-wrapper"));
+ WebElement rangeStart = rows.get(0);
+ WebElement rangeEnd = rows.get(1);
+ rangeStart.click();
+ new Actions(driver).keyDown(Keys.SHIFT).perform();
+ rangeEnd.click();
+ new Actions(driver).keyUp(Keys.SHIFT).perform();
+ driver.findElement(By.className("v-button")).click();
+ WebElement extraRow = driver.findElements(
+ By.className("v-table-cell-wrapper")).get(1);
+ new Actions(driver).keyDown(Keys.CONTROL).click(extraRow)
+ .click(extraRow).keyUp(Keys.CONTROL).perform();
+ driver.findElement(By.className("v-button")).click();
+ try {
+ driver.findElement(By.vaadin("Root/VNotification[0]"));
+ Assert.fail("Notification is shown");
+ } catch (NoSuchElementException e) {
+ // All is well.
+ }
+ }
+}