]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix Escalator testing with assert enabled on PhantomJS (#13334)
authorTeemu Suo-Anttila <teemusa@vaadin.com>
Tue, 2 Dec 2014 13:31:46 +0000 (15:31 +0200)
committerVaadin Code Review <review@vaadin.com>
Wed, 3 Dec 2014 11:22:50 +0000 (11:22 +0000)
Change-Id: I6a5eb39c44873932bdde3a229f7ed52bc7c4df8c

14 files changed:
client/src/com/vaadin/client/ui/grid/Escalator.java
uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java
uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicsTest.java [deleted file]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorColspanTest.java [deleted file]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorColumnFreezingTest.java [deleted file]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorRowColumnTest.java [deleted file]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorScrollTest.java [deleted file]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorUpdaterUiTest.java [deleted file]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColspanTest.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColumnFreezingTest.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRowColumnTest.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorScrollTest.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorUpdaterUiTest.java [new file with mode: 0644]

index bb4ca6ba78da71ad914709a768462b09b2cbb6ef..64b0e31f8413658b75aa6d5594e49412b82457dc 100644 (file)
@@ -1556,7 +1556,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
         private void paintInsertCells(final TableRowElement tr,
                 int logicalRowIndex, final int offset, final int numberOfCells) {
 
-            assert Document.get().isOrHasChild(tr) : "The row must be attached to the document";
+            assert root.isOrHasChild(tr) : "The row must be attached to the document";
 
             flyweightRow.setup(tr, logicalRowIndex,
                     columnConfiguration.getCalculatedColumnWidths());
@@ -1581,6 +1581,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
             } else {
                 referenceCell = null;
             }
+
             for (FlyweightCell cell : cells) {
                 referenceCell = insertAfterReferenceAndUpdateIt(tr,
                         cell.getElement(), referenceCell);
index 31a142d55667f69d172848e8be117912fa249e82..0b2a7a73584c5098a8fd6bb87f8ea10a72d78c97 100644 (file)
@@ -22,14 +22,14 @@ import static org.junit.Assert.fail;
 import org.openqa.selenium.By;
 import org.openqa.selenium.Dimension;
 import org.openqa.selenium.JavascriptExecutor;
-import org.openqa.selenium.NoSuchElementException;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.interactions.Actions;
 
+import com.vaadin.testbench.TestBenchElement;
 import com.vaadin.tests.annotations.TestCategory;
 import com.vaadin.tests.tb3.MultiBrowserTest;
 
-@TestCategory("grid")
+@TestCategory("escalator")
 public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest {
     protected static final String COLUMNS_AND_ROWS = "Columns and Rows";
 
@@ -69,12 +69,12 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
         return EscalatorBasicClientFeatures.class;
     }
 
-    protected WebElement getEscalator() {
-        try {
-            return getDriver().findElement(By.className("v-escalator"));
-        } catch (NoSuchElementException e) {
-            return null;
+    protected TestBenchElement getEscalator() {
+        By className = By.className("v-escalator");
+        if (isElementPresent(className)) {
+            return (TestBenchElement) findElement(className);
         }
+        return null;
     }
 
     /**
@@ -83,7 +83,7 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
      *            calculation starts from the end (-1 is the last, -2 is the
      *            second-to-last etc)
      */
-    protected WebElement getHeaderRow(int row) {
+    protected TestBenchElement getHeaderRow(int row) {
         return getRow("thead", row);
     }
 
@@ -93,7 +93,7 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
      *            calculation starts from the end (-1 is the last, -2 is the
      *            second-to-last etc)
      */
-    protected WebElement getBodyRow(int row) {
+    protected TestBenchElement getBodyRow(int row) {
         return getRow("tbody", row);
     }
 
@@ -103,7 +103,7 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
      *            calculation starts from the end (-1 is the last, -2 is the
      *            second-to-last etc)
      */
-    protected WebElement getFooterRow(int row) {
+    protected TestBenchElement getFooterRow(int row) {
         return getRow("tfoot", row);
     }
 
@@ -113,7 +113,7 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
      *            calculation starts from the end (-1 is the last, -2 is the
      *            second-to-last etc)
      */
-    protected WebElement getHeaderCell(int row, int col) {
+    protected TestBenchElement getHeaderCell(int row, int col) {
         return getCell("thead", row, col);
     }
 
@@ -123,7 +123,7 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
      *            calculation starts from the end (-1 is the last, -2 is the
      *            second-to-last etc)
      */
-    protected WebElement getBodyCell(int row, int col) {
+    protected TestBenchElement getBodyCell(int row, int col) {
         return getCell("tbody", row, col);
     }
 
@@ -133,7 +133,7 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
      *            calculation starts from the end (-1 is the last, -2 is the
      *            second-to-last etc)
      */
-    protected WebElement getFooterCell(int row, int col) {
+    protected TestBenchElement getFooterCell(int row, int col) {
         return getCell("tfoot", row, col);
     }
 
@@ -143,17 +143,13 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
      *            calculation starts from the end (-1 is the last, -2 is the
      *            second-to-last etc)
      */
-    private WebElement getCell(String sectionTag, int row, int col) {
-        WebElement rowElement = getRow(sectionTag, row);
-        if (rowElement != null) {
-            try {
-                return rowElement.findElement(By.xpath("*[" + (col + 1) + "]"));
-            } catch (NoSuchElementException e) {
-                return null;
-            }
-        } else {
-            return null;
+    private TestBenchElement getCell(String sectionTag, int row, int col) {
+        TestBenchElement rowElement = getRow(sectionTag, row);
+        By xpath = By.xpath("*[" + (col + 1) + "]");
+        if (rowElement != null && rowElement.isElementPresent(xpath)) {
+            return (TestBenchElement) rowElement.findElement(xpath);
         }
+        return null;
     }
 
     /**
@@ -162,35 +158,35 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
      *            calculation starts from the end (-1 is the last, -2 is the
      *            second-to-last etc)
      */
-    private WebElement getRow(String sectionTag, int row) {
-        WebElement escalator = getEscalator();
+    private TestBenchElement getRow(String sectionTag, int row) {
+        TestBenchElement escalator = getEscalator();
         WebElement tableSection = escalator.findElement(By.tagName(sectionTag));
+        By xpath;
 
-        try {
-            if (row >= 0) {
-                int fromFirst = row + 1;
-                return tableSection.findElement(By.xpath("tr[" + fromFirst
-                        + "]"));
-            } else {
-                int fromLast = Math.abs(row + 1);
-                return tableSection.findElement(By.xpath("tr[last() - "
-                        + fromLast + "]"));
-            }
-        } catch (NoSuchElementException e) {
-            return null;
+        if (row >= 0) {
+            int fromFirst = row + 1;
+            xpath = By.xpath("tr[" + fromFirst + "]");
+        } else {
+            int fromLast = Math.abs(row + 1);
+            xpath = By.xpath("tr[last() - " + fromLast + "]");
+        }
+        if (tableSection != null
+                && ((TestBenchElement) tableSection).isElementPresent(xpath)) {
+            return (TestBenchElement) tableSection.findElement(xpath);
         }
+        return null;
     }
 
     protected void selectMenu(String menuCaption) {
-        WebElement menuElement = getMenuElement(menuCaption);
+        TestBenchElement menuElement = getMenuElement(menuCaption);
         Dimension size = menuElement.getSize();
         new Actions(getDriver()).moveToElement(menuElement, size.width - 10,
                 size.height / 2).perform();
     }
 
-    private WebElement getMenuElement(String menuCaption) {
-        return getDriver().findElement(
-                By.xpath("//td[text() = '" + menuCaption + "']"));
+    private TestBenchElement getMenuElement(String menuCaption) {
+        return (TestBenchElement) findElement(By.xpath("//td[text() = '"
+                + menuCaption + "']"));
     }
 
     protected void selectMenuPath(String... menuCaptions) {
@@ -217,7 +213,7 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
     }
 
     private String getLogText() {
-        WebElement log = getDriver().findElement(By.cssSelector("#log"));
+        WebElement log = findElement(By.cssSelector("#log"));
         return log.getText();
     }
 
@@ -240,8 +236,8 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
         executeScript("arguments[0].scrollTop = " + px, getVeticalScrollbar());
     }
 
-    private WebElement getVeticalScrollbar() {
-        return getEscalator().findElement(
+    private TestBenchElement getVeticalScrollbar() {
+        return (TestBenchElement) getEscalator().findElement(
                 By.className("v-escalator-scroller-vertical"));
     }
 
@@ -250,8 +246,8 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest
                 getHorizontalScrollbar());
     }
 
-    private WebElement getHorizontalScrollbar() {
-        return getEscalator().findElement(
+    private TestBenchElement getHorizontalScrollbar() {
+        return (TestBenchElement) getEscalator().findElement(
                 By.className("v-escalator-scroller-horizontal"));
     }
 
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicsTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicsTest.java
deleted file mode 100644 (file)
index bac5c24..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.components.grid.basicfeatures;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-
-import org.junit.Test;
-
-import com.vaadin.testbench.elements.NotificationElement;
-
-public class EscalatorBasicsTest extends EscalatorBasicClientFeaturesTest {
-
-    @Test
-    public void testDetachingAnEmptyEscalator() {
-        setDebug(true);
-        openTestURL();
-
-        selectMenuPath(GENERAL, DETACH_ESCALATOR);
-        assertEscalatorIsRemovedCorrectly();
-    }
-
-    @Test
-    public void testDetachingASemiPopulatedEscalator() {
-        setDebug(true);
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, ADD_ONE_OF_EACH_ROW);
-        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
-        selectMenuPath(GENERAL, DETACH_ESCALATOR);
-        assertEscalatorIsRemovedCorrectly();
-    }
-
-    @Test
-    public void testDetachingAPopulatedEscalator() {
-        setDebug(true);
-        openTestURL();
-
-        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
-        selectMenuPath(GENERAL, DETACH_ESCALATOR);
-        assertEscalatorIsRemovedCorrectly();
-    }
-
-    private void assertEscalatorIsRemovedCorrectly() {
-        assertFalse($(NotificationElement.class).exists());
-        assertNull(getEscalator());
-    }
-}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorColspanTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorColspanTest.java
deleted file mode 100644 (file)
index 3c3e16e..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.components.grid.basicfeatures;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.openqa.selenium.WebElement;
-
-public class EscalatorColspanTest extends EscalatorBasicClientFeaturesTest {
-    private static final int NO_COLSPAN = 1;
-
-    @Test
-    public void testNoColspan() {
-        openTestURL();
-        populate();
-
-        assertEquals(NO_COLSPAN, getColSpan(getHeaderCell(0, 0)));
-        assertEquals(NO_COLSPAN, getColSpan(getBodyCell(0, 0)));
-        assertEquals(NO_COLSPAN, getColSpan(getFooterCell(0, 0)));
-    }
-
-    @Test
-    public void testColspan() {
-        openTestURL();
-        populate();
-
-        int singleCellWidth = getWidth(getBodyCell(0, 0));
-        int doubleCellWidth = singleCellWidth * 2;
-
-        selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NORMAL);
-
-        WebElement bodyCell = getBodyCell(0, 0);
-        assertEquals(2, getColSpan(bodyCell));
-        assertEquals(doubleCellWidth, getWidth(bodyCell));
-    }
-
-    @Test
-    public void testColspanToggle() {
-        openTestURL();
-        populate();
-
-        int singleCellWidth = getWidth(getBodyCell(0, 0));
-
-        selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NORMAL);
-        selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NONE);
-
-        WebElement bodyCell = getBodyCell(0, 0);
-        assertEquals(NO_COLSPAN, getColSpan(bodyCell));
-        assertEquals(singleCellWidth, getWidth(bodyCell));
-    }
-
-    private static int getWidth(WebElement element) {
-        String widthString = element.getCssValue("width"); // e.g. 100px
-        if ("0".equals(widthString)) {
-            return 0;
-        } else if (widthString.endsWith("px")) {
-            return Integer.parseInt(widthString.substring(0,
-                    widthString.length() - 2));
-        } else {
-            throw new IllegalStateException("Element width expressed "
-                    + "in an unsupported format: " + widthString);
-        }
-    }
-
-    private static int getColSpan(WebElement cell) {
-        String attribute = cell.getAttribute("colspan");
-        if (attribute == null) {
-            return NO_COLSPAN;
-        } else {
-            return Integer.parseInt(attribute);
-        }
-    }
-}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorColumnFreezingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorColumnFreezingTest.java
deleted file mode 100644 (file)
index 2ea0d86..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.components.grid.basicfeatures;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.junit.Test;
-import org.openqa.selenium.WebElement;
-
-public class EscalatorColumnFreezingTest extends
-        EscalatorBasicClientFeaturesTest {
-
-    private final static Pattern TRANSFORM_PATTERN = Pattern.compile(// @formatter:off
-            // any start of the string
-            ".*"
-
-            // non-capturing group for "webkitTransform: " or "transform: "
-            + "(?:webkitT|t)ransform: "
-
-            // non-capturing group for "translate" or "translate3d"
-            + "translate(?:3d)?"
-
-            // capturing the digits in e.g "(100px,"
-            + "\\((\\d+)px,"
-
-            // any end of the string
-            + ".*");
-
-            // @formatter:on
-
-    private final static Pattern LEFT_PATTERN = Pattern
-            .compile(".*left: (\\d+)px.*");
-
-    private static final int NO_FREEZE = -1;
-
-    @Test
-    public void testNoFreeze() {
-        openTestURL();
-        populate();
-
-        WebElement bodyCell = getBodyCell(0, 0);
-        assertFalse(isFrozen(bodyCell));
-        assertEquals(NO_FREEZE, getFrozenScrollCompensation(bodyCell));
-    }
-
-    @Test
-    public void testOneFreeze() {
-        openTestURL();
-        populate();
-
-        selectMenuPath(FEATURES, FROZEN_COLUMNS, FREEZE_1_COLUMN);
-        int scrollPx = 100;
-        scrollHorizontallyTo(scrollPx);
-
-        WebElement bodyCell = getBodyCell(0, 0);
-        assertTrue(isFrozen(bodyCell));
-        assertEquals(scrollPx, getFrozenScrollCompensation(bodyCell));
-    }
-
-    @Test
-    public void testFreezeToggle() {
-        openTestURL();
-        populate();
-
-        selectMenuPath(FEATURES, FROZEN_COLUMNS, FREEZE_1_COLUMN);
-        scrollHorizontallyTo(100);
-        selectMenuPath(FEATURES, FROZEN_COLUMNS, FREEZE_0_COLUMNS);
-
-        WebElement bodyCell = getBodyCell(0, 0);
-        assertFalse(isFrozen(bodyCell));
-        assertEquals(NO_FREEZE, getFrozenScrollCompensation(bodyCell));
-    }
-
-    private static boolean isFrozen(WebElement cell) {
-        return cell.getAttribute("class").contains("frozen");
-    }
-
-    private static int getFrozenScrollCompensation(WebElement cell) {
-        String styleAttribute = cell.getAttribute("style");
-        Matcher transformMatcher = TRANSFORM_PATTERN.matcher(styleAttribute);
-        Matcher leftMatcher = LEFT_PATTERN.matcher(styleAttribute);
-
-        if (transformMatcher.find()) {
-            return Integer.parseInt(transformMatcher.group(1));
-        } else if (leftMatcher.find()) {
-            return Integer.parseInt(leftMatcher.group(1));
-        } else {
-            return NO_FREEZE;
-        }
-    }
-}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorRowColumnTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorRowColumnTest.java
deleted file mode 100644 (file)
index 831524b..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * 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.components.grid.basicfeatures;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import org.junit.Test;
-import org.openqa.selenium.By;
-
-public class EscalatorRowColumnTest extends EscalatorBasicClientFeaturesTest {
-
-    /**
-     * The scroll position of the Escalator when scrolled all the way down, to
-     * reveal the 100:th row.
-     */
-    private static final int BOTTOM_SCROLL_POSITION = 1857;
-
-    @Test
-    public void testInit() {
-        openTestURL();
-        assertNotNull(getEscalator());
-        assertNull(getHeaderRow(0));
-        assertNull(getBodyRow(0));
-        assertNull(getFooterRow(0));
-
-        assertLogContains("Columns: 0");
-        assertLogContains("Header rows: 0");
-        assertLogContains("Body rows: 0");
-        assertLogContains("Footer rows: 0");
-    }
-
-    @Test
-    public void testInsertAColumn() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
-        assertNull(getHeaderRow(0));
-        assertNull(getBodyRow(0));
-        assertNull(getFooterRow(0));
-        assertLogContains("Columns: 1");
-    }
-
-    @Test
-    public void testInsertAHeaderRow() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
-        assertNull(getHeaderCell(0, 0));
-        assertNull(getBodyCell(0, 0));
-        assertNull(getFooterCell(0, 0));
-        assertLogContains("Header rows: 1");
-    }
-
-    @Test
-    public void testInsertABodyRow() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, ADD_ONE_ROW_TO_BEGINNING);
-        assertNull(getHeaderCell(0, 0));
-        assertNull(getBodyCell(0, 0));
-        assertNull(getFooterCell(0, 0));
-        assertLogContains("Body rows: 1");
-    }
-
-    @Test
-    public void testInsertAFooterRow() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
-        assertNull(getHeaderCell(0, 0));
-        assertNull(getBodyCell(0, 0));
-        assertNull(getFooterCell(0, 0));
-        assertLogContains("Footer rows: 1");
-    }
-
-    @Test
-    public void testInsertAColumnAndAHeaderRow() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
-        selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
-        assertNotNull(getHeaderCell(0, 0));
-        assertNull(getBodyCell(0, 0));
-        assertNull(getFooterCell(0, 0));
-        assertLogContains("Columns: 1");
-        assertLogContains("Header rows: 1");
-    }
-
-    @Test
-    public void testInsertAColumnAndABodyRow() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
-        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, ADD_ONE_ROW_TO_BEGINNING);
-        assertNull(getHeaderCell(0, 0));
-        assertNotNull(getBodyCell(0, 0));
-        assertNull(getFooterCell(0, 0));
-        assertLogContains("Columns: 1");
-        assertLogContains("Body rows: 1");
-    }
-
-    @Test
-    public void testInsertAColumnAndAFooterRow() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
-        selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
-        assertNull(getHeaderCell(0, 0));
-        assertNull(getBodyCell(0, 0));
-        assertNotNull(getFooterCell(0, 0));
-        assertLogContains("Columns: 1");
-        assertLogContains("Footer rows: 1");
-    }
-
-    @Test
-    public void testInsertAHeaderRowAndAColumn() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
-        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
-        assertNotNull(getHeaderCell(0, 0));
-        assertNull(getBodyCell(0, 0));
-        assertNull(getFooterCell(0, 0));
-        assertLogContains("Columns: 1");
-        assertLogContains("Header rows: 1");
-    }
-
-    @Test
-    public void testInsertABodyRowAndAColumn() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, ADD_ONE_ROW_TO_BEGINNING);
-        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
-        assertNull(getHeaderCell(0, 0));
-        assertNotNull(getBodyCell(0, 0));
-        assertNull(getFooterCell(0, 0));
-        assertLogContains("Columns: 1");
-        assertLogContains("Body rows: 1");
-    }
-
-    @Test
-    public void testInsertAFooterRowAndAColumn() {
-        openTestURL();
-
-        selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
-        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
-        assertNull(getHeaderCell(0, 0));
-        assertNull(getBodyCell(0, 0));
-        assertNotNull(getFooterCell(0, 0));
-        assertLogContains("Columns: 1");
-        assertLogContains("Footer rows: 1");
-    }
-
-    @Test
-    public void testFillColRow() {
-        openTestURL();
-
-        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
-        scrollVerticallyTo(2000); // more like 1857, but this should be enough.
-
-        // if not found, an exception is thrown here
-        findElement(By.xpath("//td[text()='Cell: 9,99']"));
-    }
-
-    @Test
-    public void testFillRowCol() {
-        openTestURL();
-
-        selectMenuPath(GENERAL, POPULATE_ROW_COLUMN);
-        scrollVerticallyTo(2000); // more like 1857, but this should be enough.
-
-        // if not found, an exception is thrown here
-        findElement(By.xpath("//td[text()='Cell: 9,99']"));
-    }
-
-    @Test
-    public void testClearColRow() {
-        openTestURL();
-
-        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
-        selectMenuPath(GENERAL, CLEAR_COLUMN_ROW);
-
-        assertNull(getBodyCell(0, 0));
-    }
-
-    @Test
-    public void testClearRowCol() {
-        openTestURL();
-
-        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
-        selectMenuPath(GENERAL, CLEAR_ROW_COLUMN);
-
-        assertNull(getBodyCell(0, 0));
-    }
-
-    @Test
-    public void testResizeColToFit() {
-        openTestURL();
-        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
-
-        int originalWidth = getBodyCell(0, 0).getSize().getWidth();
-        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
-                RESIZE_FIRST_COLUMN_TO_MAX_WIDTH);
-        int newWidth = getBodyCell(0, 0).getSize().getWidth();
-        assertNotEquals("Column width should've changed", originalWidth,
-                newWidth);
-    }
-
-    @Test
-    public void testRemoveMoreThanPagefulAtBottomWhileScrolledToBottom()
-            throws Exception {
-        openTestURL();
-        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
-
-        scrollVerticallyTo(BOTTOM_SCROLL_POSITION);
-        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_50_ROWS_FROM_BOTTOM);
-        assertEquals("Row 49: 0,49", getBodyCell(-1, 0).getText());
-
-        scrollVerticallyTo(0);
-
-        // let the DOM organize itself
-        Thread.sleep(500);
-
-        // if something goes wrong, it'll explode before this.
-        assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText());
-    }
-
-    @Test
-    public void testRemoveMoreThanPagefulAtBottomWhileScrolledAlmostToBottom()
-            throws Exception {
-        openTestURL();
-        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
-
-        // bottom minus 15 rows.
-        scrollVerticallyTo(BOTTOM_SCROLL_POSITION - 15 * 20);
-        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_50_ROWS_FROM_BOTTOM);
-        assertEquals("Row 49: 0,49", getBodyCell(-1, 0).getText());
-
-        scrollVerticallyTo(0);
-
-        // let the DOM organize itself
-        Thread.sleep(500);
-
-        // if something goes wrong, it'll explode before this.
-        assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText());
-    }
-
-    @Test
-    public void testRemoveMoreThanPagefulNearBottomWhileScrolledToBottom()
-            throws Exception {
-        openTestURL();
-        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
-
-        scrollVerticallyTo(BOTTOM_SCROLL_POSITION);
-        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS,
-                REMOVE_50_ROWS_FROM_ALMOST_BOTTOM);
-        assertEquals("Row 49: 0,99", getBodyCell(-1, 0).getText());
-
-        scrollVerticallyTo(0);
-
-        // let the DOM organize itself
-        Thread.sleep(500);
-
-        // if something goes wrong, it'll explode before this.
-        assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText());
-    }
-
-    @Test
-    public void testRemoveMoreThanPagefulNearBottomWhileScrolledAlmostToBottom()
-            throws Exception {
-        openTestURL();
-        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
-
-        // bottom minus 15 rows.
-        scrollVerticallyTo(BOTTOM_SCROLL_POSITION - 15 * 20);
-        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS,
-                REMOVE_50_ROWS_FROM_ALMOST_BOTTOM);
-
-        // let the DOM organize itself
-        Thread.sleep(500);
-        assertEquals("Row 49: 0,99", getBodyCell(-1, 0).getText());
-
-        scrollVerticallyTo(0);
-
-        // let the DOM organize itself
-        Thread.sleep(500);
-
-        // if something goes wrong, it'll explode before this.
-        assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText());
-    }
-}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorScrollTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorScrollTest.java
deleted file mode 100644 (file)
index d2be88b..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.components.grid.basicfeatures;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebElement;
-
-public class EscalatorScrollTest extends EscalatorBasicClientFeaturesTest {
-
-    /**
-     * Before the fix, removing and adding rows and also scrolling would put the
-     * scroll state in an internally inconsistent state. The scrollbar would've
-     * been scrolled correctly, but the body wasn't.
-     * 
-     * This was due to optimizations that didn't keep up with the promises, so
-     * to say. So the optimizations were removed.
-     */
-    @Test
-    public void testScrollRaceCondition() {
-        openTestURL();
-        populate();
-
-        scrollVerticallyTo(40);
-        String originalStyle = getTBodyStyle();
-        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_ALL_INSERT_SCROLL);
-
-        // body should be scrolled to exactly the same spot. (not 0)
-        assertEquals(originalStyle, getTBodyStyle());
-    }
-
-    private String getTBodyStyle() {
-        WebElement tbody = getEscalator().findElement(By.tagName("tbody"));
-        return tbody.getAttribute("style");
-    }
-}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorUpdaterUiTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorUpdaterUiTest.java
deleted file mode 100644 (file)
index c1c3a31..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.components.grid.basicfeatures;
-
-import org.junit.Test;
-
-public class EscalatorUpdaterUiTest extends EscalatorBasicClientFeaturesTest {
-    @Override
-    protected Class<?> getUIClass() {
-        return EscalatorUpdaterUi.class;
-    }
-
-    @Test
-    public void testHeaderPaintOrderRowColRowCol() {
-        boolean addColumnFirst = false;
-        boolean removeColumnFirst = false;
-        testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testHeaderPaintOrderRowColColRow() {
-        boolean addColumnFirst = false;
-        boolean removeColumnFirst = true;
-        testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testHeaderPaintOrderColRowColRow() {
-        boolean addColumnFirst = true;
-        boolean removeColumnFirst = true;
-        testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testHeaderPaintOrderColRowRowCol() {
-        boolean addColumnFirst = true;
-        boolean removeColumnFirst = false;
-        testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testBodyPaintOrderRowColRowCol() {
-        boolean addColumnFirst = false;
-        boolean removeColumnFirst = false;
-        testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testBodyPaintOrderRowColColRow() {
-        boolean addColumnFirst = false;
-        boolean removeColumnFirst = true;
-        testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testBodyPaintOrderColRowColRow() {
-        boolean addColumnFirst = true;
-        boolean removeColumnFirst = true;
-        testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testBodyPaintOrderColRowRowCol() {
-        boolean addColumnFirst = true;
-        boolean removeColumnFirst = false;
-        testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testFooterPaintOrderRowColRowCol() {
-        boolean addColumnFirst = false;
-        boolean removeColumnFirst = false;
-        testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testFooterPaintOrderRowColColRow() {
-        boolean addColumnFirst = false;
-        boolean removeColumnFirst = true;
-        testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testFooterPaintOrderColRowColRow() {
-        boolean addColumnFirst = true;
-        boolean removeColumnFirst = true;
-        testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    @Test
-    public void testFooterPaintOrderColRowRowCol() {
-        boolean addColumnFirst = true;
-        boolean removeColumnFirst = false;
-        testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst);
-    }
-
-    private void testPaintOrder(String tableSection, boolean addColumnFirst,
-            boolean removeColumnFirst) {
-        openTestURL();
-
-        if (addColumnFirst) {
-            selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
-                    ADD_ONE_COLUMN_TO_BEGINNING);
-            selectMenuPath(COLUMNS_AND_ROWS, tableSection,
-                    ADD_ONE_ROW_TO_BEGINNING);
-        } else {
-            selectMenuPath(COLUMNS_AND_ROWS, tableSection,
-                    ADD_ONE_ROW_TO_BEGINNING);
-            selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
-                    ADD_ONE_COLUMN_TO_BEGINNING);
-        }
-
-        assertLogContainsInOrder("preAttach: elementIsAttached == false",
-                "postAttach: elementIsAttached == true",
-                "update: elementIsAttached == true");
-        assertLogDoesNotContain("preDetach");
-        assertLogDoesNotContain("postDetach");
-
-        if (removeColumnFirst) {
-            selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
-                    REMOVE_ONE_COLUMN_FROM_BEGINNING);
-            selectMenuPath(COLUMNS_AND_ROWS, tableSection,
-                    REMOVE_ONE_ROW_FROM_BEGINNING);
-        } else {
-            selectMenuPath(COLUMNS_AND_ROWS, tableSection,
-                    REMOVE_ONE_ROW_FROM_BEGINNING);
-            selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
-                    REMOVE_ONE_COLUMN_FROM_BEGINNING);
-        }
-
-        assertLogContainsInOrder("preDetach: elementIsAttached == true",
-                "postDetach: elementIsAttached == false");
-    }
-
-}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java
new file mode 100644 (file)
index 0000000..95ed6ab
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.components.grid.basicfeatures.escalator;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.vaadin.testbench.elements.NotificationElement;
+import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest;
+
+public class EscalatorBasicsTest extends EscalatorBasicClientFeaturesTest {
+
+    @Test
+    public void testDetachingAnEmptyEscalator() {
+        setDebug(true);
+        openTestURL();
+
+        selectMenuPath(GENERAL, DETACH_ESCALATOR);
+        assertEscalatorIsRemovedCorrectly();
+    }
+
+    @Test
+    public void testDetachingASemiPopulatedEscalator() throws IOException {
+        setDebug(true);
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, ADD_ONE_OF_EACH_ROW);
+        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
+        selectMenuPath(GENERAL, DETACH_ESCALATOR);
+        assertEscalatorIsRemovedCorrectly();
+    }
+
+    @Test
+    public void testDetachingAPopulatedEscalator() {
+        setDebug(true);
+        openTestURL();
+
+        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
+        selectMenuPath(GENERAL, DETACH_ESCALATOR);
+        assertEscalatorIsRemovedCorrectly();
+    }
+
+    private void assertEscalatorIsRemovedCorrectly() {
+        assertFalse($(NotificationElement.class).exists());
+        assertNull(getEscalator());
+    }
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColspanTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColspanTest.java
new file mode 100644 (file)
index 0000000..01247e3
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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.components.grid.basicfeatures.escalator;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest;
+
+public class EscalatorColspanTest extends EscalatorBasicClientFeaturesTest {
+    private static final int NO_COLSPAN = 1;
+
+    @Test
+    public void testNoColspan() {
+        openTestURL();
+        populate();
+
+        assertEquals(NO_COLSPAN, getColSpan(getHeaderCell(0, 0)));
+        assertEquals(NO_COLSPAN, getColSpan(getBodyCell(0, 0)));
+        assertEquals(NO_COLSPAN, getColSpan(getFooterCell(0, 0)));
+    }
+
+    @Test
+    public void testColspan() {
+        openTestURL();
+        populate();
+
+        int singleCellWidth = getWidth(getBodyCell(0, 0));
+        int doubleCellWidth = singleCellWidth * 2;
+
+        selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NORMAL);
+
+        WebElement bodyCell = getBodyCell(0, 0);
+        assertEquals(2, getColSpan(bodyCell));
+        assertEquals(doubleCellWidth, getWidth(bodyCell));
+    }
+
+    @Test
+    public void testColspanToggle() {
+        openTestURL();
+        populate();
+
+        int singleCellWidth = getWidth(getBodyCell(0, 0));
+
+        selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NORMAL);
+        selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NONE);
+
+        WebElement bodyCell = getBodyCell(0, 0);
+        assertEquals(NO_COLSPAN, getColSpan(bodyCell));
+        assertEquals(singleCellWidth, getWidth(bodyCell));
+    }
+
+    private static int getWidth(WebElement element) {
+        String widthString = element.getCssValue("width"); // e.g. 100px
+        if ("0".equals(widthString)) {
+            return 0;
+        } else if (widthString.endsWith("px")) {
+            return Integer.parseInt(widthString.substring(0,
+                    widthString.length() - 2));
+        } else {
+            throw new IllegalStateException("Element width expressed "
+                    + "in an unsupported format: " + widthString);
+        }
+    }
+
+    private static int getColSpan(WebElement cell) {
+        String attribute = cell.getAttribute("colspan");
+        if (attribute == null) {
+            return NO_COLSPAN;
+        } else {
+            return Integer.parseInt(attribute);
+        }
+    }
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColumnFreezingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColumnFreezingTest.java
new file mode 100644 (file)
index 0000000..6b9e36b
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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.components.grid.basicfeatures.escalator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest;
+
+public class EscalatorColumnFreezingTest extends
+        EscalatorBasicClientFeaturesTest {
+
+    private final static Pattern TRANSFORM_PATTERN = Pattern.compile(// @formatter:off
+            // any start of the string
+            ".*"
+
+            // non-capturing group for "webkitTransform: " or "transform: "
+            + "(?:webkitT|t)ransform: "
+
+            // non-capturing group for "translate" or "translate3d"
+            + "translate(?:3d)?"
+
+            // capturing the digits in e.g "(100px,"
+            + "\\((\\d+)px,"
+
+            // any end of the string
+            + ".*", Pattern.CASE_INSENSITIVE);
+
+            // @formatter:on
+
+    private final static Pattern LEFT_PATTERN = Pattern.compile(
+            ".*left: (\\d+)px.*", Pattern.CASE_INSENSITIVE);
+
+    private static final int NO_FREEZE = -1;
+
+    @Test
+    public void testNoFreeze() {
+        openTestURL();
+        populate();
+
+        WebElement bodyCell = getBodyCell(0, 0);
+        assertFalse(isFrozen(bodyCell));
+        assertEquals(NO_FREEZE, getFrozenScrollCompensation(bodyCell));
+    }
+
+    @Test
+    public void testOneFreeze() {
+        openTestURL();
+        populate();
+
+        selectMenuPath(FEATURES, FROZEN_COLUMNS, FREEZE_1_COLUMN);
+        int scrollPx = 100;
+        scrollHorizontallyTo(scrollPx);
+
+        WebElement bodyCell = getBodyCell(0, 0);
+        assertTrue(isFrozen(bodyCell));
+        assertEquals(scrollPx, getFrozenScrollCompensation(bodyCell));
+    }
+
+    @Test
+    public void testFreezeToggle() {
+        openTestURL();
+        populate();
+
+        selectMenuPath(FEATURES, FROZEN_COLUMNS, FREEZE_1_COLUMN);
+        scrollHorizontallyTo(100);
+        selectMenuPath(FEATURES, FROZEN_COLUMNS, FREEZE_0_COLUMNS);
+
+        WebElement bodyCell = getBodyCell(0, 0);
+        assertFalse(isFrozen(bodyCell));
+        assertEquals(NO_FREEZE, getFrozenScrollCompensation(bodyCell));
+    }
+
+    private static boolean isFrozen(WebElement cell) {
+        return cell.getAttribute("class").contains("frozen");
+    }
+
+    private static int getFrozenScrollCompensation(WebElement cell) {
+        String styleAttribute = cell.getAttribute("style");
+        Matcher transformMatcher = TRANSFORM_PATTERN.matcher(styleAttribute);
+        Matcher leftMatcher = LEFT_PATTERN.matcher(styleAttribute);
+
+        if (transformMatcher.find()) {
+            return Integer.parseInt(transformMatcher.group(1));
+        } else if (leftMatcher.find()) {
+            return Integer.parseInt(leftMatcher.group(1));
+        } else {
+            return NO_FREEZE;
+        }
+    }
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRowColumnTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRowColumnTest.java
new file mode 100644 (file)
index 0000000..392a901
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * 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.components.grid.basicfeatures.escalator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+
+import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest;
+
+public class EscalatorRowColumnTest extends EscalatorBasicClientFeaturesTest {
+
+    /**
+     * The scroll position of the Escalator when scrolled all the way down, to
+     * reveal the 100:th row.
+     */
+    private static final int BOTTOM_SCROLL_POSITION = 1857;
+
+    @Test
+    public void testInit() {
+        openTestURL();
+        assertNotNull(getEscalator());
+        assertNull(getHeaderRow(0));
+        assertNull(getBodyRow(0));
+        assertNull(getFooterRow(0));
+
+        assertLogContains("Columns: 0");
+        assertLogContains("Header rows: 0");
+        assertLogContains("Body rows: 0");
+        assertLogContains("Footer rows: 0");
+    }
+
+    @Test
+    public void testInsertAColumn() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
+        assertNull(getHeaderRow(0));
+        assertNull(getBodyRow(0));
+        assertNull(getFooterRow(0));
+        assertLogContains("Columns: 1");
+    }
+
+    @Test
+    public void testInsertAHeaderRow() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
+        assertNull(getHeaderCell(0, 0));
+        assertNull(getBodyCell(0, 0));
+        assertNull(getFooterCell(0, 0));
+        assertLogContains("Header rows: 1");
+    }
+
+    @Test
+    public void testInsertABodyRow() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, ADD_ONE_ROW_TO_BEGINNING);
+        assertNull(getHeaderCell(0, 0));
+        assertNull(getBodyCell(0, 0));
+        assertNull(getFooterCell(0, 0));
+        assertLogContains("Body rows: 1");
+    }
+
+    @Test
+    public void testInsertAFooterRow() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
+        assertNull(getHeaderCell(0, 0));
+        assertNull(getBodyCell(0, 0));
+        assertNull(getFooterCell(0, 0));
+        assertLogContains("Footer rows: 1");
+    }
+
+    @Test
+    public void testInsertAColumnAndAHeaderRow() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
+        selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
+        assertNotNull(getHeaderCell(0, 0));
+        assertNull(getBodyCell(0, 0));
+        assertNull(getFooterCell(0, 0));
+        assertLogContains("Columns: 1");
+        assertLogContains("Header rows: 1");
+    }
+
+    @Test
+    public void testInsertAColumnAndABodyRow() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
+        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, ADD_ONE_ROW_TO_BEGINNING);
+        assertNull(getHeaderCell(0, 0));
+        assertNotNull(getBodyCell(0, 0));
+        assertNull(getFooterCell(0, 0));
+        assertLogContains("Columns: 1");
+        assertLogContains("Body rows: 1");
+    }
+
+    @Test
+    public void testInsertAColumnAndAFooterRow() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
+        selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
+        assertNull(getHeaderCell(0, 0));
+        assertNull(getBodyCell(0, 0));
+        assertNotNull(getFooterCell(0, 0));
+        assertLogContains("Columns: 1");
+        assertLogContains("Footer rows: 1");
+    }
+
+    @Test
+    public void testInsertAHeaderRowAndAColumn() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
+        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
+        assertNotNull(getHeaderCell(0, 0));
+        assertNull(getBodyCell(0, 0));
+        assertNull(getFooterCell(0, 0));
+        assertLogContains("Columns: 1");
+        assertLogContains("Header rows: 1");
+    }
+
+    @Test
+    public void testInsertABodyRowAndAColumn() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, ADD_ONE_ROW_TO_BEGINNING);
+        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
+        assertNull(getHeaderCell(0, 0));
+        assertNotNull(getBodyCell(0, 0));
+        assertNull(getFooterCell(0, 0));
+        assertLogContains("Columns: 1");
+        assertLogContains("Body rows: 1");
+    }
+
+    @Test
+    public void testInsertAFooterRowAndAColumn() {
+        openTestURL();
+
+        selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, ADD_ONE_ROW_TO_BEGINNING);
+        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING);
+        assertNull(getHeaderCell(0, 0));
+        assertNull(getBodyCell(0, 0));
+        assertNotNull(getFooterCell(0, 0));
+        assertLogContains("Columns: 1");
+        assertLogContains("Footer rows: 1");
+    }
+
+    @Test
+    public void testFillColRow() {
+        openTestURL();
+
+        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
+        scrollVerticallyTo(2000); // more like 1857, but this should be enough.
+
+        // if not found, an exception is thrown here
+        assertTrue("Wanted cell was not visible",
+                isElementPresent(By.xpath("//td[text()='Cell: 9,99']")));
+    }
+
+    @Test
+    public void testFillRowCol() {
+        openTestURL();
+
+        selectMenuPath(GENERAL, POPULATE_ROW_COLUMN);
+        scrollVerticallyTo(2000); // more like 1857, but this should be enough.
+
+        // if not found, an exception is thrown here
+        assertTrue("Wanted cell was not visible",
+                isElementPresent(By.xpath("//td[text()='Cell: 9,99']")));
+    }
+
+    @Test
+    public void testClearColRow() {
+        openTestURL();
+
+        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
+        selectMenuPath(GENERAL, CLEAR_COLUMN_ROW);
+
+        assertNull(getBodyCell(0, 0));
+    }
+
+    @Test
+    public void testClearRowCol() {
+        openTestURL();
+
+        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
+        selectMenuPath(GENERAL, CLEAR_ROW_COLUMN);
+
+        assertNull(getBodyCell(0, 0));
+    }
+
+    @Test
+    public void testResizeColToFit() {
+        openTestURL();
+        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
+
+        int originalWidth = getBodyCell(0, 0).getSize().getWidth();
+        selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
+                RESIZE_FIRST_COLUMN_TO_MAX_WIDTH);
+        int newWidth = getBodyCell(0, 0).getSize().getWidth();
+        assertNotEquals("Column width should've changed", originalWidth,
+                newWidth);
+    }
+
+    @Test
+    public void testRemoveMoreThanPagefulAtBottomWhileScrolledToBottom()
+            throws Exception {
+        openTestURL();
+        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
+
+        scrollVerticallyTo(BOTTOM_SCROLL_POSITION);
+        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_50_ROWS_FROM_BOTTOM);
+        assertEquals("Row 49: 0,49", getBodyCell(-1, 0).getText());
+
+        scrollVerticallyTo(0);
+
+        // let the DOM organize itself
+        Thread.sleep(500);
+
+        // if something goes wrong, it'll explode before this.
+        assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText());
+    }
+
+    @Test
+    public void testRemoveMoreThanPagefulAtBottomWhileScrolledAlmostToBottom()
+            throws Exception {
+        openTestURL();
+        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
+
+        // bottom minus 15 rows.
+        scrollVerticallyTo(BOTTOM_SCROLL_POSITION - 15 * 20);
+        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_50_ROWS_FROM_BOTTOM);
+        assertEquals("Row 49: 0,49", getBodyCell(-1, 0).getText());
+
+        scrollVerticallyTo(0);
+
+        // let the DOM organize itself
+        Thread.sleep(500);
+
+        // if something goes wrong, it'll explode before this.
+        assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText());
+    }
+
+    @Test
+    public void testRemoveMoreThanPagefulNearBottomWhileScrolledToBottom()
+            throws Exception {
+        openTestURL();
+        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
+
+        scrollVerticallyTo(BOTTOM_SCROLL_POSITION);
+        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS,
+                REMOVE_50_ROWS_FROM_ALMOST_BOTTOM);
+        assertEquals("Row 49: 0,99", getBodyCell(-1, 0).getText());
+
+        scrollVerticallyTo(0);
+
+        // let the DOM organize itself
+        Thread.sleep(500);
+
+        // if something goes wrong, it'll explode before this.
+        assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText());
+    }
+
+    @Test
+    public void testRemoveMoreThanPagefulNearBottomWhileScrolledAlmostToBottom()
+            throws Exception {
+        openTestURL();
+        selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);
+
+        // bottom minus 15 rows.
+        scrollVerticallyTo(BOTTOM_SCROLL_POSITION - 15 * 20);
+        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS,
+                REMOVE_50_ROWS_FROM_ALMOST_BOTTOM);
+
+        // let the DOM organize itself
+        Thread.sleep(500);
+        assertEquals("Row 49: 0,99", getBodyCell(-1, 0).getText());
+
+        scrollVerticallyTo(0);
+
+        // let the DOM organize itself
+        Thread.sleep(500);
+
+        // if something goes wrong, it'll explode before this.
+        assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText());
+    }
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorScrollTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorScrollTest.java
new file mode 100644 (file)
index 0000000..9152750
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.components.grid.basicfeatures.escalator;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest;
+
+public class EscalatorScrollTest extends EscalatorBasicClientFeaturesTest {
+
+    /**
+     * Before the fix, removing and adding rows and also scrolling would put the
+     * scroll state in an internally inconsistent state. The scrollbar would've
+     * been scrolled correctly, but the body wasn't.
+     * 
+     * This was due to optimizations that didn't keep up with the promises, so
+     * to say. So the optimizations were removed.
+     */
+    @Test
+    public void testScrollRaceCondition() {
+        openTestURL();
+        populate();
+
+        scrollVerticallyTo(40);
+        String originalStyle = getTBodyStyle();
+        selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_ALL_INSERT_SCROLL);
+
+        // body should be scrolled to exactly the same spot. (not 0)
+        assertEquals(originalStyle, getTBodyStyle());
+    }
+
+    private String getTBodyStyle() {
+        WebElement tbody = getEscalator().findElement(By.tagName("tbody"));
+        return tbody.getAttribute("style");
+    }
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorUpdaterUiTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorUpdaterUiTest.java
new file mode 100644 (file)
index 0000000..85d3fc0
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * 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.components.grid.basicfeatures.escalator;
+
+import org.junit.Test;
+
+import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest;
+import com.vaadin.tests.components.grid.basicfeatures.EscalatorUpdaterUi;
+
+public class EscalatorUpdaterUiTest extends EscalatorBasicClientFeaturesTest {
+    @Override
+    protected Class<?> getUIClass() {
+        return EscalatorUpdaterUi.class;
+    }
+
+    @Test
+    public void testHeaderPaintOrderRowColRowCol() {
+        boolean addColumnFirst = false;
+        boolean removeColumnFirst = false;
+        testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testHeaderPaintOrderRowColColRow() {
+        boolean addColumnFirst = false;
+        boolean removeColumnFirst = true;
+        testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testHeaderPaintOrderColRowColRow() {
+        boolean addColumnFirst = true;
+        boolean removeColumnFirst = true;
+        testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testHeaderPaintOrderColRowRowCol() {
+        boolean addColumnFirst = true;
+        boolean removeColumnFirst = false;
+        testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testBodyPaintOrderRowColRowCol() {
+        boolean addColumnFirst = false;
+        boolean removeColumnFirst = false;
+        testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testBodyPaintOrderRowColColRow() {
+        boolean addColumnFirst = false;
+        boolean removeColumnFirst = true;
+        testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testBodyPaintOrderColRowColRow() {
+        boolean addColumnFirst = true;
+        boolean removeColumnFirst = true;
+        testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testBodyPaintOrderColRowRowCol() {
+        boolean addColumnFirst = true;
+        boolean removeColumnFirst = false;
+        testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testFooterPaintOrderRowColRowCol() {
+        boolean addColumnFirst = false;
+        boolean removeColumnFirst = false;
+        testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testFooterPaintOrderRowColColRow() {
+        boolean addColumnFirst = false;
+        boolean removeColumnFirst = true;
+        testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testFooterPaintOrderColRowColRow() {
+        boolean addColumnFirst = true;
+        boolean removeColumnFirst = true;
+        testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    @Test
+    public void testFooterPaintOrderColRowRowCol() {
+        boolean addColumnFirst = true;
+        boolean removeColumnFirst = false;
+        testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst);
+    }
+
+    private void testPaintOrder(String tableSection, boolean addColumnFirst,
+            boolean removeColumnFirst) {
+        openTestURL();
+
+        if (addColumnFirst) {
+            selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
+                    ADD_ONE_COLUMN_TO_BEGINNING);
+            selectMenuPath(COLUMNS_AND_ROWS, tableSection,
+                    ADD_ONE_ROW_TO_BEGINNING);
+        } else {
+            selectMenuPath(COLUMNS_AND_ROWS, tableSection,
+                    ADD_ONE_ROW_TO_BEGINNING);
+            selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
+                    ADD_ONE_COLUMN_TO_BEGINNING);
+        }
+
+        assertLogContainsInOrder("preAttach: elementIsAttached == false",
+                "postAttach: elementIsAttached == true",
+                "update: elementIsAttached == true");
+        assertLogDoesNotContain("preDetach");
+        assertLogDoesNotContain("postDetach");
+
+        if (removeColumnFirst) {
+            selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
+                    REMOVE_ONE_COLUMN_FROM_BEGINNING);
+            selectMenuPath(COLUMNS_AND_ROWS, tableSection,
+                    REMOVE_ONE_ROW_FROM_BEGINNING);
+        } else {
+            selectMenuPath(COLUMNS_AND_ROWS, tableSection,
+                    REMOVE_ONE_ROW_FROM_BEGINNING);
+            selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
+                    REMOVE_ONE_COLUMN_FROM_BEGINNING);
+        }
+
+        assertLogContainsInOrder("preDetach: elementIsAttached == true",
+                "postDetach: elementIsAttached == false");
+    }
+
+}