1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package javafx.scene.control.test.tableview; 26 27 import client.test.ScreenshotCheck; 28 import client.test.Smoke; 29 import java.util.Iterator; 30 import java.util.Map.Entry; 31 import java.util.Set; 32 import java.util.logging.Level; 33 import java.util.logging.Logger; 34 import javafx.collections.ObservableList; 35 import javafx.commons.SortValidator; 36 import javafx.geometry.Orientation; 37 import javafx.scene.Node; 38 import javafx.scene.control.*; 39 import javafx.scene.control.test.tableview.TableViewApp.Data; 40 import static javafx.scene.control.test.tableview.TestBase.DATA_FIELDS_NUM; 41 import javafx.scene.control.test.treetable.TreeTableAsOldTableApp; 42 import javafx.util.StringConverter; 43 import org.jemmy.Point; 44 import org.jemmy.Rectangle; 45 import org.jemmy.action.GetAction; 46 import org.jemmy.control.Wrap; 47 import org.jemmy.fx.*; 48 import org.jemmy.interfaces.Parent; 49 import org.jemmy.lookup.Lookup; 50 import org.jemmy.lookup.LookupCriteria; 51 import org.jemmy.timing.State; 52 import org.junit.Assert; 53 import static org.junit.Assert.assertEquals; 54 import static org.junit.Assert.assertTrue; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 import test.javaclient.shared.FilteredTestRunner; 58 import test.javaclient.shared.screenshots.ScreenshotUtils; 59 60 @RunWith(FilteredTestRunner.class) 61 public class TableViewTest extends TestBase { 62 63 /* 64 * removed 65 * @Smoke 66 @Test(timeout=300000) public void keyboardCtrlShiftPageUpPageDownTest() throws 67 * Throwable { keyboardPageUpPageDownCycle(CTRL_DOWN_MASK_OS, 68 * KeyboardModifiers.SHIFT_DOWN_MASK); } 69 */ 70 @ScreenshotCheck 71 @Smoke 72 @Test(timeout = 300000) 73 public void insertSingleItemTest() throws Throwable { 74 insertAt(0); 75 insertAt(TableViewApp.DATA_ITEMS_NUM / 2); 76 ScreenshotUtils.checkScreenshot(getControlName() + "Test-insert-item", contentPane); 77 } 78 79 @ScreenshotCheck 80 @Smoke 81 @Test(timeout = 300000) 82 public void removeSingleItemTest() throws Throwable { 83 removeAt(0); 84 removeAt(TableViewApp.DATA_ITEMS_NUM / 2); 85 ScreenshotUtils.checkScreenshot(getControlName() + "Test-remove-item", contentPane); 86 } 87 88 @ScreenshotCheck 89 @Smoke 90 @Test(timeout = 300000) 91 public void insertSingleColumnTest() throws Throwable { 92 insertColumnAt(0); 93 insertColumnAt(TableViewApp.DATA_FIELDS_NUM / 2); 94 ScreenshotUtils.checkScreenshot(getControlName() + "Test-insert-column", contentPane); 95 } 96 97 @ScreenshotCheck 98 @Smoke 99 @Test(timeout = 300000) 100 public void removeSingleColumnTest() throws Throwable { 101 removeColumnAt(0); 102 removeColumnAt(TableViewApp.DATA_FIELDS_NUM / 2); 103 ScreenshotUtils.checkScreenshot(getControlName() + "Test-remove-column", contentPane); 104 } 105 106 @Smoke 107 @Test(timeout = 300000) 108 public void scrollBarsTest() throws Throwable { 109 final Lookup vScrollBar = getScrollLookup(Orientation.VERTICAL); 110 final Lookup hScrollBar = getScrollLookup(Orientation.HORIZONTAL); 111 final int ROWS_TO_REMOVE = DATA_ITEMS_NUM - pageHeightInCells; 112 final int COLS_TO_REMOVE = DATA_FIELDS_NUM - pageWidthInCells; 113 114 final State<Integer> vScrollBarCount = new State<Integer>() { 115 public Integer reached() { return Integer.valueOf(vScrollBar.size()); } 116 }; 117 118 final State<Integer> hScrollBarCount = new State<Integer>() { 119 public Integer reached() { return Integer.valueOf(hScrollBar.size()); } 120 }; 121 122 testedControl.waitState(hScrollBarCount, Integer.valueOf(1)); 123 testedControl.waitState(vScrollBarCount, Integer.valueOf(1)); 124 for (int i = 0; i < ROWS_TO_REMOVE; i++) { 125 btnRemoveItem.mouse().click(); 126 } 127 testedControl.waitState(vScrollBarCount, Integer.valueOf(0)); 128 129 testedControl.waitState(hScrollBarCount, Integer.valueOf(1)); 130 for (int i = 0; i < COLS_TO_REMOVE; i++) { 131 btnRemoveColumn.mouse().click(); 132 } 133 testedControl.waitState(hScrollBarCount, Integer.valueOf(0)); 134 135 btnInsertItem.mouse().click(); 136 testedControl.waitState(vScrollBarCount, Integer.valueOf(1)); 137 138 btnInsertColumn.mouse().click(); 139 testedControl.waitState(hScrollBarCount, Integer.valueOf(1)); 140 } 141 142 /** 143 * Checks that sort works for the column. According to the spec there are 144 * three states of sorting and all of them are checked 145 * 146 */ 147 @Smoke 148 @Test(timeout = 300000) 149 public void columnSortTest() throws Throwable { 150 Wrap<? extends Node> columHeader = headerWrap.as(Parent.class, Node.class).lookup(Label.class, new ByText("field 0")).wrap(); 151 152 //Ascending sort 153 columHeader.mouse().click(); 154 Wrap<? extends IndexedCell> cellWrap = getCellWrap(0, isTableTests ? 0 : 1);// first line for treeTable - is root line. 155 assertTrue(cellWrap.getControl().getItem().equals("item 00 field 0")); 156 157 //Descending sort 158 columHeader.mouse().click(); 159 cellWrap = getCellWrap(0, isTableTests ? 0 : 1); 160 int expectedIndex = isTableTests 161 ? TableViewApp.DATA_ITEMS_NUM - 1 162 : TreeTableAsOldTableApp.DATA_ITEMS_NUM - 2; 163 assertEquals(String.format("item %02d field 0", expectedIndex), cellWrap.getControl().getItem()); 164 165 //Disable sort 166 columHeader.mouse().click(); 167 168 //Ascending sort 169 columHeader.mouse().click(); 170 cellWrap = getCellWrap(0, isTableTests ? 0 : 1); 171 assertTrue(cellWrap.getControl().getItem().equals("item 00 field 0")); 172 173 scrollTo(0, TableViewApp.DATA_ITEMS_NUM - 1); 174 cellWrap = getCellWrap(0, TableViewApp.DATA_ITEMS_NUM - 1); 175 Rectangle old_bounds = cellWrap.getScreenBounds(); 176 columHeader.mouse().click(); 177 cellWrap = getCellWrap(0, TableViewApp.DATA_ITEMS_NUM - 1); 178 Rectangle newBounds = cellWrap.getScreenBounds(); 179 assertEquals(old_bounds.x, newBounds.x, 1); 180 assertEquals(old_bounds.y, newBounds.y, 1); 181 assertEquals(old_bounds.width, newBounds.width, 1); 182 assertEquals(old_bounds.height, newBounds.height, 1); 183 } 184 185 @ScreenshotCheck 186 @Test(timeout = 300000) 187 public void columnDragTest() throws Throwable { 188 Wrap<? extends Node> column_header_0 = headerWrap.as(Parent.class, Node.class).lookup(Label.class, new ByText("field 0")).wrap(); 189 190 Rectangle header_bounds = column_header_0.getScreenBounds(); 191 Rectangle content_bounds = contentPane.getScreenBounds(); 192 Double x = header_bounds.getX() - content_bounds.getX() + header_bounds.getWidth() / 2; 193 Double y = header_bounds.getY() - content_bounds.getY() + header_bounds.getHeight() / 2; 194 contentPane.mouse().move(new Point(x, y)); 195 contentPane.mouse().press(); 196 contentPane.mouse().move(new Point(0, 0)); 197 checkScreenshot(getControlName() + "Test-columnDrag-outside-0", contentPane); 198 contentPane.mouse().move(new Point(content_bounds.getWidth(), 0)); 199 checkScreenshot(getControlName() + "Test-columnDrag-outside-1", contentPane); 200 contentPane.mouse().move(new Point(content_bounds.getWidth(), content_bounds.getHeight())); 201 checkScreenshot(getControlName() + "Test-columnDrag-outside-2", contentPane); 202 contentPane.mouse().move(new Point(0, content_bounds.getHeight())); 203 checkScreenshot(getControlName() + "Test-columnDrag-outside-3", contentPane); 204 contentPane.mouse().move(new Point(0, 0)); 205 checkScreenshot(getControlName() + "Test-columnDrag-outside-0", contentPane); 206 contentPane.mouse().release(); 207 208 Rectangle table_bounds = tableViewWrap.getScreenBounds(); 209 x = header_bounds.getX() - table_bounds.getX() + header_bounds.getWidth() / 2; 210 y = header_bounds.getY() - table_bounds.getY() + header_bounds.getHeight() / 2; 211 tableViewWrap.mouse().move(new Point(x, y)); 212 tableViewWrap.mouse().press(); 213 tableViewWrap.mouse().move(new Point(0, 0)); 214 checkScreenshot(getControlName() + "Test-columnDrag-inside-0", contentPane); 215 tableViewWrap.mouse().move(new Point(table_bounds.getWidth() / 2, header_bounds.getHeight() / 2)); 216 checkScreenshot(getControlName() + "Test-columnDrag-inside-1", contentPane); 217 tableViewWrap.mouse().move(new Point(table_bounds.getWidth(), header_bounds.getHeight() / 2)); 218 checkScreenshot(getControlName() + "Test-columnDrag-inside-2", contentPane); 219 tableViewWrap.mouse().move(new Point(x, y)); 220 tableViewWrap.mouse().release(); 221 222 Wrap<? extends Node> column_header_3 = headerWrap.as(Parent.class, Node.class).lookup(Label.class, new ByText("field 3")).wrap(); 223 column_header_0.drag().dnd(column_header_3, column_header_3.getClickPoint().translate(5, 0)); 224 Wrap<? extends IndexedCell> cell_wrap = getCellWrap(0, 0); 225 assertTrue(cell_wrap.getControl().getItem().equals("item 00 field 1")); 226 cell_wrap = getCellWrap(3, 0); 227 assertTrue(cell_wrap.getControl().getItem().equals("item 00 field 0")); 228 229 throwScreenshotError(); 230 } 231 232 @Smoke 233 @Test(timeout = 300000) 234 public void columnAutoSize() throws Throwable { 235 final double AUTO_WIDTH = isTableTests ? 85 : 215; 236 237 final Wrap<? extends Node> columnHeader0 = headerWrap.as(Parent.class, Node.class).lookup(Label.class, new ByText("field 0")).wrap(); 238 239 Rectangle headerBounds = columnHeader0.getScreenBounds(); 240 241 final double shrinkedWidth = headerBounds.getWidth() / 2; 242 columnHeader0.mouse().move(new Point(headerBounds.getWidth(), headerBounds.getHeight() / 2)); 243 columnHeader0.mouse().press(); 244 columnHeader0.mouse().move(new Point(shrinkedWidth, headerBounds.getHeight() / 2)); 245 columnHeader0.mouse().release(); 246 247 columnHeader0.waitState(new State() { 248 public Object reached() { 249 System.out.println("Checking, that width reducing was applied correctly (by 1 times)."); 250 Rectangle header_bounds = columnHeader0.getScreenBounds(); 251 if (Math.abs(header_bounds.getWidth() - shrinkedWidth) <= 5) { 252 System.out.println("Correct."); 253 return Boolean.TRUE; 254 } 255 System.out.println("Incorrect."); 256 return null; 257 } 258 }); 259 260 headerBounds = columnHeader0.getScreenBounds(); 261 columnHeader0.mouse().click(2, new Point(headerBounds.getWidth(), headerBounds.getHeight() / 2)); 262 263 columnHeader0.waitState(new State() { 264 public Object reached() { 265 System.out.println("Checking, that autosizing was applied correctly."); 266 Rectangle header_bounds = columnHeader0.getScreenBounds(); 267 if (Math.abs(header_bounds.getWidth() - AUTO_WIDTH) < 5) { // TODO: 268 System.out.println("Correct."); 269 return Boolean.TRUE; 270 } 271 System.out.println("Incorrect."); 272 return null; 273 } 274 }); 275 } 276 277 @Smoke 278 @Test(timeout = 300000) 279 public void userDataColumnTest() { 280 ObservableList<TableColumnBase> columns; 281 if (isTableTests) { 282 columns = ((TableView) tableViewWrap.getControl()).getColumns(); 283 } else { 284 columns = ((TreeTableView) tableViewWrap.getControl()).getColumns(); 285 } 286 Object userData[] = new Object[columns.size()]; 287 for (int i = 0; i < userData.length; i++) { 288 userData[i] = new Object(); 289 columns.get(i).setUserData(userData[i]); 290 } 291 for (int i = 0; i < userData.length; i++) { 292 System.out.println("userData[i] = " + userData[i]); 293 System.out.println("columns.get(i).getUserData() = " + columns.get(i).getUserData()); 294 System.out.println("columns.get(i).getProperties().entrySet() = " + columns.get(i).getProperties().entrySet()); 295 // Assert.assertTrue(columns.get(i).getProperties().containsKey(userData[i])); 296 Assert.assertTrue(columns.get(i).getProperties().containsValue(userData[i])); 297 298 Set entrySet = columns.get(i).getProperties().entrySet(); 299 for (Iterator<Entry> it = entrySet.iterator(); it.hasNext();) { 300 Entry entry = it.next(); 301 System.out.println("key = " + entry.getKey() + "; val = " + entry.getValue()); 302 } 303 304 Assert.assertEquals(userData[i], columns.get(i).getUserData()); 305 //Assert.assertTrue(columns.get(i).getProperties().entrySet().contains(userData[i])); 306 } 307 } 308 309 /** 310 * Checks that when the sorting is applied 311 * to the underlying data collection 312 * the cells are rendered in the right order. 313 */ 314 @Smoke 315 @Test(timeout=300000) 316 public void renderingAfterSortingTest() throws Throwable { 317 318 final int ITEMS_COUNT = 7; 319 final int COL_IDX = 0; 320 321 StringConverter<Data> conv = new StringConverter<Data>() { 322 @Override 323 public String toString(Data item) { 324 return String.format("item %s field %d", item.toString(), COL_IDX); 325 } 326 327 @Override 328 public Data fromString(String s) { return new Data(s, DATA_FIELDS_NUM, 0); } 329 }; 330 331 SortValidator<Data, TableCell> validator = new SortValidator<Data, TableCell>(ITEMS_COUNT, conv) { 332 333 @Override 334 protected void setControlData(final ObservableList<Data> ls) { 335 new GetAction<Object>() { 336 @Override 337 public void run(Object... os) throws Exception { 338 if (isTableTests) { 339 ((TableView) testedControl.getControl()).setItems(ls); 340 } else { 341 for (Data data : ls) { 342 ((TreeTableView) testedControl.getControl()).getRoot().getChildren().addAll(new TreeItem(data)); 343 } 344 ((TreeTableView) testedControl.getControl()).setShowRoot(false); 345 } 346 } 347 }.dispatch(testedControl.getEnvironment()); 348 } 349 350 @Override 351 protected Lookup<? extends TableCell> getCellsLookup() { 352 return testedControl.as(Parent.class, Node.class).lookup(TableCell.class, new LookupCriteria<TableCell>() { 353 public boolean check(TableCell cell) { 354 TableColumn col = cell.getTableColumn(); 355 return COL_IDX == cell.getTableView().getColumns().indexOf(col) && cell.isVisible(); 356 } 357 }); 358 } 359 360 @Override 361 protected String getTextFromCell(TableCell cell) { 362 return cell.getText(); 363 } 364 }; 365 366 boolean result = validator.check(); 367 String msg = validator.getFailureReason(); 368 assertTrue(msg, result); 369 } 370 371 @Smoke 372 @Test(timeout=300000) 373 public void scrollToColumnIndex() { 374 DATA_FIELDS_NUM = 64; 375 refill(DATA_FIELDS_NUM, DATA_ITEMS_NUM); 376 377 scrollToColumnByIndex(DATA_FIELDS_NUM - 1); 378 assertTrue(isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 379 assertTrue(!isColumnHeaderVisible(0)); 380 assertEquals(getScrollBarMaxValue(Orientation.HORIZONTAL), getScrollBarValue(Orientation.HORIZONTAL), 1e-7); 381 382 scrollToColumnByIndex(0); 383 assertTrue(isColumnHeaderVisible(0)); 384 assertTrue(!isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 385 assertEquals(getScrollBarMinValue(Orientation.HORIZONTAL), getScrollBarValue(Orientation.HORIZONTAL), 1e-7); 386 387 scrollToColumn(DATA_FIELDS_NUM - 1); 388 assertTrue(isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 389 assertTrue(!isColumnHeaderVisible(0)); 390 assertEquals(getScrollBarMaxValue(Orientation.HORIZONTAL), getScrollBarValue(Orientation.HORIZONTAL), 1e-7); 391 392 scrollToColumn(0); 393 assertTrue(isColumnHeaderVisible(0)); 394 assertTrue(!isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 395 assertEquals(getScrollBarMinValue(Orientation.HORIZONTAL), getScrollBarValue(Orientation.HORIZONTAL), 1e-7); 396 397 scrollToColumnByIndex(DATA_FIELDS_NUM / 3); 398 assertTrue(isColumnHeaderVisible(DATA_FIELDS_NUM / 3)); 399 assertTrue(!isColumnHeaderVisible(0)); 400 assertTrue(!isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 401 double delta = testedControl.getScreenBounds().getWidth() / 2; 402 assertEquals(getScrollBarMaxValue(Orientation.HORIZONTAL) / 3, getScrollBarValue(Orientation.HORIZONTAL), delta); 403 } 404 405 /** 406 * Checks that column resizing is correct 407 * according to desired values 408 */ 409 @Smoke 410 @Test 411 public void columnResizeTest() { 412 final int columnIndex = 0; 413 414 double delta = 0.0; 415 double expectedWidth = getColumnWidth(columnIndex); 416 resizeColumn(columnIndex, delta); 417 assertEquals(expectedWidth, getColumnWidth(columnIndex), 1e-7); 418 419 delta = 100.0; 420 expectedWidth += delta; 421 resizeColumn(columnIndex, delta); 422 assertEquals(expectedWidth, getColumnWidth(columnIndex), 1e-7); 423 424 delta = 0.0; 425 resizeColumn(columnIndex, delta); 426 assertEquals(expectedWidth, getColumnWidth(columnIndex), 1e-7); 427 428 delta = 100.0; 429 expectedWidth += delta; 430 resizeColumn(columnIndex, delta); 431 assertEquals(expectedWidth, getColumnWidth(columnIndex), 1e-7); 432 } 433 434 @Override 435 protected void insertAt(int pos) { 436 txtItemInsertIndex.clear(); 437 txtItemInsertIndex.type(String.valueOf(pos)); 438 btnInsertItem.mouse().click(); 439 } 440 441 @Override 442 protected void insertColumnAt(int pos) { 443 txtColumnInserIndex.clear(); 444 txtColumnInserIndex.type(String.valueOf(pos)); 445 btnInsertColumn.mouse().click(); 446 } 447 448 @Override 449 protected void removeAt(int pos) { 450 txtItemRemoveIndex.clear(); 451 txtItemRemoveIndex.type(String.valueOf(pos)); 452 btnRemoveItem.mouse().click(); 453 } 454 455 @Override 456 protected void removeColumnAt(int pos) { 457 txtColumnRemoveIndex.clear(); 458 txtColumnRemoveIndex.type(String.valueOf(pos)); 459 btnRemoveColumn.mouse().click(); 460 } 461 }