summaryrefslogtreecommitdiffstats
path: root/uitest
diff options
context:
space:
mode:
authorcaalador <mikael.grankvist@gmail.com>2017-02-02 14:01:19 +0200
committerPekka Hyvönen <pekka@vaadin.com>2017-02-02 14:01:19 +0200
commit59157179b6e5099952f827485e16b67a88831ebf (patch)
treebef348f7ffb73103e25f69368a8294e48d16ae19 /uitest
parentbe2c4684cd43547c2785831a8b0aeda63ccbaebe (diff)
downloadvaadin-framework-59157179b6e5099952f827485e16b67a88831ebf.tar.gz
vaadin-framework-59157179b6e5099952f827485e16b67a88831ebf.zip
Add scrollTo methods to Grid (#8203) (#8410)
* Add scroll methods to serverside grid (#8203) Added scrollToTop(), scrollToEnd() and scrollTo(int row) * Fix scrolling to view of opened details (#8203) Removed dependency for DetailsManagerConnector from GridConnector. GridConnector now handles one off listeners. * Rename detailsRefresh to better show that it's one-off. Add missing copyright header.
Diffstat (limited to 'uitest')
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/grid/GridDetailsLocation.java73
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/grid/GridFastAsyncUpdate.java169
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/grid/GridScrollTo.java67
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/grid/GridDetailsLocationTest.java303
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/grid/GridScrollToTest.java151
5 files changed, 763 insertions, 0 deletions
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridDetailsLocation.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDetailsLocation.java
new file mode 100644
index 0000000000..74e8f44b1f
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDetailsLocation.java
@@ -0,0 +1,73 @@
+package com.vaadin.tests.components.grid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.util.Person;
+import com.vaadin.tests.util.PersonContainer;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+
+public class GridDetailsLocation extends AbstractTestUI {
+
+ private TextField numberTextField;
+ private Grid<Person> grid;
+ private List<Person> testData;
+
+ @Override
+ protected void setup(VaadinRequest request) {
+
+ grid = new Grid<>();
+ testData = new ArrayList<>(PersonContainer.createTestData(1000));
+ grid.setItems(testData);
+ grid.addColumn(item -> item.getFirstName()).setCaption("First Name");
+ grid.addColumn(item -> item.getLastName()).setCaption("Last Name");
+
+ grid.setSelectionMode(Grid.SelectionMode.NONE);
+ addComponent(grid);
+
+ final CheckBox checkbox = new CheckBox("Details generator");
+ checkbox.addValueChangeListener(event -> {
+ if (checkbox.getValue()) {
+ grid.setDetailsGenerator(person -> {
+ Label label = new Label(
+ person.getFirstName() + " " + person.getLastName());
+ // currently the decorator row doesn't change its height
+ // when the content height is different.
+ label.setHeight("30px");
+ return label;
+ });
+ } else {
+ grid.setDetailsGenerator(null);
+ }
+ });
+ addComponent(checkbox);
+
+ numberTextField = new TextField("Row");
+ addComponent(numberTextField);
+
+ addComponent(new Button("Toggle and scroll", clickEvent -> {
+ toggle();
+ scrollTo();
+ }));
+ addComponent(new Button("Scroll and toggle", clickEvent -> {
+ scrollTo();
+ toggle();
+ }));
+ }
+
+ private void toggle() {
+ Person itemId = testData.get(Integer.parseInt(numberTextField.getValue()));
+ boolean isVisible = grid.isDetailsVisible(itemId);
+ grid.setDetailsVisible(itemId, !isVisible);
+ }
+
+ private void scrollTo() {
+ grid.scrollTo(Integer.parseInt(numberTextField.getValue()));
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridFastAsyncUpdate.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridFastAsyncUpdate.java
new file mode 100644
index 0000000000..3f4391d504
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridFastAsyncUpdate.java
@@ -0,0 +1,169 @@
+package com.vaadin.tests.components.grid;
+
+import java.util.Calendar;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.logging.Level;
+
+import com.vaadin.annotations.Push;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.VerticalLayout;
+
+@Push
+public class GridFastAsyncUpdate extends AbstractTestUI {
+
+ private final Runnable addRowsTask = new Runnable() {
+ @Override
+ public void run() {
+ System.out.println("Logging...");
+ try {
+ Random random = new Random();
+ while (!Thread.currentThread().isInterrupted()) {
+ Thread.sleep(random.nextInt(100));
+
+ GridFastAsyncUpdate.this.access(() -> {
+ ++counter;
+ Item item = new Item(counter,
+ (Calendar.getInstance().getTimeInMillis()
+ - loggingStart),
+ Level.INFO.toString(), "Message");
+ items.add(item);
+ grid.setItems(items);
+
+ if (grid != null && !scrollLock) {
+ grid.scrollToEnd();
+ }
+ });
+ }
+ } catch (InterruptedException e) {
+ System.out.println("logging thread interrupted");
+ }
+ }
+ };
+
+ private int counter;
+ private List<Item> items = new LinkedList<>();
+
+ private Grid<Item> grid;
+ private long loggingStart;
+ private volatile boolean scrollLock = false;
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final VerticalLayout layout = new VerticalLayout();
+ layout.setSizeFull();
+ layout.setMargin(true);
+ addComponent(layout);
+
+ HorizontalLayout buttons = new HorizontalLayout();
+ layout.addComponent(buttons);
+
+ final ExecutorService logExecutor = Executors.newSingleThreadExecutor();
+
+ final Button logButton = new Button("Start logging");
+ logButton.addClickListener(clickEvent -> {
+ if ("Start logging".equals(logButton.getCaption())) {
+ loggingStart = Calendar.getInstance().getTimeInMillis();
+ logExecutor.submit(addRowsTask);
+ logButton.setCaption("Stop logging");
+ } else {
+ System.out.println("Stop logging...");
+ try {
+ logExecutor.shutdownNow();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ logButton.setCaption("Start logging");
+ }
+ });
+ buttons.addComponent(logButton);
+
+ final Button scrollButton = new Button("Stop scrolling");
+ scrollButton.addClickListener(clickEvent -> {
+ if (!scrollLock) {
+ System.out.println("Stop scrolling");
+ scrollButton.setCaption("Start scrolling");
+ scrollLock = true;
+ } else {
+ System.out.println("Start scrolling");
+ scrollButton.setCaption("Stop scrolling");
+ scrollLock = false;
+ }
+ });
+ buttons.addComponent(scrollButton);
+
+ grid = new Grid<>();
+ grid.addColumn(Item::getSequenceNumber).setCaption("");
+ grid.addColumn(Item::getMillis).setCaption("");
+ grid.addColumn(Item::getLevel).setCaption("");
+ grid.addColumn(Item::getMessage).setCaption("");
+
+ grid.setWidth("100%");
+ grid.setSelectionMode(Grid.SelectionMode.SINGLE);
+ grid.addSelectionListener(selectionEvent -> {
+ if (!selectionEvent.getAllSelectedItems().isEmpty()) {
+ disableScroll();
+ }
+ });
+
+ layout.addComponent(grid);
+ layout.setExpandRatio(grid, 1.0f);
+ }
+
+ protected void disableScroll() {
+ scrollLock = true;
+ }
+
+ protected class Item {
+ Integer sequenceNumber;
+ Long millis;
+ String level, message;
+
+ public Item(Integer sequanceNumber, Long millis, String level,
+ String message) {
+ this.sequenceNumber = sequanceNumber;
+ this.millis = millis;
+ this.level = level;
+ this.message = message;
+ }
+
+ public Integer getSequenceNumber() {
+ return sequenceNumber;
+ }
+
+ public void setSequenceNumber(Integer sequenceNumber) {
+ this.sequenceNumber = sequenceNumber;
+ }
+
+ public Long getMillis() {
+ return millis;
+ }
+
+ public void setMillis(Long millis) {
+ this.millis = millis;
+ }
+
+ public String getLevel() {
+ return level;
+ }
+
+ public void setLevel(String level) {
+ this.level = level;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridScrollTo.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridScrollTo.java
new file mode 100644
index 0000000000..9f83436a11
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridScrollTo.java
@@ -0,0 +1,67 @@
+package com.vaadin.tests.components.grid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.data.ValueProvider;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+
+public class GridScrollTo extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ List<String> data = new ArrayList<>();
+ for (int i = 0; i < 200; i++) {
+ data.add("Name " + i);
+ }
+
+ Grid<String> grid = new Grid<>();
+ grid.setItems(data);
+
+ grid.setSelectionMode(Grid.SelectionMode.NONE);
+
+ grid.addColumn(ValueProvider.identity()).setId("Name")
+ .setCaption("Name");
+
+ grid.setDetailsGenerator(item -> {
+ final HorizontalLayout detailsLayout = new HorizontalLayout();
+ detailsLayout.setWidth(100, Unit.PERCENTAGE);
+ detailsLayout.setHeightUndefined();
+
+ final Label lbl1 = new Label(item + " details");
+ detailsLayout.addComponent(lbl1);
+ return detailsLayout;
+ });
+
+ grid.addItemClickListener(event -> {
+ final String itemId = event.getItem();
+ grid.setDetailsVisible(itemId, !grid.isDetailsVisible(itemId));
+ });
+
+ Button scrollToTop = new Button("Scroll to top",
+ clickEvent -> grid.scrollToStart());
+ scrollToTop.setId("top");
+
+ Button scrollToEnd = new Button("Scroll to end",
+ clickEvent -> grid.scrollToEnd());
+ scrollToEnd.setId("end");
+
+ TextField rowField = new TextField("Target row");
+ rowField.setId("row-field");
+
+ Button scrollToRow = new Button("Scroll to row", clickEvent -> grid
+ .scrollTo(Integer.parseInt(rowField.getValue())));
+ scrollToRow.setId("row");
+
+ addComponent(grid);
+
+ addComponent(new HorizontalLayout(scrollToTop, scrollToEnd, rowField,
+ scrollToRow));
+ }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridDetailsLocationTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridDetailsLocationTest.java
new file mode 100644
index 0000000000..e54fe8b0d3
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/grid/GridDetailsLocationTest.java
@@ -0,0 +1,303 @@
+package com.vaadin.tests.components.grid;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.StaleElementReferenceException;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.CheckBoxElement;
+import com.vaadin.testbench.elements.GridElement;
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.testbench.parallel.TestCategory;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+@TestCategory("grid")
+public class GridDetailsLocationTest extends MultiBrowserTest {
+
+ private static final int detailsDefaultHeight = 51;
+ private static final int detailsDefinedHeight = 33;
+
+ private static class Param {
+ private final int rowIndex;
+ private final boolean useGenerator;
+ private final boolean scrollFirstToBottom;
+
+ public Param(int rowIndex, boolean useGenerator,
+ boolean scrollFirstToBottom) {
+ this.rowIndex = rowIndex;
+ this.useGenerator = useGenerator;
+ this.scrollFirstToBottom = scrollFirstToBottom;
+ }
+
+ public int getRowIndex() {
+ return rowIndex;
+ }
+
+ public boolean useGenerator() {
+ return useGenerator;
+ }
+
+ public boolean scrollFirstToBottom() {
+ return scrollFirstToBottom;
+ }
+
+ @Override
+ public String toString() {
+ return "Param [rowIndex=" + getRowIndex() + ", useGenerator="
+ + useGenerator() + ", scrollFirstToBottom="
+ + scrollFirstToBottom() + "]";
+ }
+
+ }
+
+ public static Collection<Param> parameters() {
+ List<Param> data = new ArrayList<>();
+
+ int[] params = new int[] { 0, 500, 999 };
+
+ for (int rowIndex : params) {
+
+ data.add(new Param(rowIndex, true, false));
+ data.add(new Param(rowIndex, true, true));
+ }
+
+ return data;
+ }
+
+ @Before
+ public void setUp() {
+ setDebug(true);
+ }
+
+ @Test
+ public void toggleAndScroll() throws Throwable {
+ for (Param param : parameters()) {
+ try {
+ openTestURL();
+ useGenerator(param.useGenerator());
+ scrollToBottom(param.scrollFirstToBottom());
+
+ // the tested method
+ toggleAndScroll(param.getRowIndex());
+
+ verifyLocation(param);
+ } catch (Throwable t) {
+ throw new Throwable("" + param, t);
+ }
+ }
+ }
+
+ @Test
+ public void scrollAndToggle() throws Throwable {
+ for (Param param : parameters()) {
+ try {
+ openTestURL();
+ useGenerator(param.useGenerator());
+ scrollToBottom(param.scrollFirstToBottom());
+
+ // the tested method
+ scrollAndToggle(param.getRowIndex());
+
+ verifyLocation(param);
+
+ } catch (Throwable t) {
+ throw new Throwable("" + param, t);
+ }
+ }
+ }
+
+ @Test
+ public void testDetailsHeightWithGenerator() {
+ openTestURL();
+ useGenerator(true);
+ toggleAndScroll(5);
+
+ verifyDetailsRowHeight(5, detailsDefinedHeight, 0);
+ verifyDetailsDecoratorLocation(5, 0, 0);
+
+ toggleAndScroll(0);
+
+ verifyDetailsRowHeight(0, detailsDefinedHeight, 0);
+ // decorator elements are in DOM in the order they have been added
+ verifyDetailsDecoratorLocation(0, 0, 1);
+
+ verifyDetailsRowHeight(5, detailsDefinedHeight, 1);
+ verifyDetailsDecoratorLocation(5, 1, 0);
+ }
+
+ private void verifyDetailsRowHeight(int rowIndex, int expectedHeight,
+ int visibleIndexOfSpacer) {
+ waitForDetailsVisible();
+ WebElement details = getDetailsElement(visibleIndexOfSpacer);
+ Assert.assertEquals("Wrong details row height", expectedHeight,
+ details.getSize().getHeight());
+ }
+
+ private void verifyDetailsDecoratorLocation(int row,
+ int visibleIndexOfSpacer, int visibleIndexOfDeco) {
+ WebElement detailsElement = getDetailsElement(visibleIndexOfSpacer);
+ WebElement detailsDecoElement = getDetailsDecoElement(
+ visibleIndexOfDeco);
+ GridElement.GridRowElement rowElement = getGrid().getRow(row);
+
+ Assert.assertEquals(
+ "Details deco top position does not match row top pos",
+ rowElement.getLocation().getY(),
+ detailsDecoElement.getLocation().getY());
+ Assert.assertEquals(
+ "Details deco bottom position does not match details bottom pos",
+ detailsElement.getLocation().getY()
+ + detailsElement.getSize().getHeight(),
+ detailsDecoElement.getLocation().getY()
+ + detailsDecoElement.getSize().getHeight());
+ }
+
+ private void verifyLocation(Param param) {
+ Assert.assertFalse("Notification was present",
+ isElementPresent(By.className("v-Notification")));
+
+ TestBenchElement headerRow = getGrid().getHeaderRow(0);
+ final int topBoundary = headerRow.getLocation().getX()
+ + headerRow.getSize().height;
+ final int bottomBoundary = getGrid().getLocation().getX()
+ + getGrid().getSize().getHeight()
+ - getHorizontalScrollbar().getSize().height;
+
+ GridElement.GridRowElement row = getGrid().getRow(param.getRowIndex());
+ final int rowTop = row.getLocation().getX();
+
+ waitForDetailsVisible();
+ WebElement details = getDetailsElement();
+ final int detailsBottom = details.getLocation().getX()
+ + details.getSize().getHeight();
+
+ assertGreaterOrEqual("Row top should be inside grid, gridTop:"
+ + topBoundary + " rowTop" + rowTop, topBoundary, rowTop);
+ assertLessThanOrEqual(
+ "Decorator bottom should be inside grid, gridBottom:"
+ + bottomBoundary + " decoratorBotton:" + detailsBottom,
+ detailsBottom, bottomBoundary);
+
+ verifyDetailsRowHeight(param.getRowIndex(), param.useGenerator()
+ ? detailsDefinedHeight : detailsDefaultHeight, 0);
+ verifyDetailsDecoratorLocation(param.getRowIndex(), 0, 0);
+
+ Assert.assertFalse("Notification was present",
+ isElementPresent(By.className("v-Notification")));
+ }
+
+ private final By locator = By.className("v-grid-spacer");
+
+ private WebElement getDetailsElement() {
+ return getDetailsElement(0);
+ }
+
+ private WebElement getDetailsElement(int index) {
+ return findElements(locator).get(index);
+ }
+
+ private WebElement getDetailsDecoElement(int index) {
+ return findElements(By.className("v-grid-spacer-deco")).get(index);
+ }
+
+ private void waitForDetailsVisible() {
+ waitUntil(new ExpectedCondition<WebElement>() {
+
+ @Override
+ public WebElement apply(WebDriver driver) {
+ try {
+ WebElement detailsElement = getDetailsElement();
+ return detailsElement.isDisplayed()
+ && detailsElement.getSize().getHeight() > 3
+ ? detailsElement : null;
+ } catch (StaleElementReferenceException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "visibility of element located by " + locator;
+ }
+
+ }, 5);
+ waitForElementVisible(By.className("v-grid-spacer"));
+ }
+
+ private void scrollToBottom(boolean scrollFirstToBottom) {
+ if (scrollFirstToBottom) {
+ executeScript("arguments[0].scrollTop = 9999999",
+ getVerticalScrollbar());
+ }
+ }
+
+ private void useGenerator(boolean use) {
+ CheckBoxElement checkBox = $(CheckBoxElement.class).first();
+ boolean isChecked = isCheckedValo(checkBox);
+ if (use != isChecked) {
+ clickValo(checkBox);
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ private boolean isCheckedValo(CheckBoxElement checkBoxElement) {
+ WebElement checkbox = checkBoxElement.findElement(By.tagName("input"));
+ Object value = executeScript("return arguments[0].checked;", checkbox);
+ return (Boolean) value;
+ }
+
+ private void clickValo(CheckBoxElement checkBoxElement) {
+ checkBoxElement.click(5, 5);
+ }
+
+ private void scrollAndToggle(int row) {
+ setRow(row);
+ getScrollAndToggle().click();
+ }
+
+ private void toggleAndScroll(int row) {
+ setRow(row);
+ getToggleAndScroll().click();
+ }
+
+ private ButtonElement getScrollAndToggle() {
+ return $(ButtonElement.class).caption("Scroll and toggle").first();
+ }
+
+ private ButtonElement getToggleAndScroll() {
+ return $(ButtonElement.class).caption("Toggle and scroll").first();
+ }
+
+ private void setRow(int row) {
+ $(TextFieldElement.class).first().clear();
+ $(TextFieldElement.class).first().sendKeys(String.valueOf(row),
+ Keys.ENTER, Keys.TAB);
+ }
+
+ private GridElement getGrid() {
+ return $(GridElement.class).first();
+ }
+
+ private WebElement getVerticalScrollbar() {
+ WebElement scrollBar = getGrid()
+ .findElement(By.className("v-grid-scroller-vertical"));
+ return scrollBar;
+ }
+
+ private WebElement getHorizontalScrollbar() {
+ WebElement scrollBar = getGrid()
+ .findElement(By.className("v-grid-scroller-horizontal"));
+ return scrollBar;
+ }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridScrollToTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridScrollToTest.java
new file mode 100644
index 0000000000..8bdb246d81
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/grid/GridScrollToTest.java
@@ -0,0 +1,151 @@
+package com.vaadin.tests.components.grid;
+
+import java.util.Optional;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.GridElement;
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.testbench.parallel.TestCategory;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+import com.vaadin.ui.Button;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+@TestCategory("grid")
+public class GridScrollToTest extends SingleBrowserTest {
+
+ @Test
+ public void testScrollToEnd() {
+ openTestURL();
+ String finalCellText = "199";
+
+ assertEquals("Found final element even though should be at top of list",
+ 0, cellsContaining(finalCellText));
+
+ $(ButtonElement.class).id("end").click();
+
+ assertEquals("Could not find final element", 1,
+ cellsContaining(finalCellText));
+ }
+
+ @Test
+ public void testScrollToRow() {
+ openTestURL();
+ String row = "50";
+
+ assertEquals("Found row element even though should be at top of list",
+ 0, cellsContaining(row));
+
+ $(TextFieldElement.class).id("row-field").setValue(row);
+
+ $(ButtonElement.class).id("row").click();
+
+ assertEquals("Could not find row element", 1, cellsContaining(row));
+ }
+
+ @Test
+ public void testScrollTop() {
+ openTestURL();
+ String row = "Name 0";
+
+ assertEquals("Couldn't find first element", 1, cellsContaining(row));
+
+ getGrid().getVerticalScroller().scroll(800);
+
+ assertEquals(
+ "Found first element even though we should have scrolled down",
+ 0, cellsContaining(row));
+
+ $(ButtonElement.class).id("top").click();
+
+ assertEquals("Couldn't find first element", 1, cellsContaining(row));
+ }
+
+ @Test
+ public void scrollToLastWithDetailsShowDetails() {
+ openTestURL();
+
+ // Scroll to end
+ $(ButtonElement.class).id("end").click();
+
+ // Open details
+ clickCellContaining("199");
+
+ waitForElementPresent(By.className("v-grid-spacer"));
+ waitForElementPresent(By.className("v-label"));
+ assertTrue("Details not visible", getGrid().findElements(By.className("v-label")).stream()
+ .filter(element -> element.getText().contains("Name 199 details")).findFirst().get().isDisplayed());
+ // scroll away
+ $(ButtonElement.class).id("top").click();
+
+ assertEquals("Found final element even though should be at top of list",
+ 0, cellsContaining("199"));
+
+ assertFalse("Found final element details even though should be at top of list", getGrid().findElements(By.className("v-label")).stream()
+ .filter(element -> element.getText().contains("Name 199 details")).findFirst().isPresent());
+
+ // Scroll to end
+ $(ButtonElement.class).id("end").click();
+
+ assertTrue("Details not visible", getGrid().findElements(By.className("v-label")).stream()
+ .filter(element -> element.getText().contains("Name 199 details")).findFirst().get().isDisplayed());
+ }
+
+ @Test
+ public void scrollToRowShowsDetails() {
+ openTestURL();
+
+ // Scroll to 50
+ $(TextFieldElement.class).id("row-field").setValue("50");
+
+ $(ButtonElement.class).id("row").click();
+
+ clickCellContaining("50");
+
+ waitForElementPresent(By.className("v-grid-spacer"));
+ waitForElementPresent(By.className("v-label"));
+ assertTrue("Details not visible", getGrid().findElements(By.className("v-label")).stream()
+ .filter(element -> element.getText().contains("Name 50 details")).findFirst().get().isDisplayed());
+ // scroll away
+ $(ButtonElement.class).id("top").click();
+
+ assertEquals("Found final element even though should be at top of list",
+ 0, cellsContaining("50"));
+
+ assertFalse("Found final element details even though should be at top of list", getGrid().findElements(By.className("v-label")).stream()
+ .filter(element -> element.getText().contains("Name 50 details")).findFirst().isPresent());
+
+ // Scroll to end
+ $(ButtonElement.class).id("row").click();
+
+ assertTrue("Details not visible", getGrid().findElements(By.className("v-label")).stream()
+ .filter(element -> element.getText().contains("Name 50 details")).findFirst().get().isDisplayed());
+ }
+
+ private GridElement getGrid() {
+ return $(GridElement.class).first();
+ }
+
+ private long cellsContaining(String text) {
+ return getGrid().findElements(By.className("v-grid-cell")).stream()
+ .filter(element -> element.getText().contains(text)).count();
+ }
+
+ private void clickCellContaining(String text) {
+ Optional<WebElement> first = getGrid()
+ .findElements(By.className("v-grid-cell")).stream()
+ .filter(element -> element.getText().contains(text))
+ .findFirst();
+ if (first.isPresent())
+ first.get().click();
+ else
+ Assert.fail("Cell not present");
+ }
+}