You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GridComponentsTest.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. package com.vaadin.tests.components.grid;
  2. import java.util.Locale;
  3. import java.util.stream.IntStream;
  4. import java.util.stream.Stream;
  5. import org.junit.Assume;
  6. import org.junit.Test;
  7. import org.openqa.selenium.Keys;
  8. import org.openqa.selenium.WebElement;
  9. import org.openqa.selenium.interactions.Actions;
  10. import com.vaadin.testbench.By;
  11. import com.vaadin.testbench.elements.ButtonElement;
  12. import com.vaadin.testbench.elements.GridElement;
  13. import com.vaadin.testbench.elements.GridElement.GridCellElement;
  14. import com.vaadin.testbench.elements.GridElement.GridRowElement;
  15. import com.vaadin.testbench.elements.LabelElement;
  16. import com.vaadin.testbench.elements.NotificationElement;
  17. import com.vaadin.testbench.elements.TextFieldElement;
  18. import com.vaadin.testbench.parallel.BrowserUtil;
  19. import com.vaadin.tests.tb3.MultiBrowserTest;
  20. import static org.junit.Assert.assertEquals;
  21. import static org.junit.Assert.assertFalse;
  22. import static org.junit.Assert.assertTrue;
  23. public class GridComponentsTest extends MultiBrowserTest {
  24. @Test
  25. public void testReuseTextFieldOnScroll() {
  26. openTestURL();
  27. GridElement grid = $(GridElement.class).first();
  28. editTextFieldInCell(grid, 0, 1);
  29. // Scroll out of view port
  30. grid.getRow(900);
  31. // Scroll back
  32. grid.getRow(0);
  33. WebElement textField = grid.getCell(0, 1)
  34. .findElement(By.tagName("input"));
  35. assertEquals("TextField value was reset", "Foo",
  36. textField.getAttribute("value"));
  37. assertTrue("No mention in the log",
  38. logContainsText("1. Reusing old text field for: Row 0"));
  39. }
  40. @Test
  41. public void testReuseTextFieldOnSelect() {
  42. openTestURL();
  43. GridElement grid = $(GridElement.class).first();
  44. editTextFieldInCell(grid, 1, 1);
  45. // Select row
  46. grid.getCell(1, 0).click();
  47. WebElement textField = grid.getCell(1, 1)
  48. .findElement(By.tagName("input"));
  49. assertEquals("TextField value was reset", "Foo",
  50. textField.getAttribute("value"));
  51. assertTrue("No mention in the log",
  52. logContainsText("1. Reusing old text field for: Row 1"));
  53. }
  54. @Test
  55. public void testReplaceData() {
  56. openTestURL();
  57. assertRowExists(5, "Row 5");
  58. $(ButtonElement.class).caption("Reset data").first().click();
  59. assertRowExists(5, "Row 1005");
  60. }
  61. @Test
  62. public void testTextFieldSize() {
  63. openTestURL();
  64. GridCellElement cell = $(GridElement.class).first().getCell(0, 1);
  65. int cellWidth = cell.getSize().getWidth();
  66. int fieldWidth = cell.findElement(By.tagName("input")).getSize()
  67. .getWidth();
  68. // padding left and right, +1 to fix sub pixel issues
  69. int padding = 18 * 2 + 1;
  70. int extraSpace = Math.abs(fieldWidth - cellWidth);
  71. assertTrue("Too much unused space in cell. Expected: " + padding
  72. + " Actual: " + extraSpace, extraSpace <= padding);
  73. }
  74. private void editTextFieldInCell(GridElement grid, int row, int col) {
  75. WebElement textField = grid.getCell(row, col)
  76. .findElement(By.tagName("input"));
  77. textField.clear();
  78. textField.sendKeys("Foo");
  79. }
  80. @Test
  81. public void testRow5() {
  82. openTestURL();
  83. assertRowExists(5, "Row 5");
  84. }
  85. @Test
  86. public void testRow0() {
  87. openTestURL();
  88. assertRowExists(0, "Row 0");
  89. assertEquals("Grid row height is not what it should be", 40,
  90. $(GridElement.class).first().getRow(0).getSize().getHeight());
  91. }
  92. @Test
  93. public void testRow999() {
  94. openTestURL();
  95. assertRowExists(999, "Row 999");
  96. }
  97. @Test
  98. public void testRow30() {
  99. openTestURL();
  100. Stream.of(30, 130, 230, 330).forEach(this::assertNoButton);
  101. IntStream.range(300, 310).forEach(this::assertNoButton);
  102. }
  103. @Test(expected = AssertionError.class)
  104. public void testRow31() {
  105. openTestURL();
  106. // There is a button on row 31. This should fail.
  107. assertNoButton(31);
  108. }
  109. @Test
  110. public void testHeaders() {
  111. openTestURL();
  112. GridElement grid = $(GridElement.class).first();
  113. GridCellElement headerCell = grid.getHeaderCell(0, 0);
  114. assertTrue("First header should contain a Label",
  115. headerCell.isElementPresent(LabelElement.class));
  116. assertEquals("Label",
  117. headerCell.$(LabelElement.class).first().getText());
  118. assertFalse("Second header should not contain a component",
  119. grid.getHeaderCell(0, 1).isElementPresent(LabelElement.class));
  120. assertEquals("Other Components", grid.getHeaderCell(0, 1).getText());
  121. }
  122. @Test
  123. public void testSelectRowByClickingLabel() {
  124. openTestURL();
  125. GridElement grid = $(GridElement.class).first();
  126. assertFalse("Row should not be initially selected",
  127. grid.getRow(0).isSelected());
  128. grid.getCell(0, 0).$(LabelElement.class).first().click(10, 10,
  129. new Keys[0]);
  130. assertTrue("Row should be selected", grid.getRow(0).isSelected());
  131. }
  132. @Test
  133. public void testRowNotSelectedFromHeaderOrFooter() {
  134. openTestURL();
  135. GridElement grid = $(GridElement.class).first();
  136. grid.getCell(4, 0).$(LabelElement.class).first().click(10, 10,
  137. new Keys[0]);
  138. assertTrue("Row 4 should be selected", grid.getRow(4).isSelected());
  139. TextFieldElement headerTextField = grid.getHeaderCell(1, 0)
  140. .$(TextFieldElement.class).first();
  141. headerTextField.sendKeys(Keys.SPACE);
  142. assertFalse("Row 1 should not be selected",
  143. grid.getRow(1).isSelected());
  144. assertTrue("Row 4 should still be selected",
  145. grid.getRow(4).isSelected());
  146. TextFieldElement footerTextField = grid.getFooterCell(0, 0)
  147. .$(TextFieldElement.class).first();
  148. footerTextField.sendKeys(Keys.SPACE);
  149. assertFalse("Row 0 should not be selected",
  150. grid.getRow(0).isSelected());
  151. assertTrue("Row 4 should still be selected",
  152. grid.getRow(4).isSelected());
  153. }
  154. @Test
  155. public void testTabNavigation() {
  156. Assume.assumeFalse("Firefox has issues with Shift",
  157. BrowserUtil.isFirefox(getDesiredCapabilities()));
  158. openTestURL();
  159. GridElement grid = $(GridElement.class).first();
  160. WebElement resizeHandle = grid.getHeaderCell(0, 0)
  161. .findElement(By.cssSelector("div.v-grid-column-resize-handle"));
  162. new Actions(getDriver()).moveToElement(resizeHandle).clickAndHold()
  163. .moveByOffset(440, 0).release().perform();
  164. // Scroll to end
  165. grid.getCell(0, 2);
  166. int scrollMax = getScrollLeft(grid);
  167. assertTrue("Width of the grid too narrow, no scroll bar",
  168. scrollMax > 0);
  169. // Scroll to start
  170. grid.getHorizontalScroller().scrollLeft(0);
  171. assertEquals(
  172. "Grid should scrolled to the start for this part of the test..",
  173. 0, getScrollLeft(grid));
  174. // Focus TextField in second column
  175. WebElement textField = grid.getCell(0, 1)
  176. .findElement(By.tagName("input"));
  177. textField.click();
  178. // Navigate to currently out of viewport Button
  179. new Actions(getDriver()).sendKeys(Keys.TAB).perform();
  180. assertEquals("Grid should be scrolled to the end", scrollMax,
  181. getScrollLeft(grid));
  182. // Navigate back to fully visible TextField
  183. new Actions(getDriver()).sendKeys(Keys.chord(Keys.SHIFT, Keys.TAB))
  184. .perform();
  185. assertEquals(
  186. "Grid should not scroll when focusing the text field again. ",
  187. scrollMax, getScrollLeft(grid));
  188. // Navigate to out of viewport TextField in Header
  189. new Actions(getDriver()).sendKeys(Keys.chord(Keys.SHIFT, Keys.TAB))
  190. .perform();
  191. // After Chrome 75, sendkeys issues
  192. if (BrowserUtil.isChrome(getDesiredCapabilities())) {
  193. grid.getHeaderCell(1, 0).findElement(By.id("headerField")).click();
  194. }
  195. assertEquals("Focus should be in TextField in Header", "headerField",
  196. getFocusedElement().getAttribute("id"));
  197. assertEquals("Grid should've scrolled back to start.", 0,
  198. getScrollLeft(grid));
  199. // Focus button in last visible row of Grid
  200. grid.getCell(6, 2).findElement(By.id("row_6")).click();
  201. // Navigate to currently out of viewport TextField on Row 7
  202. new Actions(getDriver()).sendKeys(Keys.TAB).perform();
  203. int scrollTopRow7 = Integer
  204. .parseInt(grid.getVerticalScroller().getAttribute("scrollTop"));
  205. assertTrue("Grid should be scrolled to show row 7", scrollTopRow7 > 0);
  206. // Navigate to currently out of viewport TextField on Row 8
  207. new Actions(getDriver()).sendKeys(Keys.TAB, Keys.TAB).perform();
  208. assertTrue("Grid should be scrolled to show row 7",
  209. Integer.parseInt(grid.getVerticalScroller()
  210. .getAttribute("scrollTop")) > scrollTopRow7);
  211. // Focus button in last row of Grid
  212. grid.getCell(999, 2).findElement(By.id("row_999")).click();
  213. // Navigate to out of viewport TextField in Footer
  214. new Actions(getDriver()).sendKeys(Keys.TAB).perform();
  215. assertEquals("Focus should be in TextField in Footer", "footerField",
  216. getFocusedElement().getAttribute("id"));
  217. assertEquals("Grid should've scrolled horizontally back to start.", 0,
  218. getScrollLeft(grid));
  219. }
  220. private int getScrollLeft(GridElement grid) {
  221. return Integer.parseInt(
  222. grid.getHorizontalScroller().getAttribute("scrollLeft"));
  223. }
  224. private void assertRowExists(int i, String string) {
  225. GridRowElement row = $(GridElement.class).first().getRow(i);
  226. assertEquals("Label text did not match", string,
  227. row.getCell(0).getText());
  228. row.findElement(
  229. By.id(string.replace(' ', '_').toLowerCase(Locale.ROOT)))
  230. .click();
  231. // IE 11 is slow, need to wait for the notification.
  232. waitUntil(driver -> isElementPresent(NotificationElement.class), 10);
  233. assertTrue("Notification should contain given text: " + string,
  234. $(NotificationElement.class).first().getText()
  235. .contains(string));
  236. $(NotificationElement.class).first().close();
  237. waitUntil(driver -> !isElementPresent(NotificationElement.class), 10);
  238. }
  239. private void assertNoButton(int i) {
  240. GridRowElement row = $(GridElement.class).first().getRow(i);
  241. assertFalse("Row " + i + " should not have a button",
  242. row.getCell(2).isElementPresent(ButtonElement.class));
  243. }
  244. }