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 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. package com.vaadin.tests.components.grid;
  2. import static org.junit.Assert.assertEquals;
  3. import static org.junit.Assert.assertFalse;
  4. import static org.junit.Assert.assertTrue;
  5. import java.util.Locale;
  6. import java.util.stream.IntStream;
  7. import java.util.stream.Stream;
  8. import org.junit.Assume;
  9. import org.junit.Test;
  10. import org.openqa.selenium.Keys;
  11. import org.openqa.selenium.WebElement;
  12. import org.openqa.selenium.interactions.Actions;
  13. import com.vaadin.testbench.By;
  14. import com.vaadin.testbench.elements.ButtonElement;
  15. import com.vaadin.testbench.elements.GridElement;
  16. import com.vaadin.testbench.elements.GridElement.GridCellElement;
  17. import com.vaadin.testbench.elements.GridElement.GridRowElement;
  18. import com.vaadin.testbench.elements.LabelElement;
  19. import com.vaadin.testbench.elements.NotificationElement;
  20. import com.vaadin.testbench.elements.TextFieldElement;
  21. import com.vaadin.testbench.parallel.BrowserUtil;
  22. import com.vaadin.tests.tb3.MultiBrowserTest;
  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. pressKeyWithModifier(Keys.SHIFT, Keys.TAB);
  184. assertEquals(
  185. "Grid should not scroll when focusing the text field again. ",
  186. scrollMax, getScrollLeft(grid));
  187. // Navigate to out of viewport TextField in Header
  188. pressKeyWithModifier(Keys.SHIFT, Keys.TAB);
  189. assertEquals("Focus should be in TextField in Header", "headerField",
  190. getFocusedElement().getAttribute("id"));
  191. assertEquals("Grid should've scrolled back to start.", 0,
  192. getScrollLeft(grid));
  193. // Focus button in last visible row of Grid
  194. grid.getCell(6, 2).findElement(By.id("row_6")).click();
  195. // Navigate to currently out of viewport TextField on Row 7
  196. new Actions(getDriver()).sendKeys(Keys.TAB).perform();
  197. int scrollTopRow7 = Integer
  198. .parseInt(grid.getVerticalScroller().getAttribute("scrollTop"));
  199. assertTrue("Grid should be scrolled to show row 7", scrollTopRow7 > 0);
  200. // Navigate to currently out of viewport TextField on Row 8
  201. new Actions(getDriver()).sendKeys(Keys.TAB, Keys.TAB).perform();
  202. assertTrue("Grid should be scrolled to show row 8",
  203. Integer.parseInt(grid.getVerticalScroller()
  204. .getAttribute("scrollTop")) > scrollTopRow7);
  205. // Focus button in first visible row of Grid
  206. grid.getCell(2, 2).findElement(By.id("row_2")).click();
  207. int scrollTopRow2 = Integer
  208. .parseInt(grid.getVerticalScroller().getAttribute("scrollTop"));
  209. // Navigate to currently out of viewport Button on Row 1
  210. pressKeyWithModifier(Keys.SHIFT, Keys.TAB);
  211. pressKeyWithModifier(Keys.SHIFT, Keys.TAB);
  212. int scrollTopRow1 = Integer
  213. .parseInt(grid.getVerticalScroller().getAttribute("scrollTop"));
  214. assertTrue("Grid should be scrolled to show row 1",
  215. scrollTopRow1 < scrollTopRow2);
  216. // Continue further to the very first row
  217. pressKeyWithModifier(Keys.SHIFT, Keys.TAB);
  218. pressKeyWithModifier(Keys.SHIFT, Keys.TAB);
  219. assertTrue("Grid should be scrolled to show row 0",
  220. Integer.parseInt(grid.getVerticalScroller()
  221. .getAttribute("scrollTop")) < scrollTopRow1);
  222. // Focus button in last row of Grid
  223. grid.getCell(999, 2).findElement(By.id("row_999")).click();
  224. // Navigate to out of viewport TextField in Footer
  225. new Actions(getDriver()).sendKeys(Keys.TAB).perform();
  226. assertEquals("Focus should be in TextField in Footer", "footerField",
  227. getFocusedElement().getAttribute("id"));
  228. assertEquals("Grid should've scrolled horizontally back to start.", 0,
  229. getScrollLeft(grid));
  230. }
  231. private int getScrollLeft(GridElement grid) {
  232. return Integer.parseInt(
  233. grid.getHorizontalScroller().getAttribute("scrollLeft"));
  234. }
  235. private void assertRowExists(int i, String string) {
  236. GridRowElement row = $(GridElement.class).first().getRow(i);
  237. assertEquals("Label text did not match", string,
  238. row.getCell(0).getText());
  239. row.findElement(
  240. By.id(string.replace(' ', '_').toLowerCase(Locale.ROOT)))
  241. .click();
  242. // IE 11 is slow, need to wait for the notification.
  243. waitUntil(driver -> isElementPresent(NotificationElement.class), 10);
  244. assertTrue("Notification should contain given text: " + string,
  245. $(NotificationElement.class).first().getText()
  246. .contains(string));
  247. $(NotificationElement.class).first().close();
  248. waitUntil(driver -> !isElementPresent(NotificationElement.class), 10);
  249. }
  250. private void assertNoButton(int i) {
  251. GridRowElement row = $(GridElement.class).first().getRow(i);
  252. assertFalse("Row " + i + " should not have a button",
  253. row.getCell(2).isElementPresent(ButtonElement.class));
  254. }
  255. // Workaround for Chrome 75, sendKeys(Keys.chord(Keys.SHIFT, Keys.TAB))
  256. // doesn't work anymore
  257. private void pressKeyWithModifier(Keys keyModifier, Keys key) {
  258. new Actions(getDriver()).keyDown(keyModifier).perform();
  259. new Actions(getDriver()).sendKeys(key).perform();
  260. new Actions(getDriver()).keyUp(keyModifier).perform();
  261. }
  262. }