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 * http://xdesign.us.oracle.com/projects/javaFX/fxcontrols-ue/specifications/treetable/treetable.html#sorting 147 */ 148 @Smoke 149 @Test(timeout = 300000) 150 public void columnSortTest() throws Throwable { 151 Wrap<? extends Node> columHeader = headerWrap.as(Parent.class, Node.class).lookup(Label.class, new ByText("field 0")).wrap(); 152 153 //Ascending sort 154 columHeader.mouse().click(); 155 Wrap<? extends IndexedCell> cellWrap = getCellWrap(0, isTableTests ? 0 : 1);// first line for treeTable - is root line. 156 assertTrue(cellWrap.getControl().getItem().equals("item 00 field 0")); 157 158 //Descending sort 159 columHeader.mouse().click(); 160 cellWrap = getCellWrap(0, isTableTests ? 0 : 1); 161 int expectedIndex = isTableTests 162 ? TableViewApp.DATA_ITEMS_NUM - 1 163 : TreeTableAsOldTableApp.DATA_ITEMS_NUM - 2; 164 assertEquals(String.format("item %02d field 0", expectedIndex), cellWrap.getControl().getItem()); 165 166 //Disable sort 167 columHeader.mouse().click(); 168 169 //Ascending sort 170 columHeader.mouse().click(); 171 cellWrap = getCellWrap(0, isTableTests ? 0 : 1); 172 assertTrue(cellWrap.getControl().getItem().equals("item 00 field 0")); 173 174 scrollTo(0, TableViewApp.DATA_ITEMS_NUM - 1); 175 cellWrap = getCellWrap(0, TableViewApp.DATA_ITEMS_NUM - 1); 176 Rectangle old_bounds = cellWrap.getScreenBounds(); 177 columHeader.mouse().click(); 178 cellWrap = getCellWrap(0, TableViewApp.DATA_ITEMS_NUM - 1); 179 Rectangle newBounds = cellWrap.getScreenBounds(); 180 assertEquals(old_bounds.x, newBounds.x, 1); 181 assertEquals(old_bounds.y, newBounds.y, 1); 182 assertEquals(old_bounds.width, newBounds.width, 1); 183 assertEquals(old_bounds.height, newBounds.height, 1); 184 } 185 186 @ScreenshotCheck 187 @Test(timeout = 300000) 188 public void columnDragTest() throws Throwable { 189 Wrap<? extends Node> column_header_0 = headerWrap.as(Parent.class, Node.class).lookup(Label.class, new ByText("field 0")).wrap(); 190 191 Rectangle header_bounds = column_header_0.getScreenBounds(); 192 Rectangle content_bounds = contentPane.getScreenBounds(); 193 Double x = header_bounds.getX() - content_bounds.getX() + header_bounds.getWidth() / 2; 194 Double y = header_bounds.getY() - content_bounds.getY() + header_bounds.getHeight() / 2; 195 contentPane.mouse().move(new Point(x, y)); 196 contentPane.mouse().press(); 197 contentPane.mouse().move(new Point(0, 0)); 198 checkScreenshot(getControlName() + "Test-columnDrag-outside-0", contentPane); 199 contentPane.mouse().move(new Point(content_bounds.getWidth(), 0)); 200 checkScreenshot(getControlName() + "Test-columnDrag-outside-1", contentPane); 201 contentPane.mouse().move(new Point(content_bounds.getWidth(), content_bounds.getHeight())); 202 checkScreenshot(getControlName() + "Test-columnDrag-outside-2", contentPane); 203 contentPane.mouse().move(new Point(0, content_bounds.getHeight())); 204 checkScreenshot(getControlName() + "Test-columnDrag-outside-3", contentPane); 205 contentPane.mouse().move(new Point(0, 0)); 206 checkScreenshot(getControlName() + "Test-columnDrag-outside-0", contentPane); 207 contentPane.mouse().release(); 208 209 Rectangle table_bounds = tableViewWrap.getScreenBounds(); 210 x = header_bounds.getX() - table_bounds.getX() + header_bounds.getWidth() / 2; 211 y = header_bounds.getY() - table_bounds.getY() + header_bounds.getHeight() / 2; 212 tableViewWrap.mouse().move(new Point(x, y)); 213 tableViewWrap.mouse().press(); 214 tableViewWrap.mouse().move(new Point(0, 0)); 215 checkScreenshot(getControlName() + "Test-columnDrag-inside-0", contentPane); 216 tableViewWrap.mouse().move(new Point(table_bounds.getWidth() / 2, header_bounds.getHeight() / 2)); 217 checkScreenshot(getControlName() + "Test-columnDrag-inside-1", contentPane); 218 tableViewWrap.mouse().move(new Point(table_bounds.getWidth(), header_bounds.getHeight() / 2)); 219 checkScreenshot(getControlName() + "Test-columnDrag-inside-2", contentPane); 220 tableViewWrap.mouse().move(new Point(x, y)); 221 tableViewWrap.mouse().release(); 222 223 Wrap<? extends Node> column_header_3 = headerWrap.as(Parent.class, Node.class).lookup(Label.class, new ByText("field 3")).wrap(); 224 column_header_0.drag().dnd(column_header_3, column_header_3.getClickPoint().translate(5, 0)); 225 Wrap<? extends IndexedCell> cell_wrap = getCellWrap(0, 0); 226 assertTrue(cell_wrap.getControl().getItem().equals("item 00 field 1")); 227 cell_wrap = getCellWrap(3, 0); 228 assertTrue(cell_wrap.getControl().getItem().equals("item 00 field 0")); 229 230 throwScreenshotError(); 231 } 232 233 @Smoke 234 @Test(timeout = 300000) 235 public void columnAutoSize() throws Throwable { 236 final double AUTO_WIDTH = isTableTests ? 85 : 215; 237 238 final Wrap<? extends Node> columnHeader0 = headerWrap.as(Parent.class, Node.class).lookup(Label.class, new ByText("field 0")).wrap(); 239 240 Rectangle headerBounds = columnHeader0.getScreenBounds(); 241 242 final double shrinkedWidth = headerBounds.getWidth() / 2; 243 columnHeader0.mouse().move(new Point(headerBounds.getWidth(), headerBounds.getHeight() / 2)); 244 columnHeader0.mouse().press(); 245 columnHeader0.mouse().move(new Point(shrinkedWidth, headerBounds.getHeight() / 2)); 246 columnHeader0.mouse().release(); 247 248 columnHeader0.waitState(new State() { 249 public Object reached() { 250 System.out.println("Checking, that width reducing was applied correctly (by 1 times)."); 251 Rectangle header_bounds = columnHeader0.getScreenBounds(); 252 if (Math.abs(header_bounds.getWidth() - shrinkedWidth) <= 5) { 253 System.out.println("Correct."); 254 return Boolean.TRUE; 255 } 256 System.out.println("Incorrect."); 257 return null; 258 } 259 }); 260 261 headerBounds = columnHeader0.getScreenBounds(); 262 columnHeader0.mouse().click(2, new Point(headerBounds.getWidth(), headerBounds.getHeight() / 2)); 263 264 columnHeader0.waitState(new State() { 265 public Object reached() { 266 System.out.println("Checking, that autosizing was applied correctly."); 267 Rectangle header_bounds = columnHeader0.getScreenBounds(); 268 if (Math.abs(header_bounds.getWidth() - AUTO_WIDTH) < 5) { // TODO: 269 System.out.println("Correct."); 270 return Boolean.TRUE; 271 } 272 System.out.println("Incorrect."); 273 return null; 274 } 275 }); 276 } 277 278 @Smoke 279 @Test(timeout = 300000) 280 public void userDataColumnTest() { 281 ObservableList<TableColumnBase> columns; 282 if (isTableTests) { 283 columns = ((TableView) tableViewWrap.getControl()).getColumns(); 284 } else { 285 columns = ((TreeTableView) tableViewWrap.getControl()).getColumns(); 286 } 287 Object userData[] = new Object[columns.size()]; 288 for (int i = 0; i < userData.length; i++) { 289 userData[i] = new Object(); 290 columns.get(i).setUserData(userData[i]); 291 } 292 for (int i = 0; i < userData.length; i++) { 293 System.out.println("userData[i] = " + userData[i]); 294 System.out.println("columns.get(i).getUserData() = " + columns.get(i).getUserData()); 295 System.out.println("columns.get(i).getProperties().entrySet() = " + columns.get(i).getProperties().entrySet()); 296 // Assert.assertTrue(columns.get(i).getProperties().containsKey(userData[i])); 297 Assert.assertTrue(columns.get(i).getProperties().containsValue(userData[i])); 298 299 Set entrySet = columns.get(i).getProperties().entrySet(); 300 for (Iterator<Entry> it = entrySet.iterator(); it.hasNext();) { 301 Entry entry = it.next(); 302 System.out.println("key = " + entry.getKey() + "; val = " + entry.getValue()); 303 } 304 305 Assert.assertEquals(userData[i], columns.get(i).getUserData()); 306 //Assert.assertTrue(columns.get(i).getProperties().entrySet().contains(userData[i])); 307 } 308 } 309 310 /** 311 * Checks that when the sorting is applied 312 * to the underlying data collection 313 * the cells are rendered in the right order. 314 */ 315 @Smoke 316 @Test(timeout=300000) 317 public void renderingAfterSortingTest() throws Throwable { 318 319 final int ITEMS_COUNT = 7; 320 final int COL_IDX = 0; 321 322 StringConverter<Data> conv = new StringConverter<Data>() { 323 @Override 324 public String toString(Data item) { 325 return String.format("item %s field %d", item.toString(), COL_IDX); 326 } 327 328 @Override 329 public Data fromString(String s) { return new Data(s, DATA_FIELDS_NUM, 0); } 330 }; 331 332 SortValidator<Data, TableCell> validator = new SortValidator<Data, TableCell>(ITEMS_COUNT, conv) { 333 334 @Override 335 protected void setControlData(final ObservableList<Data> ls) { 336 new GetAction<Object>() { 337 @Override 338 public void run(Object... os) throws Exception { 339 if (isTableTests) { 340 ((TableView) testedControl.getControl()).setItems(ls); 341 } else { 342 for (Data data : ls) { 343 ((TreeTableView) testedControl.getControl()).getRoot().getChildren().addAll(new TreeItem(data)); 344 } 345 ((TreeTableView) testedControl.getControl()).setShowRoot(false); 346 } 347 } 348 }.dispatch(testedControl.getEnvironment()); 349 } 350 351 @Override 352 protected Lookup<? extends TableCell> getCellsLookup() { 353 return testedControl.as(Parent.class, Node.class).lookup(TableCell.class, new LookupCriteria<TableCell>() { 354 public boolean check(TableCell cell) { 355 TableColumn col = cell.getTableColumn(); 356 return COL_IDX == cell.getTableView().getColumns().indexOf(col) && cell.isVisible(); 357 } 358 }); 359 } 360 361 @Override 362 protected String getTextFromCell(TableCell cell) { 363 return cell.getText(); 364 } 365 }; 366 367 boolean result = validator.check(); 368 String msg = validator.getFailureReason(); 369 assertTrue(msg, result); 370 } 371 372 @Smoke 373 @Test(timeout=300000) 374 public void scrollToColumnIndex() { 375 DATA_FIELDS_NUM = 64; 376 refill(DATA_FIELDS_NUM, DATA_ITEMS_NUM); 377 378 scrollToColumnByIndex(DATA_FIELDS_NUM - 1); 379 assertTrue(isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 380 assertTrue(!isColumnHeaderVisible(0)); 381 assertEquals(getScrollBarMaxValue(Orientation.HORIZONTAL), getScrollBarValue(Orientation.HORIZONTAL), 1e-7); 382 383 scrollToColumnByIndex(0); 384 assertTrue(isColumnHeaderVisible(0)); 385 assertTrue(!isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 386 assertEquals(getScrollBarMinValue(Orientation.HORIZONTAL), getScrollBarValue(Orientation.HORIZONTAL), 1e-7); 387 388 scrollToColumn(DATA_FIELDS_NUM - 1); 389 assertTrue(isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 390 assertTrue(!isColumnHeaderVisible(0)); 391 assertEquals(getScrollBarMaxValue(Orientation.HORIZONTAL), getScrollBarValue(Orientation.HORIZONTAL), 1e-7); 392 393 scrollToColumn(0); 394 assertTrue(isColumnHeaderVisible(0)); 395 assertTrue(!isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 396 assertEquals(getScrollBarMinValue(Orientation.HORIZONTAL), getScrollBarValue(Orientation.HORIZONTAL), 1e-7); 397 398 scrollToColumnByIndex(DATA_FIELDS_NUM / 3); 399 assertTrue(isColumnHeaderVisible(DATA_FIELDS_NUM / 3)); 400 assertTrue(!isColumnHeaderVisible(0)); 401 assertTrue(!isColumnHeaderVisible(DATA_FIELDS_NUM - 1)); 402 double delta = testedControl.getScreenBounds().getWidth() / 2; 403 assertEquals(getScrollBarMaxValue(Orientation.HORIZONTAL) / 3, getScrollBarValue(Orientation.HORIZONTAL), delta); 404 } 405 406 /** 407 * Checks that column resizing is correct 408 * according to desired values 409 */ 410 @Smoke 411 @Test 412 public void columnResizeTest() { 413 final int columnIndex = 0; 414 415 double delta = 0.0; 416 double expectedWidth = getColumnWidth(columnIndex); 417 resizeColumn(columnIndex, delta); 418 assertEquals(expectedWidth, getColumnWidth(columnIndex), 1e-7); 419 420 delta = 100.0; 421 expectedWidth += delta; 422 resizeColumn(columnIndex, delta); 423 assertEquals(expectedWidth, getColumnWidth(columnIndex), 1e-7); 424 425 delta = 0.0; 426 resizeColumn(columnIndex, delta); 427 assertEquals(expectedWidth, getColumnWidth(columnIndex), 1e-7); 428 429 delta = 100.0; 430 expectedWidth += delta; 431 resizeColumn(columnIndex, delta); 432 assertEquals(expectedWidth, getColumnWidth(columnIndex), 1e-7); 433 } 434 435 @Override 436 protected void insertAt(int pos) { 437 txtItemInsertIndex.clear(); 438 txtItemInsertIndex.type(String.valueOf(pos)); 439 btnInsertItem.mouse().click(); 440 } 441 442 @Override 443 protected void insertColumnAt(int pos) { 444 txtColumnInserIndex.clear(); 445 txtColumnInserIndex.type(String.valueOf(pos)); 446 btnInsertColumn.mouse().click(); 447 } 448 449 @Override 450 protected void removeAt(int pos) { 451 txtItemRemoveIndex.clear(); 452 txtItemRemoveIndex.type(String.valueOf(pos)); 453 btnRemoveItem.mouse().click(); 454 } 455 456 @Override 457 protected void removeColumnAt(int pos) { 458 txtColumnRemoveIndex.clear(); 459 txtColumnRemoveIndex.type(String.valueOf(pos)); 460 btnRemoveColumn.mouse().click(); 461 } 462 }