From 16a12ff27bfebed0a9c77b7d8b487d95c6531bea Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Tue, 9 Dec 2014 13:26:01 +0200 Subject: [PATCH 1/4] Add GridElement to Element APIs (#13334) Change-Id: I3bb56ba580b611969681a7de847d0730a4e479a8 --- .../testbench/elements/GridElement.java | 268 ++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java diff --git a/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java b/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java new file mode 100644 index 000000000..d582d267e --- /dev/null +++ b/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java @@ -0,0 +1,268 @@ +package com.vaadin.testbench.elements; + +import java.util.ArrayList; +import java.util.List; + +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elementsbase.AbstractElement; +import com.vaadin.testbench.elementsbase.ServerClass; + +/** + * TestBench Element API for Grid + * + * @since + * @author Vaadin Ltd + */ +@ServerClass("com.vaadin.ui.Grid") +public class GridElement extends AbstractComponentElement { + + public static class GridCellElement extends AbstractElement { + + private static final String FOCUSED_CELL_CLASS_NAME = "-cell-active"; + private static final String FOCUSED_HEADER_CLASS_NAME = "-header-active"; + private static final String FROZEN_CLASS_NAME = "frozen"; + + public boolean isFocused() { + return getAttribute("class").contains(FOCUSED_CELL_CLASS_NAME); + } + + public boolean isFocusedHeader() { + return getAttribute("class").contains(FOCUSED_HEADER_CLASS_NAME); + } + + public boolean isFrozen() { + return getAttribute("class").contains(FROZEN_CLASS_NAME); + } + } + + public static class GridRowElement extends AbstractElement { + + private static final String FOCUSED_CLASS_NAME = "-row-active"; + private static final String SELECTED_CLASS_NAME = "-row-selected"; + + public boolean isFocused() { + return getAttribute("class").contains(FOCUSED_CLASS_NAME); + } + + @Override + public boolean isSelected() { + return getAttribute("class").contains(SELECTED_CLASS_NAME); + } + } + + /** + * Scrolls Grid element so that wanted row is displayed + * + * @param index + * Target row + */ + public void scrollToRow(int index) { + try { + getSubPart("#cell[" + index + "]"); + } catch (NoSuchElementException e) { + // Expected, ignore it. + } + } + + /** + * Gets cell element with given row and column index. + * + * @param rowIndex + * Row index + * @param colIndex + * Column index + * @return Cell element with given indices. + */ + public GridCellElement getCell(int rowIndex, int colIndex) { + scrollToRow(rowIndex); + return getSubPart("#cell[" + rowIndex + "][" + colIndex + "]").wrap( + GridCellElement.class); + } + + /** + * Gets row element with given row index. + * + * @param index + * Row index + * @return Row element with given index. + */ + public GridRowElement getRow(int index) { + scrollToRow(index); + return getSubPart("#cell[" + index + "]").wrap(GridRowElement.class); + } + + /** + * Gets header cell element with given row and column index. + * + * @param rowIndex + * Row index + * @param colIndex + * Column index + * @return Header cell element with given indices. + */ + public GridCellElement getHeaderCell(int rowIndex, int colIndex) { + return getSubPart("#header[" + rowIndex + "][" + colIndex + "]").wrap( + GridCellElement.class); + } + + /** + * Gets footer cell element with given row and column index. + * + * @param rowIndex + * Row index + * @param colIndex + * Column index + * @return Footer cell element with given indices. + */ + public GridCellElement getFooterCell(int rowIndex, int colIndex) { + return getSubPart("#footer[" + rowIndex + "][" + colIndex + "]").wrap( + GridCellElement.class); + } + + /** + * Gets list of header cell elements on given row. + * + * @param rowIndex + * Row index + * @return Header cell elements on given row. + */ + public List getHeaderCells(int rowIndex) { + List headers = new ArrayList(); + for (TestBenchElement e : TestBenchElement.wrapElements( + getSubPart("#header[" + rowIndex + "]").findElements( + By.xpath("./th")), getCommandExecutor())) { + headers.add(e.wrap(GridCellElement.class)); + } + return headers; + } + + /** + * Gets list of header cell elements on given row. + * + * @param rowIndex + * Row index + * @return Header cell elements on given row. + */ + public List getFooterCells(int rowIndex) { + List footers = new ArrayList(); + for (TestBenchElement e : TestBenchElement.wrapElements( + getSubPart("#footer[" + rowIndex + "]").findElements( + By.xpath("./td")), getCommandExecutor())) { + footers.add(e.wrap(GridCellElement.class)); + } + return footers; + } + + /** + * Get header row count + * + * @return Header row count + */ + public int getHeaderCount() { + return getSubPart("#header").findElements(By.xpath("./tr")).size(); + } + + /** + * Get footer row count + * + * @return Footer row count + */ + public int getFooterCount() { + return getSubPart("#footer").findElements(By.xpath("./tr")).size(); + } + + /** + * Get a header row by index + * + * @param rowIndex + * Row index + * @return The th element of the row + */ + public WebElement getHeaderRow(int rowIndex) { + return getSubPart("#header[" + rowIndex + "]"); + } + + /** + * Get a footer row by index + * + * @param rowIndex + * Row index + * @return The tr element of the row + */ + public WebElement getFooterRow(int rowIndex) { + return getSubPart("#footer[" + rowIndex + "]"); + } + + /** + * Get the vertical scroll element + * + * @return The element representing the vertical scrollbar + */ + public WebElement getVerticalScroller() { + List rootElements = findElements(By.xpath("./div")); + return rootElements.get(0); + } + + /** + * Get the horizontal scroll element + * + * @return The element representing the horizontal scrollbar + */ + public WebElement getHorizontalScroller() { + List rootElements = findElements(By.xpath("./div")); + return rootElements.get(1); + } + + /** + * Get the header element + * + * @return The thead element + */ + public WebElement getHeader() { + return getSubPart("#header"); + } + + /** + * Get the body element + * + * @return the tbody element + */ + public WebElement getBody() { + return getSubPart("#cell"); + } + + /** + * Get the footer element + * + * @return the tfoot element + */ + public WebElement getFooter() { + return getSubPart("#footer"); + } + + /** + * Get the element wrapping the table element + * + * @return The element that wraps the table element + */ + public WebElement getTableWrapper() { + List rootElements = findElements(By.xpath("./div")); + return rootElements.get(2); + } + + /** + * Helper function to get Grid subparts wrapped correctly + * + * @param subPartSelector + * SubPart to be used in ComponentLocator + * @return SubPart element wrapped in TestBenchElement class + */ + private TestBenchElement getSubPart(String subPartSelector) { + return (TestBenchElement) findElement(By.vaadin(subPartSelector)); + } + +} From 9cc2c9f9da61e1788e7a086bdce229c5a0293a0b Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Fri, 19 Dec 2014 10:19:08 +0200 Subject: [PATCH 2/4] Update GridElement to reflect the current Grid implementation (#13334) Change-Id: If3ac4cf811bd381b7598535b00d5433415d2f5d9 --- .../testbench/elements/GridElement.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java b/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java index d582d267e..8c72aff11 100644 --- a/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java +++ b/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java @@ -1,3 +1,15 @@ +/** + * Copyright (C) 2012 Vaadin Ltd + * + * This program is available under Commercial Vaadin Add-On License 3.0 + * (CVALv3). + * + * See the file licensing.txt distributed with this software for more + * information about licensing. + * + * You should have received a copy of the license along with this program. + * If not, see . + */ package com.vaadin.testbench.elements; import java.util.ArrayList; @@ -22,18 +34,13 @@ public class GridElement extends AbstractComponentElement { public static class GridCellElement extends AbstractElement { - private static final String FOCUSED_CELL_CLASS_NAME = "-cell-active"; - private static final String FOCUSED_HEADER_CLASS_NAME = "-header-active"; + private static final String FOCUSED_CELL_CLASS_NAME = "-cell-focused"; private static final String FROZEN_CLASS_NAME = "frozen"; public boolean isFocused() { return getAttribute("class").contains(FOCUSED_CELL_CLASS_NAME); } - public boolean isFocusedHeader() { - return getAttribute("class").contains(FOCUSED_HEADER_CLASS_NAME); - } - public boolean isFrozen() { return getAttribute("class").contains(FROZEN_CLASS_NAME); } @@ -41,7 +48,7 @@ public boolean isFrozen() { public static class GridRowElement extends AbstractElement { - private static final String FOCUSED_CLASS_NAME = "-row-active"; + private static final String FOCUSED_CLASS_NAME = "-row-focused"; private static final String SELECTED_CLASS_NAME = "-row-selected"; public boolean isFocused() { From c52dad275e0c71f7dea59b02dd2339c4d86cccc0 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Mon, 26 Jan 2015 12:53:55 +0200 Subject: [PATCH 3/4] Add Editor support to GridElement Change-Id: I91d07c0ea618baacea3b2ac8923cfc7b83f95c44 --- .../testbench/elements/GridElement.java | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java b/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java index 8c72aff11..1e1266cc4 100644 --- a/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java +++ b/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java @@ -61,6 +61,51 @@ public boolean isSelected() { } } + public static class GridEditorElement extends AbstractElement { + + private GridElement grid; + + private GridEditorElement setGrid(GridElement grid) { + this.grid = grid; + return this; + } + + /** + * Gets the editor field for column in given index. + * + * @param colIndex + * column index + * @return the editor field for given location + */ + public TestBenchElement getField(int colIndex) { + return grid.getSubPart("#editor[" + colIndex + "]"); + } + + /** + * Saves the fields of this editor. + *

+ * Note: that this closes the editor making this element + * useless. + */ + public void save() { + getField(0); + List buttons = findElements(By.xpath("./button")); + buttons.get(0).click(); + } + + /** + * Cancels this editor. + *

+ * Note: that this closes the editor making this element + * useless. + */ + public void cancel() { + getField(0); + List buttons = findElements(By.xpath("./button")); + buttons.get(1).click(); + } + } + /** * Scrolls Grid element so that wanted row is displayed * @@ -261,6 +306,11 @@ public WebElement getTableWrapper() { return rootElements.get(2); } + public GridEditorElement getEditor() { + return getSubPart("#editor").wrap(GridEditorElement.class) + .setGrid(this); + } + /** * Helper function to get Grid subparts wrapped correctly * @@ -271,5 +321,4 @@ public WebElement getTableWrapper() { private TestBenchElement getSubPart(String subPartSelector) { return (TestBenchElement) findElement(By.vaadin(subPartSelector)); } - } From bfe943a133e2a10f458ce8c922b96ab61275a461 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Mon, 9 Feb 2015 15:35:46 +0200 Subject: [PATCH 4/4] Fix GridElement to always return TestBenchElements (#16600) Also contains an updated version of GridEditorElement with support for non-editable columns and editor error messages. Change-Id: I9d1e8dda3b17ce855bedaffe8d587939f8fbd619 --- .../testbench/elements/GridElement.java | 76 ++++++++++++++----- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java b/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java index 1e1266cc4..f636e3655 100644 --- a/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java +++ b/vaadin-testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java @@ -74,13 +74,41 @@ private GridEditorElement setGrid(GridElement grid) { * Gets the editor field for column in given index. * * @param colIndex - * column index + * the column index * @return the editor field for given location + * + * @throws NoSuchElementException + * if {@code isEditable(colIndex) == false} */ public TestBenchElement getField(int colIndex) { return grid.getSubPart("#editor[" + colIndex + "]"); } + /** + * Gets whether the column with the given index is editable, that is, + * has an associated editor field. + * + * @param colIndex + * the column index + * @return {@code true} if the column has an editor field, {@code false} + *  otherwise + */ + public boolean isEditable(int colIndex) { + return grid + .isElementPresent(By.vaadin("#editor[" + colIndex + "]")); + } + + /** + * Checks whether a field is marked with an error. + * + * @param colIndex + * column index + * @return true iff the field is marked with an error + */ + public boolean isFieldErrorMarked(int colIndex) { + return getField(colIndex).getAttribute("class").contains("error"); + } + /** * Saves the fields of this editor. *

@@ -88,9 +116,7 @@ public TestBenchElement getField(int colIndex) { * useless. */ public void save() { - getField(0); - List buttons = findElements(By.xpath("./button")); - buttons.get(0).click(); + findElement(By.className("v-grid-editor-save")).click(); } /** @@ -100,9 +126,23 @@ public void save() { * useless. */ public void cancel() { - getField(0); - List buttons = findElements(By.xpath("./button")); - buttons.get(1).click(); + findElement(By.className("v-grid-editor-cancel")).click(); + } + + /** + * Gets the error message text, or null if no message is + * present. + */ + public String getErrorMessage() { + WebElement messageWrapper = findElement(By + .className("v-grid-editor-message")); + List divs = messageWrapper.findElements(By + .tagName("div")); + if (divs.isEmpty()) { + return null; + } else { + return divs.get(0).getText(); + } } } @@ -234,7 +274,7 @@ public int getFooterCount() { * Row index * @return The th element of the row */ - public WebElement getHeaderRow(int rowIndex) { + public TestBenchElement getHeaderRow(int rowIndex) { return getSubPart("#header[" + rowIndex + "]"); } @@ -245,7 +285,7 @@ public WebElement getHeaderRow(int rowIndex) { * Row index * @return The tr element of the row */ - public WebElement getFooterRow(int rowIndex) { + public TestBenchElement getFooterRow(int rowIndex) { return getSubPart("#footer[" + rowIndex + "]"); } @@ -254,9 +294,9 @@ public WebElement getFooterRow(int rowIndex) { * * @return The element representing the vertical scrollbar */ - public WebElement getVerticalScroller() { + public TestBenchElement getVerticalScroller() { List rootElements = findElements(By.xpath("./div")); - return rootElements.get(0); + return (TestBenchElement) rootElements.get(0); } /** @@ -264,9 +304,9 @@ public WebElement getVerticalScroller() { * * @return The element representing the horizontal scrollbar */ - public WebElement getHorizontalScroller() { + public TestBenchElement getHorizontalScroller() { List rootElements = findElements(By.xpath("./div")); - return rootElements.get(1); + return (TestBenchElement) rootElements.get(1); } /** @@ -274,7 +314,7 @@ public WebElement getHorizontalScroller() { * * @return The thead element */ - public WebElement getHeader() { + public TestBenchElement getHeader() { return getSubPart("#header"); } @@ -283,7 +323,7 @@ public WebElement getHeader() { * * @return the tbody element */ - public WebElement getBody() { + public TestBenchElement getBody() { return getSubPart("#cell"); } @@ -292,7 +332,7 @@ public WebElement getBody() { * * @return the tfoot element */ - public WebElement getFooter() { + public TestBenchElement getFooter() { return getSubPart("#footer"); } @@ -301,9 +341,9 @@ public WebElement getFooter() { * * @return The element that wraps the table element */ - public WebElement getTableWrapper() { + public TestBenchElement getTableWrapper() { List rootElements = findElements(By.xpath("./div")); - return rootElements.get(2); + return (TestBenchElement) rootElements.get(2); } public GridEditorElement getEditor() {