diff options
author | Teemu Suo-Anttila <teemusa@vaadin.com> | 2016-08-24 14:05:02 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2016-08-29 08:56:56 +0000 |
commit | b4861eda6bbda053277e3fb6858b8a94e8c3243b (patch) | |
tree | 5b120ff177526702a4586eeb4afdd46aef341ea1 /uitest | |
parent | 010954022ddf6d0bcac3df9a098ce67603d3322b (diff) | |
download | vaadin-framework-b4861eda6bbda053277e3fb6858b8a94e8c3243b.tar.gz vaadin-framework-b4861eda6bbda053277e3fb6858b8a94e8c3243b.zip |
Implement DetailsGenerators for Grid
Change-Id: I09057b990f10bde6cf72a16677e58cb2bc9a7029
Diffstat (limited to 'uitest')
5 files changed, 465 insertions, 11 deletions
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java b/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java index 8ef56e7f64..fa032dac48 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java @@ -1,19 +1,106 @@ package com.vaadin.tests.components.grid.basics; import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import com.vaadin.server.VaadinRequest; import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Component; +import com.vaadin.ui.CssLayout; import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.DetailsGenerator; +import com.vaadin.ui.Label; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.MenuBar.MenuItem; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Panel; +import com.vaadin.ui.VerticalLayout; public class GridBasics extends AbstractTestUIWithLog { + private static class DetailedDetailsGenerator + implements DetailsGenerator<DataObject> { + + @Override + public Component apply(DataObject dataObj) { + CssLayout cssLayout = new CssLayout(); + cssLayout.setHeight("200px"); + cssLayout.setWidth("100%"); + + cssLayout.addComponent( + new Label("Row Number: " + dataObj.getRowNumber())); + cssLayout.addComponent(new Label("Date: " + dataObj.getDate())); + cssLayout.addComponent( + new Label("Big Random: " + dataObj.getBigRandom())); + cssLayout.addComponent( + new Label("Small Random: " + dataObj.getSmallRandom())); + + cssLayout + .addComponent(new Button("Press me", + e -> Notification.show("You clicked on the " + + "button in the details for " + "row " + + dataObj.getRowNumber()))); + return cssLayout; + } + } + + private static class PersistingDetailsGenerator + implements DetailsGenerator<DataObject> { + + private Map<DataObject, Panel> detailsMap = new HashMap<>(); + + @Override + public Component apply(DataObject dataObj) { + if (!detailsMap.containsKey(dataObj)) { + Panel panel = new Panel(); + panel.setContent(new Label("One")); + detailsMap.put(dataObj, panel); + } + return detailsMap.get(dataObj); + } + + public void changeDetailsComponent(MenuItem item) { + for (DataObject id : detailsMap.keySet()) { + Panel panel = detailsMap.get(id); + Label label = (Label) panel.getContent(); + if (label.getValue().equals("One")) { + panel.setContent(new Label("Two")); + } else { + panel.setContent(new Label("One")); + } + } + } + } + private Grid<DataObject> grid; + private Map<String, DetailsGenerator<DataObject>> generators = new LinkedHashMap<>(); + private List<DataObject> data; + private int watchingCount = 0; + private PersistingDetailsGenerator persistingDetails; + + public GridBasics() { + generators.put("NULL", null); + generators.put("Detailed", new DetailedDetailsGenerator()); + generators + .put("\"Watching\"", + dataObj -> new Label("You are watching item id " + + dataObj.getRowNumber() + " (" + + (watchingCount++) + ")")); + persistingDetails = new PersistingDetailsGenerator(); + generators.put("Persisting", persistingDetails); + } @Override protected void setup(VaadinRequest request) { - List<DataObject> data = DataObject.generateObjects(); + data = DataObject.generateObjects(); + + VerticalLayout layout = new VerticalLayout(); + layout.setSpacing(true); + layout.setSizeFull(); // Create grid grid = new Grid<>(); @@ -26,7 +113,50 @@ public class GridBasics extends AbstractTestUIWithLog { grid.addColumn("Small Random", Integer.class, DataObject::getSmallRandom); - addComponent(grid); + layout.addComponent(createMenu()); + layout.addComponent(grid); + addComponent(layout); + } + + private Component createMenu() { + MenuBar menu = new MenuBar(); + MenuItem componentMenu = menu.addItem("Component", null); + createDetailsMenu(componentMenu.addItem("Details", null)); + return menu; + } + + /* DetailsGenerator related things */ + + private void createDetailsMenu(MenuItem detailsMenu) { + MenuItem generatorsMenu = detailsMenu.addItem("Generators", null); + + generators.forEach((name, gen) -> generatorsMenu.addItem(name, + item -> grid.setDetailsGenerator(gen))); + + generatorsMenu.addItem("- Change Component", + persistingDetails::changeDetailsComponent); + + detailsMenu.addItem("Toggle First", item -> { + DataObject first = data.get(0); + openOrCloseDetails(first); + openOrCloseDetails(first); + }); + detailsMenu.addItem("Open First", item -> { + DataObject object = data.get(0); + openOrCloseDetails(object); + }); + detailsMenu.addItem("Open 1", item -> { + DataObject object = data.get(1); + openOrCloseDetails(object); + }); + detailsMenu.addItem("Open 995", item -> { + DataObject object = data.get(995); + openOrCloseDetails(object); + }); + } + + private void openOrCloseDetails(DataObject dataObj) { + grid.setDetailsVisible(dataObj, !grid.isDetailsVisible(dataObj)); } } diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridBasicDetailsTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridBasicDetailsTest.java new file mode 100644 index 0000000000..a0f36703da --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridBasicDetailsTest.java @@ -0,0 +1,301 @@ +package com.vaadin.tests.components.grid.basics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.NoSuchElementException; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.NotificationElement; + +public class GridBasicDetailsTest extends GridBasicsTest { + /** + * The reason to why last item details wasn't selected is that since it will + * exist only after the viewport has been scrolled into view, we wouldn't be + * able to scroll that particular details row into view, making tests + * awkward with two scroll commands back to back. + */ + private static final int ALMOST_LAST_INDEX = 995; + private static final String[] OPEN_ALMOST_LAST_ITEM_DETAILS = new String[] { + "Component", "Details", "Open " + ALMOST_LAST_INDEX }; + private static final String[] OPEN_FIRST_ITEM_DETAILS = new String[] { + "Component", "Details", "Open First" }; + private static final String[] TOGGLE_FIRST_ITEM_DETAILS = new String[] { + "Component", "Details", "Toggle First" }; + private static final String[] DETAILS_GENERATOR_NULL = new String[] { + "Component", "Details", "Generators", "NULL" }; + private static final String[] DETAILS_GENERATOR_WATCHING = new String[] { + "Component", "Details", "Generators", "\"Watching\"" }; + private static final String[] DETAILS_GENERATOR_PERSISTING = new String[] { + "Component", "Details", "Generators", "Persisting" }; + private static final String[] CHANGE_HIERARCHY = new String[] { "Component", + "Details", "Generators", "- Change Component" }; + + @Override + @Before + public void setUp() { + openTestURL(); + } + + @Test(expected = NoSuchElementException.class) + public void openWithNoGenerator() { + try { + getGridElement().getDetails(0); + fail("Expected NoSuchElementException"); + } catch (NoSuchElementException ignore) { + // expected + } + + try { + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + } catch (NoSuchElementException e) { + Assert.fail("Unable to set up details."); + } + + getGridElement().getDetails(0); + } + + @Test + public void openVisiblePopulatedDetails() { + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + assertNotNull("details should've populated", getGridElement() + .getDetails(0).findElement(By.className("v-widget"))); + } + + @Test(expected = NoSuchElementException.class) + public void closeVisiblePopulatedDetails() { + try { + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + } catch (NoSuchElementException e) { + Assert.fail("Unable to set up details."); + } + getGridElement().getDetails(0); + } + + @Test + public void openDetailsOutsideOfActiveRange() throws InterruptedException { + getGridElement().scroll(10000); + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + getGridElement().scroll(0); + assertNotNull("details should've been opened", + getGridElement().getDetails(0)); + } + + @Test(expected = NoSuchElementException.class) + public void closeDetailsOutsideOfActiveRange() { + try { + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + getGridElement().scroll(10000); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + getGridElement().scroll(0); + } catch (NoSuchElementException e) { + Assert.fail("Unable to set up details."); + } + getGridElement().getDetails(0); + } + + @Test + public void componentIsVisibleClientSide() { + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + + TestBenchElement details = getGridElement().getDetails(0); + assertNotNull("No widget detected inside details", + details.findElement(By.className("v-widget"))); + } + + @Test + public void openingDetailsTwice() { + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); // open + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); // close + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); // open + + TestBenchElement details = getGridElement().getDetails(0); + assertNotNull("No widget detected inside details", + details.findElement(By.className("v-widget"))); + } + + @Test(expected = NoSuchElementException.class) + public void scrollingDoesNotCreateAFloodOfDetailsRows() { + try { + selectMenuPath(DETAILS_GENERATOR_WATCHING); + + // scroll somewhere to hit uncached rows + getGridElement().scrollToRow(101); + } catch (NoSuchElementException e) { + Assert.fail("Unable to set up details."); + } + + // this should throw + getGridElement().getDetails(100); + } + + @Test + public void openingDetailsOutOfView() { + getGridElement().scrollToRow(500); + + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + + getGridElement().scrollToRow(0); + + // if this fails, it'll fail before the assertNotNull + assertNotNull("unexpected null details row", + getGridElement().getDetails(0)); + } + + @Test + public void togglingAVisibleDetailsRowWithOneRoundtrip() { + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); // open + + assertTrue("Unexpected generator content", + getGridElement().getDetails(0).getText().endsWith("(0)")); + selectMenuPath(TOGGLE_FIRST_ITEM_DETAILS); + assertTrue("New component was not displayed in the client", + getGridElement().getDetails(0).getText().endsWith("(1)")); + } + + @Test + public void almostLastItemIdIsRendered() { + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(OPEN_ALMOST_LAST_ITEM_DETAILS); + scrollGridVerticallyTo(100000); + + TestBenchElement details = getGridElement() + .getDetails(ALMOST_LAST_INDEX); + assertNotNull(details); + assertTrue("Unexpected details content", + details.getText().endsWith(ALMOST_LAST_INDEX + " (0)")); + } + + @Test + public void persistingChangesWorkInDetails() { + selectMenuPath(DETAILS_GENERATOR_PERSISTING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + assertEquals("One", getGridElement().getDetails(0).getText()); + selectMenuPath(CHANGE_HIERARCHY); + assertEquals("Two", getGridElement().getDetails(0).getText()); + } + + @Test + public void persistingChangesWorkInDetailsWhileOutOfView() { + selectMenuPath(DETAILS_GENERATOR_PERSISTING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + assertEquals("One", getGridElement().getDetails(0).getText()); + scrollGridVerticallyTo(10000); + selectMenuPath(CHANGE_HIERARCHY); + scrollGridVerticallyTo(0); + assertEquals("Two", getGridElement().getDetails(0).getText()); + } + + @Test + public void persistingChangesWorkInDetailsWhenNotAttached() { + selectMenuPath(DETAILS_GENERATOR_PERSISTING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + assertEquals("One", getGridElement().getDetails(0).getText()); + + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + assertFalse("Details should be detached", + getGridElement().isElementPresent(By.vaadin("#details[0]"))); + + selectMenuPath(CHANGE_HIERARCHY); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + + assertEquals("Two", getGridElement().getDetails(0).getText()); + } + + @Test + public void swappingDetailsGenerators_noDetailsShown() { + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(DETAILS_GENERATOR_NULL); + assertFalse("Got some errors", $(NotificationElement.class).exists()); + } + + @Test + public void swappingDetailsGenerators_shownDetails() { + selectMenuPath(DETAILS_GENERATOR_PERSISTING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + assertTrue("Details should contain 'One' at first", + getGridElement().getDetails(0).getText().contains("One")); + + selectMenuPath(DETAILS_GENERATOR_WATCHING); + assertFalse( + "Details should contain 'Watching' after swapping generator", + getGridElement().getDetails(0).getText().contains("Watching")); + } + + @Test + public void swappingDetailsGenerators_whileDetailsScrolledOut_showNever() { + scrollGridVerticallyTo(1000); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + selectMenuPath(DETAILS_GENERATOR_WATCHING); + assertFalse("Got some errors", $(NotificationElement.class).exists()); + } + + @Test + public void swappingDetailsGenerators_whileDetailsScrolledOut_showAfter() { + scrollGridVerticallyTo(1000); + selectMenuPath(DETAILS_GENERATOR_PERSISTING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + selectMenuPath(DETAILS_GENERATOR_WATCHING); + scrollGridVerticallyTo(0); + + assertFalse("Got some errors", $(NotificationElement.class).exists()); + assertNotNull("Could not find a details", + getGridElement().getDetails(0)); + } + + @Test + public void swappingDetailsGenerators_whileDetailsScrolledOut_showBefore() { + selectMenuPath(DETAILS_GENERATOR_PERSISTING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + selectMenuPath(DETAILS_GENERATOR_WATCHING); + scrollGridVerticallyTo(1000); + + assertFalse("Got some errors", $(NotificationElement.class).exists()); + assertNotNull("Could not find a details", + getGridElement().getDetails(0)); + } + + @Test + public void swappingDetailsGenerators_whileDetailsScrolledOut_showBeforeAndAfter() { + selectMenuPath(DETAILS_GENERATOR_PERSISTING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + selectMenuPath(DETAILS_GENERATOR_WATCHING); + scrollGridVerticallyTo(1000); + scrollGridVerticallyTo(0); + + assertFalse("Got some errors", $(NotificationElement.class).exists()); + assertNotNull("Could not find a details", + getGridElement().getDetails(0)); + } + + @Test + public void noAssertErrorsOnEmptyDetailsAndScrollDown() { + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + scrollGridVerticallyTo(500); + assertFalse(logContainsText("AssertionError")); + } + + @Test + public void noAssertErrorsOnPopulatedDetailsAndScrollDown() { + selectMenuPath(DETAILS_GENERATOR_WATCHING); + selectMenuPath(OPEN_FIRST_ITEM_DETAILS); + scrollGridVerticallyTo(500); + assertFalse(logContainsText("AssertionError")); + } + +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridBasicsTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridBasicsTest.java index 63f2c60f21..1a1bc30e81 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridBasicsTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridBasicsTest.java @@ -4,9 +4,11 @@ import java.util.List; import java.util.stream.Stream; import org.junit.Before; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; -import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.customelements.GridElement; import com.vaadin.testbench.parallel.Browser; import com.vaadin.tests.tb3.MultiBrowserTest; @@ -35,11 +37,32 @@ public abstract class GridBasicsTest extends MultiBrowserTest { testData = DataObject.generateObjects(); } - protected GridElement getGrid() { + protected GridElement getGridElement() { return $(GridElement.class).first(); } protected Stream<DataObject> getTestData() { return testData.stream(); } + + protected void scrollGridVerticallyTo(double px) { + executeScript("arguments[0].scrollTop = " + px, + getGridVerticalScrollbar()); + } + + protected void scrollGridHorizontallyTo(double px) { + executeScript("arguments[0].scrollLeft = " + px, + getGridHorizontalScrollbar()); + } + + protected WebElement getGridVerticalScrollbar() { + return getDriver().findElement(By.xpath( + "//div[contains(@class, \"v-grid-scroller-vertical\")]")); + } + + protected WebElement getGridHorizontalScrollbar() { + return getDriver().findElement(By.xpath( + "//div[contains(@class, \"v-grid-scroller-horizontal\")]")); + } + } diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridContentTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridContentTest.java index 315282439a..267567bb53 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridContentTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridContentTest.java @@ -10,8 +10,8 @@ public class GridContentTest extends GridBasicsTest { DataObject first = getTestData().findFirst().orElse(null); Assert.assertEquals("Text content should match row number", first.getRowNumber().toString(), - getGrid().getCell(0, 2).getText()); + getGridElement().getCell(0, 2).getText()); Assert.assertEquals("HTML content did not match", first.getHtmlString(), - getGrid().getCell(0, 2).getAttribute("innerHTML")); + getGridElement().getCell(0, 2).getAttribute("innerHTML")); } } diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridSortingTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridSortingTest.java index e9cd744719..83044123d2 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridSortingTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridSortingTest.java @@ -23,21 +23,21 @@ public class GridSortingTest extends GridBasicsTest { @Test public void testSortBySingleColumnByUser() { - getGrid().getHeaderCell(0, 3).click(); + getGridElement().getHeaderCell(0, 3).click(); int i = 0; for (Integer rowNumber : getTestData().sorted(BIG_RANDOM) .map(DataObject::getRowNumber).limit(5) .collect(Collectors.toList())) { Assert.assertEquals( "Grid was not sorted as expected, row number mismatch", - rowNumber.toString(), getGrid().getCell(i++, 0).getText()); + rowNumber.toString(), getGridElement().getCell(i++, 0).getText()); } } @Test public void testSortByMultipleColumnsByUser() { - getGrid().getHeaderCell(0, 4).click(); - getGrid().getHeaderCell(0, 3).click(15, 15, Keys.SHIFT); + getGridElement().getHeaderCell(0, 4).click(); + getGridElement().getHeaderCell(0, 3).click(15, 15, Keys.SHIFT); int i = 0; for (Integer rowNumber : getTestData() @@ -46,7 +46,7 @@ public class GridSortingTest extends GridBasicsTest { .collect(Collectors.toList())) { Assert.assertEquals( "Grid was not sorted as expected, row number mismatch", - rowNumber.toString(), getGrid().getCell(i++, 0).getText()); + rowNumber.toString(), getGridElement().getCell(i++, 0).getText()); } } } |