/* * Copyright 2000-2016 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.v7.tests.components.grid.basicfeatures.server; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.List; import org.junit.Test; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebElement; import com.vaadin.testbench.By; import com.vaadin.testbench.TestBenchElement; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; import com.vaadin.testbench.elements.NotificationElement; import com.vaadin.v7.tests.components.grid.basicfeatures.GridBasicFeatures; import com.vaadin.v7.tests.components.grid.basicfeatures.GridBasicFeaturesTest; public class GridStructureTest extends GridBasicFeaturesTest { @Test public void testRemovingAllColumns() { setDebug(true); openTestURL(); for (int i = 0; i < GridBasicFeatures.COLUMNS; ++i) { selectMenuPath("Component", "Columns", "Column " + i, "Add / Remove"); assertFalse(isElementPresent(NotificationElement.class)); } assertEquals("Headers still visible.", 0, getGridHeaderRowCells().size()); } @Test public void testRemoveAndAddColumn() { setDebug(true); openTestURL(); assertEquals("column 0", getGridElement().getHeaderCell(0, 0).getText().toLowerCase()); selectMenuPath("Component", "Columns", "Column 0", "Add / Remove"); assertEquals("column 1", getGridElement().getHeaderCell(0, 0).getText().toLowerCase()); selectMenuPath("Component", "Columns", "Column 0", "Add / Remove"); // Column 0 is now the last column in Grid. assertEquals("Unexpected column content", "(0, 0)", getGridElement().getCell(0, 11).getText()); } @Test public void testRemovingColumn() throws Exception { openTestURL(); // Column 0 should be visible List<TestBenchElement> cells = getGridHeaderRowCells(); assertEquals("column 0", cells.get(0).getText().toLowerCase()); // Hide column 0 selectMenuPath("Component", "Columns", "Column 0", "Add / Remove"); // Column 1 should now be the first cell cells = getGridHeaderRowCells(); assertEquals("column 1", cells.get(0).getText().toLowerCase()); } @Test public void testDataLoadingAfterRowRemoval() throws Exception { openTestURL(); // Remove columns 2,3,4 selectMenuPath("Component", "Columns", "Column 2", "Add / Remove"); selectMenuPath("Component", "Columns", "Column 3", "Add / Remove"); selectMenuPath("Component", "Columns", "Column 4", "Add / Remove"); // Scroll so new data is lazy loaded scrollGridVerticallyTo(1000); // Let lazy loading do its job sleep(1000); // Check that row is loaded assertThat(getGridElement().getCell(11, 0).getText(), not("...")); } @Test public void testFreezingColumn() throws Exception { openTestURL(); // Freeze column 1 selectMenuPath("Component", "State", "Frozen column count", "1"); WebElement cell = getGridElement().getCell(0, 0); assertTrue(cell.getAttribute("class").contains("frozen")); cell = getGridElement().getCell(0, 1); assertFalse(cell.getAttribute("class").contains("frozen")); } @Test public void testInitialColumnWidths() throws Exception { openTestURL(); WebElement cell = getGridElement().getCell(0, 0); assertEquals(100, cell.getSize().getWidth()); cell = getGridElement().getCell(0, 1); assertEquals(150, cell.getSize().getWidth()); cell = getGridElement().getCell(0, 2); assertEquals(200, cell.getSize().getWidth()); } @Test public void testColumnWidths() throws Exception { openTestURL(); // Default column width is 100px WebElement cell = getGridElement().getCell(0, 0); assertEquals(100, cell.getSize().getWidth()); // Set first column to be 200px wide selectMenuPath("Component", "Columns", "Column 0", "Column 0 Width", "200px"); cell = getGridElement().getCell(0, 0); assertEquals(200, cell.getSize().getWidth()); // Set second column to be 150px wide selectMenuPath("Component", "Columns", "Column 1", "Column 1 Width", "150px"); cell = getGridElement().getCell(0, 1); assertEquals(150, cell.getSize().getWidth()); selectMenuPath("Component", "Columns", "Column 0", "Column 0 Width", "Auto"); // since the column 0 was previously 200, it should've shrunk when // autoresizing. cell = getGridElement().getCell(0, 0); assertLessThan("", cell.getSize().getWidth(), 200); } @Test public void testPrimaryStyleNames() throws Exception { openTestURL(); // v-grid is default primary style namea assertPrimaryStylename("v-grid"); selectMenuPath("Component", "State", "Primary style name", "v-escalator"); assertPrimaryStylename("v-escalator"); selectMenuPath("Component", "State", "Primary style name", "my-grid"); assertPrimaryStylename("my-grid"); selectMenuPath("Component", "State", "Primary style name", "v-grid"); assertPrimaryStylename("v-grid"); } /** * Test that the current view is updated when a server-side container change * occurs (without scrolling back and forth) */ @Test public void testItemSetChangeEvent() throws Exception { openTestURL(); final org.openqa.selenium.By newRow = By .xpath("//td[text()='newcell: 0']"); assertTrue("Unexpected initial state", !isElementPresent(newRow)); selectMenuPath("Component", "Body rows", "Add first row"); assertTrue("Add row failed", isElementPresent(newRow)); selectMenuPath("Component", "Body rows", "Remove first row"); assertTrue("Remove row failed", !isElementPresent(newRow)); } /** * Test that the current view is updated when a property's value is reflect * to the client, when the value is modified server-side. */ @Test public void testPropertyValueChangeEvent() throws Exception { openTestURL(); assertEquals("Unexpected cell initial state", "(0, 0)", getGridElement().getCell(0, 0).getText()); selectMenuPath("Component", "Body rows", "Modify first row (getItemProperty)"); assertEquals("(First) modification with getItemProperty failed", "modified: 0", getGridElement().getCell(0, 0).getText()); selectMenuPath("Component", "Body rows", "Modify first row (getContainerProperty)"); assertEquals("(Second) modification with getItemProperty failed", "modified: Column 0", getGridElement().getCell(0, 0).getText()); } @Test public void testRemovingAllItems() throws Exception { openTestURL(); selectMenuPath("Component", "Body rows", "Remove all rows"); assertEquals(0, getGridElement().findElement(By.tagName("tbody")) .findElements(By.tagName("tr")).size()); } @Test public void testRemoveFirstRowTwice() { openTestURL(); selectMenuPath("Component", "Body rows", "Remove first row"); selectMenuPath("Component", "Body rows", "Remove first row"); getGridElement().scrollToRow(50); assertFalse("Listener setup problem occurred.", logContainsText("AssertionError: Value change listeners")); } @Test public void testVerticalScrollBarVisibilityWhenEnoughRows() throws Exception { openTestURL(); assertTrue(verticalScrollbarIsPresent()); selectMenuPath("Component", "Body rows", "Remove all rows"); assertFalse(verticalScrollbarIsPresent()); selectMenuPath("Component", "Size", "HeightMode Row"); selectMenuPath("Component", "Size", "Height by Rows", "2.33 rows"); selectMenuPath("Component", "Body rows", "Add first row"); selectMenuPath("Component", "Body rows", "Add first row"); assertFalse(verticalScrollbarIsPresent()); selectMenuPath("Component", "Body rows", "Add first row"); assertTrue(verticalScrollbarIsPresent()); } @Test public void testBareItemSetChange() throws Exception { openTestURL(); filterSomeAndAssert(); } @Test public void testBareItemSetChangeRemovingAllRows() throws Exception { openTestURL(); selectMenuPath("Component", "Filter", "Impassable filter"); assertFalse("A notification shouldn't have been displayed", $(NotificationElement.class).exists()); assertTrue("No body cells should've been found", getGridElement() .getBody().findElements(By.tagName("td")).isEmpty()); } @Test public void testBareItemSetChangeWithMidScroll() throws Exception { openTestURL(); getGridElement().scrollToRow(GridBasicFeatures.ROWS / 2); filterSomeAndAssert(); } @Test public void testBareItemSetChangeWithBottomScroll() throws Exception { openTestURL(); getGridElement().scrollToRow(GridBasicFeatures.ROWS); filterSomeAndAssert(); } @Test public void testBareItemSetChangeWithBottomScrollAndSmallViewport() throws Exception { openTestURL(); selectMenuPath("Component", "Size", "HeightMode Row"); getGridElement().getRow(GridBasicFeatures.ROWS - 1); // filter selectMenuPath("Component", "Filter", "Column 1 starts with \"(23\""); String text = getGridElement().getCell(10, 0).getText(); assertFalse(text.isEmpty()); } private void filterSomeAndAssert() { selectMenuPath("Component", "Filter", "Column 1 starts with \"(23\""); boolean foundElements = false; for (int row = 0; row < 100; row++) { try { GridCellElement cell = getGridElement().getCell(row, 1); foundElements = true; assertTrue( "Unexpected cell contents. " + "Did the ItemSetChange work after all?", cell.getText().startsWith("(23")); } catch (NoSuchElementException e) { assertTrue("No rows were found", foundElements); return; } } fail("unexpected amount of rows post-filter. Did the ItemSetChange work after all?"); } @Test public void testRemoveLastColumn() { setDebug(true); openTestURL(); int col = GridBasicFeatures.COLUMNS; String columnName = "Column " + (GridBasicFeatures.COLUMNS - 1); assertTrue(columnName + " was not present in DOM", isElementPresent(By.xpath("//th[" + col + "]/div[1]"))); selectMenuPath("Component", "Columns", columnName, "Add / Remove"); assertFalse(isElementPresent(NotificationElement.class)); assertFalse(columnName + " was still present in DOM", isElementPresent(By.xpath("//th[" + col + "]/div[1]"))); } @Test public void testReverseColumns() { openTestURL(); String[] gridData = new String[GridBasicFeatures.COLUMNS]; GridElement grid = getGridElement(); for (int i = 0; i < gridData.length; ++i) { gridData[i] = grid.getCell(0, i).getAttribute("innerHTML"); } selectMenuPath("Component", "State", "Reverse Grid Columns"); // Compare with reversed order for (int i = 0; i < gridData.length; ++i) { final int column = gridData.length - 1 - i; final String newText = grid.getCell(0, column) .getAttribute("innerHTML"); assertEquals( "Grid contained unexpected values. (0, " + column + ")", gridData[i], newText); } } @Test public void testAddingProperty() { setDebug(true); openTestURL(); assertNotEquals("property value", getGridElement().getCell(0, 0).getText()); selectMenuPath("Component", "Properties", "Prepend property"); assertEquals("property value", getGridElement().getCell(0, 0).getText()); } @Test public void testRemovingAddedProperty() { openTestURL(); assertEquals("(0, 0)", getGridElement().getCell(0, 0).getText()); assertNotEquals("property value", getGridElement().getCell(0, 0).getText()); selectMenuPath("Component", "Properties", "Prepend property"); selectMenuPath("Component", "Properties", "Prepend property"); assertNotEquals("property value", getGridElement().getCell(0, 0).getText()); assertEquals("(0, 0)", getGridElement().getCell(0, 0).getText()); } private boolean verticalScrollbarIsPresent() { return "scroll" .equals(getGridVerticalScrollbar().getCssValue("overflow-y")); } @Test public void testAddRowAboveViewport() { setDebug(true); openTestURL(); GridCellElement cell = getGridElement().getCell(500, 1); String cellContent = cell.getText(); selectMenuPath("Component", "Body rows", "Add first row"); assertFalse("Error notification was present", isElementPresent(NotificationElement.class)); assertEquals("Grid scrolled unexpectedly", cellContent, cell.getText()); } @Test public void testRemoveAndAddRowAboveViewport() { setDebug(true); openTestURL(); GridCellElement cell = getGridElement().getCell(500, 1); String cellContent = cell.getText(); selectMenuPath("Component", "Body rows", "Remove first row"); assertFalse("Error notification was present after removing row", isElementPresent(NotificationElement.class)); assertEquals("Grid scrolled unexpectedly", cellContent, cell.getText()); selectMenuPath("Component", "Body rows", "Add first row"); assertFalse("Error notification was present after adding row", isElementPresent(NotificationElement.class)); assertEquals("Grid scrolled unexpectedly", cellContent, cell.getText()); } @Test public void testScrollAndRemoveAll() { setDebug(true); openTestURL(); getGridElement().scrollToRow(500); selectMenuPath("Component", "Body rows", "Remove all rows"); assertFalse("Error notification was present after removing all rows", isElementPresent(NotificationElement.class)); assertFalse( getGridElement().isElementPresent(By.vaadin("#cell[0][0]"))); } private void assertPrimaryStylename(String stylename) { assertTrue(getGridElement().getAttribute("class").contains(stylename)); String tableWrapperStyleName = getGridElement().getTableWrapper() .getAttribute("class"); assertTrue(tableWrapperStyleName.contains(stylename + "-tablewrapper")); String hscrollStyleName = getGridElement().getHorizontalScroller() .getAttribute("class"); assertTrue(hscrollStyleName.contains(stylename + "-scroller")); assertTrue( hscrollStyleName.contains(stylename + "-scroller-horizontal")); String vscrollStyleName = getGridElement().getVerticalScroller() .getAttribute("class"); assertTrue(vscrollStyleName.contains(stylename + "-scroller")); assertTrue(vscrollStyleName.contains(stylename + "-scroller-vertical")); } @Test public void testScrollPosDoesNotChangeAfterStateChange() { openTestURL(); scrollGridVerticallyTo(1000); int scrollPos = getGridVerticalScrollPos(); selectMenuPath("Component", "Editor", "Enabled"); assertEquals("Scroll position should've not have changed", scrollPos, getGridVerticalScrollPos()); } @Test public void testReloadPage() throws InterruptedException { setDebug(true); openTestURL(); reopenTestURL(); // After opening the URL Grid can be stuck in a state where it thinks it // should wait for something that's not going to happen. testBench().disableWaitForVaadin(); // Wait until page is loaded completely. int count = 0; while (!$(GridElement.class).exists()) { if (count == 100) { fail("Reloading page failed"); } sleep(100); ++count; } // Wait a bit more for notification to occur. sleep(1000); assertFalse("Exception occurred when reloading page", isElementPresent(NotificationElement.class)); } @Test public void testAddThirdRowToGrid() { openTestURL(); selectMenuPath("Component", "Body rows", "Add third row"); assertFalse(logContainsText("Exception occured")); } @Test public void getBodyRowCountJS() { openTestURL(); GridElement grid = $(GridElement.class).first(); assertEquals(1000L, executeScript("return arguments[0].getBodyRowCount()", grid)); selectMenuPath("Component", "Body rows", "Remove all rows"); assertEquals(0L, executeScript("return arguments[0].getBodyRowCount()", grid)); selectMenuPath("Component", "Body rows", "Add first row"); assertEquals(1L, executeScript("return arguments[0].getBodyRowCount()", grid)); } }