summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2015-10-01 11:53:23 +0300
committerVaadin Code Review <review@vaadin.com>2015-10-02 08:17:15 +0000
commit4e02b7e7402a1d79298787968065a7773e7e34a8 (patch)
treec8fe0423f7d7ae2b8595bd4d1fb9a92797e871c7
parent6d47320640275234a736ab29979a0dfd8eba4084 (diff)
downloadvaadin-framework-4e02b7e7402a1d79298787968065a7773e7e34a8.tar.gz
vaadin-framework-4e02b7e7402a1d79298787968065a7773e7e34a8.zip
Implement ContextClickEvent for Table (#19042)
This patch also introduces a testing infrastructure for context click event and listener testing. Change-Id: I3aa88758278c91086df3d0971edb34914a93fd29
-rw-r--r--client/src/com/vaadin/client/ui/table/TableConnector.java61
-rw-r--r--server/src/com/vaadin/ui/Table.java66
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/table/TableContextClickTest.java57
-rw-r--r--shared/src/com/vaadin/shared/ui/table/TableConstants.java7
-rw-r--r--shared/src/com/vaadin/shared/ui/table/TableServerRpc.java36
-rw-r--r--uitest/src/com/vaadin/tests/contextclick/AbstractContextClickTest.java103
-rw-r--r--uitest/src/com/vaadin/tests/contextclick/AbstractContextClickUI.java92
-rw-r--r--uitest/src/com/vaadin/tests/contextclick/ListenerAddAndRemoveTest.java58
-rw-r--r--uitest/src/com/vaadin/tests/contextclick/TableContextClick.java52
-rw-r--r--uitest/src/com/vaadin/tests/contextclick/TableContextClickTest.java73
-rw-r--r--uitest/src/com/vaadin/tests/contextclick/TableContextClickTestBase.java45
11 files changed, 650 insertions, 0 deletions
diff --git a/client/src/com/vaadin/client/ui/table/TableConnector.java b/client/src/com/vaadin/client/ui/table/TableConnector.java
index 7bbda39c43..70248d367c 100644
--- a/client/src/com/vaadin/client/ui/table/TableConnector.java
+++ b/client/src/com/vaadin/client/ui/table/TableConnector.java
@@ -22,7 +22,9 @@ import java.util.List;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.event.dom.client.ContextMenuEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConnection;
@@ -32,6 +34,7 @@ import com.vaadin.client.ConnectorHierarchyChangeEvent;
import com.vaadin.client.ConnectorHierarchyChangeEvent.ConnectorHierarchyChangeHandler;
import com.vaadin.client.DirectionalManagedLayout;
import com.vaadin.client.HasComponentsConnector;
+import com.vaadin.client.MouseEventDetailsBuilder;
import com.vaadin.client.Paintable;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.TooltipInfo;
@@ -41,9 +44,14 @@ import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.PostLayoutListener;
import com.vaadin.client.ui.VScrollTable;
import com.vaadin.client.ui.VScrollTable.ContextMenuDetails;
+import com.vaadin.client.ui.VScrollTable.FooterCell;
+import com.vaadin.client.ui.VScrollTable.HeaderCell;
import com.vaadin.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
+import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.table.TableConstants;
+import com.vaadin.shared.ui.table.TableConstants.Section;
+import com.vaadin.shared.ui.table.TableServerRpc;
import com.vaadin.shared.ui.table.TableState;
@Connect(com.vaadin.ui.Table.class)
@@ -74,6 +82,59 @@ public class TableConnector extends AbstractFieldConnector implements
getWidget().onUnregister();
}
+ @Override
+ protected void sendContextClickEvent(ContextMenuEvent event) {
+ EventTarget eventTarget = event.getNativeEvent().getEventTarget();
+ if (!Element.is(eventTarget)) {
+ super.sendContextClickEvent(event);
+ return;
+ }
+ Element e = Element.as(eventTarget);
+
+ Section section;
+ String colKey;
+ String rowKey = null;
+ if (getWidget().tFoot.getElement().isOrHasChild(e)) {
+ section = Section.FOOTER;
+ FooterCell w = WidgetUtil.findWidget(e, FooterCell.class);
+ colKey = w.getColKey();
+ } else if (getWidget().tHead.getElement().isOrHasChild(e)) {
+ section = Section.HEADER;
+ HeaderCell w = WidgetUtil.findWidget(e, HeaderCell.class);
+ colKey = w.getColKey();
+ } else if (getWidget().scrollBody.getElement().isOrHasChild(e)) {
+ section = Section.BODY;
+ VScrollTableRow w = WidgetUtil.findWidget(e, VScrollTableRow.class);
+ rowKey = w.getKey();
+ colKey = getWidget().tHead.getHeaderCell(
+ getElementIndex(e, w.getElement())).getColKey();
+ } else {
+ super.sendContextClickEvent(event);
+ return;
+ }
+
+ MouseEventDetails details = MouseEventDetailsBuilder
+ .buildMouseEventDetails(event.getNativeEvent());
+
+ // Prevent browser default context menu
+ event.preventDefault();
+ event.stopPropagation();
+
+ getRpcProxy(TableServerRpc.class).contextClick(rowKey, colKey, section,
+ details);
+ }
+
+ private int getElementIndex(Element e,
+ com.google.gwt.user.client.Element element) {
+ int i = 0;
+ Element current = element.getFirstChildElement();
+ while (!current.isOrHasChild(e)) {
+ current = current.getNextSiblingElement();
+ ++i;
+ }
+ return i;
+ }
+
/*
* (non-Javadoc)
*
diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java
index 5f22ec46ab..f7b0853ce9 100644
--- a/server/src/com/vaadin/ui/Table.java
+++ b/server/src/com/vaadin/ui/Table.java
@@ -46,6 +46,7 @@ import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.ConverterUtil;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
+import com.vaadin.event.ContextClickEvent;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
@@ -65,6 +66,8 @@ import com.vaadin.server.Resource;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.ui.MultiSelectMode;
import com.vaadin.shared.ui.table.TableConstants;
+import com.vaadin.shared.ui.table.TableConstants.Section;
+import com.vaadin.shared.ui.table.TableServerRpc;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
@@ -595,6 +598,18 @@ public class Table extends AbstractSelect implements Action.Container,
*/
public Table() {
setRowHeaderMode(ROW_HEADER_MODE_HIDDEN);
+
+ registerRpc(new TableServerRpc() {
+
+ @Override
+ public void contextClick(String rowKey, String colKey,
+ Section section, MouseEventDetails details) {
+ Object itemId = itemIdMapper.get(rowKey);
+ Object propertyId = columnIdMap.get(colKey);
+ fireEvent(new TableContextClickEvent(Table.this, details,
+ itemId, propertyId, section));
+ }
+ });
}
/**
@@ -6377,6 +6392,57 @@ public class Table extends AbstractSelect implements Action.Container,
return result;
}
+ /* Context Click handling */
+
+ public static class TableContextClickEvent extends ContextClickEvent {
+
+ private final Object itemId;
+ private final Object propertyId;
+ private final Section section;
+
+ public TableContextClickEvent(Table source,
+ MouseEventDetails mouseEventDetails, Object itemId,
+ Object propertyId, Section section) {
+ super(source, mouseEventDetails);
+
+ this.itemId = itemId;
+ this.propertyId = propertyId;
+ this.section = section;
+ }
+
+ /**
+ * Returns the item id of context clicked row.
+ *
+ * @return item id of clicked row; <code>null</code> if header or footer
+ */
+ public Object getItemId() {
+ return itemId;
+ }
+
+ /**
+ * Returns the property id of context clicked column.
+ *
+ * @return property id
+ */
+ public Object getPropertyId() {
+ return propertyId;
+ }
+
+ /**
+ * Returns the clicked section of Table.
+ *
+ * @return section of Table
+ */
+ public Section getSection() {
+ return section;
+ }
+
+ @Override
+ public Table getComponent() {
+ return (Table) super.getComponent();
+ }
+ }
+
private final Logger getLogger() {
if (logger == null) {
logger = Logger.getLogger(Table.class.getName());
diff --git a/server/tests/src/com/vaadin/tests/server/component/table/TableContextClickTest.java b/server/tests/src/com/vaadin/tests/server/component/table/TableContextClickTest.java
new file mode 100644
index 0000000000..d96a5d626a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/table/TableContextClickTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.server.component.table;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.event.ContextClickEvent;
+import com.vaadin.event.ContextClickEvent.ContextClickListener;
+import com.vaadin.shared.ui.table.TableConstants.Section;
+import com.vaadin.ui.Table;
+
+public class TableContextClickTest extends Table {
+
+ private String error = null;
+ private boolean handled = false;
+
+ @Test
+ public void testContextClickListenerWithTableEvent() {
+ addContextClickListener(new ContextClickListener() {
+
+ @Override
+ public void contextClick(ContextClickEvent event) {
+ if (!(event instanceof TableContextClickEvent)) {
+ return;
+ }
+
+ TableContextClickEvent e = (TableContextClickEvent) event;
+ if (e.getSection() != Section.BODY) {
+ error = "Event section was not BODY.";
+ }
+ handled = true;
+ }
+ });
+ fireEvent(new TableContextClickEvent(this, null, null, null,
+ Section.BODY));
+
+ if (error != null) {
+ Assert.fail(error);
+ } else if (!handled) {
+ Assert.fail("Event was not handled by the ContextClickListener");
+ }
+ }
+}
diff --git a/shared/src/com/vaadin/shared/ui/table/TableConstants.java b/shared/src/com/vaadin/shared/ui/table/TableConstants.java
index e782492e9d..9117729eb1 100644
--- a/shared/src/com/vaadin/shared/ui/table/TableConstants.java
+++ b/shared/src/com/vaadin/shared/ui/table/TableConstants.java
@@ -18,6 +18,13 @@ package com.vaadin.shared.ui.table;
import java.io.Serializable;
public class TableConstants implements Serializable {
+ /**
+ * Enum describing different sections of Table.
+ */
+ public enum Section {
+ HEADER, BODY, FOOTER
+ }
+
public static final String ITEM_CLICK_EVENT_ID = "itemClick";
public static final String HEADER_CLICK_EVENT_ID = "handleHeaderClick";
public static final String FOOTER_CLICK_EVENT_ID = "handleFooterClick";
diff --git a/shared/src/com/vaadin/shared/ui/table/TableServerRpc.java b/shared/src/com/vaadin/shared/ui/table/TableServerRpc.java
new file mode 100644
index 0000000000..bfd6f544ef
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/table/TableServerRpc.java
@@ -0,0 +1,36 @@
+/*
+ * 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.shared.ui.table;
+
+import com.vaadin.shared.MouseEventDetails;
+import com.vaadin.shared.communication.ServerRpc;
+import com.vaadin.shared.ui.table.TableConstants.Section;
+
+/**
+ * Client-to-server RPC interface for the Table component
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface TableServerRpc extends ServerRpc {
+
+ /**
+ * Informs the server that a context click happened inside of Table
+ */
+ public void contextClick(String rowKey, String colKey, Section section,
+ MouseEventDetails details);
+
+}
diff --git a/uitest/src/com/vaadin/tests/contextclick/AbstractContextClickTest.java b/uitest/src/com/vaadin/tests/contextclick/AbstractContextClickTest.java
new file mode 100644
index 0000000000..2323d0c9cb
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/contextclick/AbstractContextClickTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.contextclick;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.openqa.selenium.Point;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.elements.AbstractComponentElement;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.parallel.BrowserUtil;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public abstract class AbstractContextClickTest extends MultiBrowserTest {
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ return getBrowsersSupportingContextMenu();
+ }
+
+ @Test
+ public void testDefaultListener() {
+ openTestURL();
+
+ addOrRemoveDefaultListener();
+
+ assertDefaultContextClickListener(1);
+ }
+
+ protected void assertNoContextClickHandler() {
+ AbstractComponentElement component = $(AbstractComponentElement.class)
+ .id("testComponent");
+
+ String log = getLogRow(0);
+
+ contextClick(component);
+
+ assertEquals("Log entry without a context click listener.", log,
+ getLogRow(0));
+
+ }
+
+ protected void assertDefaultContextClickListener(int index) {
+ AbstractComponentElement component = $(AbstractComponentElement.class)
+ .id("testComponent");
+
+ contextClick(component);
+
+ Point l = component.getLocation();
+
+ int drift = 0;
+ // IE 10 and 11 report different Y location.
+ if (BrowserUtil.isIE(getDesiredCapabilities(), 10)
+ || BrowserUtil.isIE(getDesiredCapabilities(), 11)) {
+ drift = 1;
+ }
+
+ assertEquals(index + ". ContextClickEvent: (" + (l.getX() + 10) + ", "
+ + (l.getY() + 10 + drift) + ")", getLogRow(0));
+ }
+
+ protected void addOrRemoveDefaultListener() {
+ $(ButtonElement.class).caption("Add/Remove default listener").first()
+ .click();
+ }
+
+ protected void addOrRemoveTypedListener() {
+ $(ButtonElement.class).caption("Add/Remove typed listener").first()
+ .click();
+ }
+
+ /**
+ * Performs a context click followed by a regular click. This prevents
+ * browser context menu from blocking future operations.
+ *
+ * @param e
+ * web element
+ */
+ protected void contextClick(WebElement e) {
+ new Actions(getDriver()).moveToElement(e, 10, 10).contextClick()
+ .perform();
+ new Actions(getDriver()).moveToElement(e, 5, 5).click().perform();
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/contextclick/AbstractContextClickUI.java b/uitest/src/com/vaadin/tests/contextclick/AbstractContextClickUI.java
new file mode 100644
index 0000000000..9a0ef31692
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/contextclick/AbstractContextClickUI.java
@@ -0,0 +1,92 @@
+/*
+ * 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.contextclick;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.event.ContextClickEvent;
+import com.vaadin.event.ContextClickEvent.ContextClickListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+
+@Theme("valo")
+public abstract class AbstractContextClickUI<T extends AbstractComponent, E extends ContextClickEvent>
+ extends AbstractTestUIWithLog {
+
+ private final class ListenerHandler implements Button.ClickListener {
+ private boolean hasListener = false;
+ private final ContextClickListener listener;
+
+ public ListenerHandler(ContextClickListener listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ if (!hasListener) {
+ testComponent.addContextClickListener(listener);
+ event.getButton().setDescription("Remove listener");
+ hasListener = true;
+ } else {
+ testComponent.removeContextClickListener(listener);
+ event.getButton().setDescription("Add listener");
+ hasListener = false;
+ }
+ }
+ }
+
+ protected T testComponent;
+ private ContextClickListener defaultListener = new ContextClickListener() {
+
+ @Override
+ public void contextClick(ContextClickEvent event) {
+ log("ContextClickEvent: (" + event.getClientX() + ", "
+ + event.getClientY() + ")");
+ }
+ };
+
+ private ContextClickListener typedListener = new ContextClickListener() {
+
+ @Override
+ public void contextClick(ContextClickEvent event) {
+ try {
+ E typedEvent = (E) event;
+ handleContextClickEvent(typedEvent);
+ } catch (Exception e) {
+ log("UNEXPECTED EVENT TYPE!");
+ }
+ }
+ };
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ testComponent = createTestComponent();
+ testComponent.setId("testComponent");
+
+ addComponent(testComponent);
+
+ addComponent(new Button("Add/Remove default listener",
+ new ListenerHandler(defaultListener)));
+ addComponent(new Button("Add/Remove typed listener",
+ new ListenerHandler(typedListener)));
+ }
+
+ protected abstract T createTestComponent();
+
+ protected abstract void handleContextClickEvent(E event);
+}
diff --git a/uitest/src/com/vaadin/tests/contextclick/ListenerAddAndRemoveTest.java b/uitest/src/com/vaadin/tests/contextclick/ListenerAddAndRemoveTest.java
new file mode 100644
index 0000000000..01fbd87d74
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/contextclick/ListenerAddAndRemoveTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.contextclick;
+
+import org.junit.Test;
+
+public class ListenerAddAndRemoveTest extends TableContextClickTestBase {
+
+ @Test
+ public void testAddAndRemoveListeners() {
+ openTestURL();
+
+ // Add typed listener
+ addOrRemoveTypedListener();
+
+ // Add default listener
+ addOrRemoveDefaultListener();
+
+ // Remove the default listener
+ addOrRemoveDefaultListener();
+
+ // Check that typed listener is still working
+ assertTypedContextClickListener(1);
+
+ // Re-add the default listener
+ addOrRemoveDefaultListener();
+
+ // Remove typed listener
+ addOrRemoveTypedListener();
+
+ // Check that default listener still works
+ assertDefaultContextClickListener(3);
+
+ // Remove default listener
+ addOrRemoveDefaultListener();
+
+ // Assert no listeners present.
+ assertNoContextClickHandler();
+
+ // Re-add typed listener
+ addOrRemoveTypedListener();
+
+ assertTypedContextClickListener(4);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/contextclick/TableContextClick.java b/uitest/src/com/vaadin/tests/contextclick/TableContextClick.java
new file mode 100644
index 0000000000..8d75dd61c0
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/contextclick/TableContextClick.java
@@ -0,0 +1,52 @@
+/*
+ * 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.contextclick;
+
+import com.vaadin.data.Item;
+import com.vaadin.shared.ui.table.TableConstants.Section;
+import com.vaadin.tests.util.PersonContainer;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.TableContextClickEvent;
+
+public class TableContextClick extends
+ AbstractContextClickUI<Table, TableContextClickEvent> {
+
+ @Override
+ protected Table createTestComponent() {
+ Table table = new Table();
+ table.setContainerDataSource(PersonContainer.createWithTestData());
+ table.setFooterVisible(true);
+ return table;
+ }
+
+ @Override
+ protected void handleContextClickEvent(TableContextClickEvent event) {
+ String value = "";
+ Object propertyId = event.getPropertyId();
+ if (event.getItemId() != null) {
+ Item item = event.getComponent().getContainerDataSource()
+ .getItem(event.getItemId());
+ value += item.getItemProperty("firstName").getValue() + " ";
+ value += item.getItemProperty("lastName").getValue();
+ } else if (event.getSection() == Section.HEADER) {
+ value = testComponent.getColumnHeader(propertyId);
+ } else if (event.getSection() == Section.FOOTER) {
+ value = testComponent.getColumnFooter(propertyId);
+ }
+ log("ContextClickEvent value: " + value + ", propertyId: " + propertyId
+ + ", section: " + event.getSection());
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/contextclick/TableContextClickTest.java b/uitest/src/com/vaadin/tests/contextclick/TableContextClickTest.java
new file mode 100644
index 0000000000..51efbf9498
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/contextclick/TableContextClickTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.contextclick;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.vaadin.testbench.elements.TableElement;
+
+public class TableContextClickTest extends TableContextClickTestBase {
+
+ @Test
+ public void testBodyContextClickWithTypedListener() {
+ openTestURL();
+
+ addOrRemoveTypedListener();
+
+ assertTypedContextClickListener(1);
+ }
+
+ @Test
+ public void testHeaderContextClickWithTypedListener() {
+ openTestURL();
+
+ addOrRemoveTypedListener();
+
+ contextClick($(TableElement.class).first().getHeaderCell(0));
+
+ assertEquals(
+ "1. ContextClickEvent value: address, propertyId: address, section: HEADER",
+ getLogRow(0));
+
+ contextClick($(TableElement.class).first().getHeaderCell(3));
+
+ assertEquals(
+ "2. ContextClickEvent value: lastName, propertyId: lastName, section: HEADER",
+ getLogRow(0));
+ }
+
+ @Test
+ public void testFooterContextClickWithTypedListener() {
+ openTestURL();
+
+ addOrRemoveTypedListener();
+
+ contextClick($(TableElement.class).first().getFooterCell(0));
+
+ assertEquals(
+ "1. ContextClickEvent value: null, propertyId: address, section: FOOTER",
+ getLogRow(0));
+
+ contextClick($(TableElement.class).first().getFooterCell(3));
+
+ assertEquals(
+ "2. ContextClickEvent value: null, propertyId: lastName, section: FOOTER",
+ getLogRow(0));
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/contextclick/TableContextClickTestBase.java b/uitest/src/com/vaadin/tests/contextclick/TableContextClickTestBase.java
new file mode 100644
index 0000000000..e3f4647c33
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/contextclick/TableContextClickTestBase.java
@@ -0,0 +1,45 @@
+/*
+ * 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.contextclick;
+
+import static org.junit.Assert.assertEquals;
+
+import com.vaadin.testbench.elements.TableElement;
+
+public abstract class TableContextClickTestBase extends
+ AbstractContextClickTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return TableContextClick.class;
+ }
+
+ protected void assertTypedContextClickListener(int startIndex) {
+ contextClick($(TableElement.class).first().getCell(0, 0));
+
+ assertEquals(
+ (startIndex++)
+ + ". ContextClickEvent value: Lisa Schneider, propertyId: address, section: BODY",
+ getLogRow(0));
+
+ contextClick($(TableElement.class).first().getCell(0, 3));
+
+ assertEquals(
+ startIndex
+ + ". ContextClickEvent value: Lisa Schneider, propertyId: lastName, section: BODY",
+ getLogRow(0));
+ }
+}