]> source.dussan.org Git - vaadin-framework.git/commitdiff
Table should load widgets after container content refresh (#16611)
authorMikael Grankvist <mgrankvi@vaadin.com>
Wed, 11 Feb 2015 08:38:52 +0000 (10:38 +0200)
committerArtur Signell <artur@vaadin.com>
Mon, 2 Mar 2015 19:51:32 +0000 (21:51 +0200)
Change-Id: I887830f31f886743d1bd7167236e2f7b61349dd7

client/src/com/vaadin/client/ui/VScrollTable.java
uitest/src/com/vaadin/tests/components/table/ReloadWidgets.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/table/ReloadWidgetsTest.java [new file with mode: 0644]

index 6b4bb8eb9d25047d9b7ce80e8bcdd046a41b0711..a648128f4d9fd5dd2ab8fe5aaad3b92d4aaf8d52 100644 (file)
@@ -1225,7 +1225,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
         // Without this call the scroll position is messed up in IE even after
         // the lazy scroller has set the scroll position to the first visible
         // item
-        scrollBodyPanel.getScrollPosition();
+        int pos = scrollBodyPanel.getScrollPosition();
+
+        // Reset first row in view port so client requests correct last row.
+        if (pos == 0) {
+            firstRowInViewPort = 0;
+        }
 
         scrollBody = createScrollBody();
 
@@ -3380,7 +3385,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
 
         /**
          * Saves natural column width if it hasn't been saved already.
-         *
+         * 
          * @param columnIndex
          * @since 7.3.9
          */
@@ -4322,7 +4327,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
 
         /**
          * Saves natural column width if it hasn't been saved already.
-         *
+         * 
          * @param columnIndex
          * @since 7.3.9
          */
diff --git a/uitest/src/com/vaadin/tests/components/table/ReloadWidgets.java b/uitest/src/com/vaadin/tests/components/table/ReloadWidgets.java
new file mode 100644 (file)
index 0000000..ef72f92
--- /dev/null
@@ -0,0 +1,118 @@
+package com.vaadin.tests.components.table;
+
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Table;
+
+@SuppressWarnings("serial")
+public class ReloadWidgets extends AbstractTestUI {
+
+    int pressed = 0;
+
+    @Override
+    protected void setup(VaadinRequest request) {
+
+        final Table table = new Table(null, new BeanItemContainer<Bean>(
+                Bean.class));
+        table.setId("table");
+        table.setSizeFull();
+
+        table.setColumnHeader("col1", "Text");
+        table.setColumnHeader("col2", "Button");
+
+        fillTable(table);
+
+        Button button = new Button("Refresh");
+        button.setId("refresh");
+        button.addClickListener(new Button.ClickListener() {
+            @Override
+            public void buttonClick(ClickEvent event) {
+                table.removeAllItems();
+                fillTable(table);
+            }
+        });
+        getLayout().addComponent(button);
+        getLayout().addComponent(table);
+        getLayout().setExpandRatio(table, 1f);
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "Table should always populate button widgets to column 2";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 16611;
+    }
+
+    private void fillTable(Table table) {
+        int i = 0;
+        int size = pressed % 2 == 0 ? 500 : 499;
+        pressed++;
+        for (int step = 0; step < i + size; step++) {
+            String caption = Integer.toString(step);
+            Button button = new Button(caption);
+            button.setId(caption);
+            Bean itemId = new Bean(caption, button);
+            table.addItem(itemId);
+        }
+    }
+
+    public class Bean {
+        private String col1;
+        private Button col2;
+
+        public Bean(String col1, Button col2) {
+            this.col1 = col1;
+            this.col2 = col2;
+        }
+
+        public String getCol1() {
+            return col1;
+        }
+
+        public void setCol1(String col1) {
+            this.col1 = col1;
+        }
+
+        public Button getCol2() {
+            return col2;
+        }
+
+        public void setCol2(Button col2) {
+            this.col2 = col2;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            Bean bean = (Bean) o;
+
+            if (!col1.equals(bean.col1)) {
+                return false;
+            }
+            if (!col2.equals(bean.col2)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = col1.hashCode();
+            result = 31 * result + col2.hashCode();
+            return result;
+        }
+    }
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/ReloadWidgetsTest.java b/uitest/src/com/vaadin/tests/components/table/ReloadWidgetsTest.java
new file mode 100644 (file)
index 0000000..c92e00a
--- /dev/null
@@ -0,0 +1,80 @@
+package com.vaadin.tests.components.table;
+
+import java.util.List;
+
+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.testbench.By;
+import com.vaadin.testbench.elements.TableElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class ReloadWidgetsTest extends MultiBrowserTest {
+
+    private int rowHeight = -1;
+
+    private WebElement wrapper;
+
+    @Override
+    public void setup() throws Exception {
+        super.setup();
+        openTestURL();
+
+        TableElement table = $(TableElement.class).id("table");
+        rowHeight = table.getCell(1, 0).getLocation().getY()
+                - table.getCell(0, 0).getLocation().getY();
+
+        wrapper = findElement(By.className("v-table-body-wrapper"));
+    }
+
+    @Test
+    public void testScrollingThenUpdatingContents() throws Exception {
+        // Scroll down to row 44 so that we get the cut-off point where the
+        // problem becomes apparent
+        testBenchElement(wrapper).scroll(44 * rowHeight);
+        waitForScrollToFinish();
+
+        // Assert that we have the button widget.
+        Assert.assertTrue(
+                "Button widget was not found after scrolling for the first time",
+                !findElements(By.id("46")).isEmpty());
+
+        // Now refresh the container contents
+        WebElement refreshButton = findElement(By.id("refresh"));
+        refreshButton.click();
+
+        // Again scroll down to row 44 so we get the cut-off point visible
+        testBenchElement(wrapper).scroll(44 * rowHeight);
+        waitForScrollToFinish();
+
+        // Assert that we still get the button
+        Assert.assertTrue(
+                "Button widget was not found after refreshing container items.",
+                !findElements(By.id("46")).isEmpty());
+    }
+
+    /**
+     * Waits until the scroll position indicator goes away, signifying that all
+     * the required rows have been fetched.
+     */
+    private void waitForScrollToFinish() {
+        waitUntil(new ExpectedCondition<Boolean>() {
+            @Override
+            public Boolean apply(WebDriver input) {
+                List<WebElement> elements = findElements(By
+                        .className("v-table-scrollposition"));
+                return elements.isEmpty() || !elements.get(0).isDisplayed();
+            }
+
+            @Override
+            public String toString() {
+                // Timed out after 10 seconds waiting for ...
+                return "scroll position indicator to vanish";
+            }
+        });
+    }
+
+}