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 26 package javafx.scene.control.test.tableview; 27 28 import client.test.Smoke; 29 import com.sun.javafx.scene.control.skin.NestedTableColumnHeader; 30 import com.sun.javafx.scene.control.skin.TableColumnHeader; 31 import com.sun.javafx.scene.control.skin.TableHeaderRow; 32 import java.awt.Robot; 33 import java.awt.event.InputEvent; 34 import java.util.ArrayList; 35 import java.util.List; 36 import java.util.logging.Level; 37 import java.util.logging.Logger; 38 import static javafx.collections.FXCollections.*; 39 import javafx.collections.ObservableList; 40 import static javafx.commons.Consts.*; 41 import javafx.commons.Consts.CellEditorType; 42 import javafx.geometry.Orientation; 43 import javafx.scene.Group; 44 import javafx.scene.Node; 45 import javafx.scene.Scene; 46 import javafx.scene.control.Cell; 47 import javafx.scene.control.ChoiceBox; 48 import javafx.scene.control.ComboBox; 49 import javafx.scene.control.Control; 50 import javafx.scene.control.IndexedCell; 51 import javafx.scene.control.Label; 52 import javafx.scene.control.ListView; 53 import javafx.scene.control.TableCell; 54 import javafx.scene.control.TableColumn; 55 import javafx.scene.control.TableColumnBase; 56 import javafx.scene.control.TableRow; 57 import javafx.scene.control.TableView; 58 import javafx.scene.control.TextField; 59 import javafx.scene.control.TreeTableCell; 60 import javafx.scene.control.TreeTableColumn; 61 import javafx.scene.control.TreeTableRow; 62 import javafx.scene.control.TreeTableView; 63 import static javafx.scene.control.test.tableview.ApplicationInteractionFunctions.addColumn; 64 import static javafx.scene.control.test.tableview.ApplicationInteractionFunctions.isTableTests; 65 import static javafx.scene.control.test.tableview.ApplicationInteractionFunctions.testedControl; 66 import static javafx.scene.control.test.util.TableListCommonTests.fixedCellSizePropertyTestCommon; 67 import javafx.scene.control.test.utils.ptables.AbstractPropertyController.SettingType; 68 import javafx.scene.control.test.utils.ptables.PropertyTablesFactory.CustomReversedComparator; 69 import javafx.scene.text.Text; 70 import org.jemmy.Point; 71 import org.jemmy.Rectangle; 72 import org.jemmy.action.GetAction; 73 import org.jemmy.control.Wrap; 74 import org.jemmy.env.Timeout; 75 import org.jemmy.fx.ByStyleClass; 76 import org.jemmy.fx.ByText; 77 import org.jemmy.interfaces.Keyboard.KeyboardButtons; 78 import org.jemmy.interfaces.Keyboard.KeyboardModifiers; 79 import org.jemmy.interfaces.Parent; 80 import org.jemmy.interfaces.Selectable; 81 import org.jemmy.lookup.Lookup; 82 import org.jemmy.lookup.LookupCriteria; 83 import org.jemmy.timing.State; 84 import org.jemmy.timing.Waiter; 85 import static org.junit.Assert.*; 86 import org.junit.Test; 87 import static javafx.scene.control.test.tableview.TableUtils.*; 88 import static javafx.scene.control.test.treetable.TreeTableNewApp.DataItem; 89 import javafx.stage.PopupWindow; 90 import javafx.util.Callback; 91 import org.jemmy.fx.ByWindowType; 92 import org.jemmy.fx.Root; 93 94 /** 95 * @author Alexander Kirov 96 */ 97 public class TableViewNewTest extends ApplicationInteractionFunctions { 98 99 @Test(timeout = 300000) 100 /** 101 * This test will sort content of some column and check, that other columns 102 * were sorted in the way, so that data in the same row is preserved (that 103 * there is no data confusing). 104 */ 105 public void correctSortConsistencyTest() throws InterruptedException { 106 setSize(200, 200); 107 final int columns = 2; 108 final int rows = 5; 109 for (int i = 0; i < columns; i++) { 110 addColumn("items" + String.valueOf(i), i, true); 111 } 112 setNewDataSize(rows); 113 createNestedColumn("nested", 0, 0, 1); 114 requestFocusOnControl(testedControl); 115 116 if (!isTableTests) { 117 new GetAction<Object>() { 118 @Override 119 public void run(Object... os) throws Exception { 120 TreeTableView ttv = (TreeTableView) testedControl.getControl(); 121 ttv.showRootProperty().set(false); 122 } 123 }.dispatch(testedControl.getEnvironment()); 124 } 125 126 switchToPropertiesTab("items0"); 127 setPropertyBySlider(SettingType.UNIDIRECTIONAL, Properties.prefWidth, 80); 128 switchToPropertiesTab("items1"); 129 setPropertyBySlider(SettingType.UNIDIRECTIONAL, Properties.prefWidth, 80); 130 131 Wrap<? extends TableColumnHeader> header1 = getTableColumnHeaderWrap("items0"); 132 Wrap<? extends TableColumnHeader> header2 = getTableColumnHeaderWrap("items1"); 133 134 checkKeyCellsContent("items0-0", "items1-0", "items0-4", "items1-4", columns, rows); 135 //Direct sort. 136 header1.mouse().click(); 137 checkKeyCellsContent("items0-0", "items1-0", "items0-4", "items1-4", columns, rows); 138 //Reversed sort. 139 header1.mouse().click(); 140 checkKeyCellsContent("items0-4", "items1-4", "items0-0", "items1-0", columns, rows); 141 //Direct sort. 142 header2.mouse().click(); 143 checkKeyCellsContent("items0-0", "items1-0", "items0-4", "items1-4", columns, rows); 144 //Reversed sort. 145 header2.mouse().click(); 146 checkKeyCellsContent("items0-4", "items1-4", "items0-0", "items1-0", columns, rows); 147 148 switchToPropertiesTab("items0"); 149 setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.sortable, Boolean.FALSE); 150 151 header1.mouse().click(); 152 checkKeyCellsContent("items0-4", "items1-4", "items0-0", "items1-0", columns, rows); 153 154 switchToPropertiesTab("items1"); 155 setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.sortable, Boolean.FALSE); 156 header2.mouse().click(); 157 checkKeyCellsContent("items0-4", "items1-4", "items0-0", "items1-0", columns, rows); 158 } 159 160 protected void checkKeyCellsContent(String upperLeftText, String upperRightText, String downLeftText, String downRightText, int columns, int rows) { 161 checkTextContainment(getCellWrap(0, 0), upperLeftText); 162 checkTextContainment(getCellWrap(columns - 1, 0), upperRightText); 163 checkTextContainment(getCellWrap(0, rows - 1), downLeftText); 164 checkTextContainment(getCellWrap(columns - 1, rows - 1), downRightText); 165 } 166 167 protected void checkTextContainment(final Wrap<? extends TableCell> cellWrap, final String textExpectToFind) { 168 new Waiter(new Timeout("", 1000)).ensureState(new State() { 169 public Object reached() { 170 LookupCriteria<Node> lookupCriteria = new LookupCriteria<Node>() { 171 public boolean check(Node cntrl) { 172 return Text.class.isAssignableFrom(cntrl.getClass()) 173 || ((Text) cntrl).getText().equals(textExpectToFind); 174 } 175 }; 176 177 if (cellWrap.as(Parent.class, Node.class).lookup(Text.class, new ByText(textExpectToFind)).size() == 1) { 178 return true; 179 } else if (cellWrap.as(Parent.class, Node.class).lookup(lookupCriteria).size() == 1) { 180 return true; 181 } else { 182 return null; 183 } 184 185 } 186 }); 187 } 188 189 @Test(timeout = 300000) 190 /** 191 * When you scroll (in horizontal dimension) to some column, and sort it, 192 * then scrolling will be dropped. This test checks, that scrolling will be 193 * preserved after sorting. 194 */ 195 public void tableViewNotScrollingOnSortTest() throws InterruptedException { 196 setSize(200, 200); 197 int count = 10; 198 for (int i = 0; i < count; i++) { 199 addColumn("items" + String.valueOf(i), i); 200 } 201 setNewDataSize(25); 202 switchToPropertiesTab("TreeTableView"); 203 setPropertyBySlider(SettingType.UNIDIRECTIONAL, Properties.prefWidth, 170); 204 setPropertyBySlider(SettingType.UNIDIRECTIONAL, Properties.prefHeight, 170); 205 206 for (int i = 0; i < count; i++) { 207 checkSortNotScrollingFor("items" + String.valueOf(i), i); 208 } 209 } 210 211 private void checkSortNotScrollingFor(String name, int index) { 212 scrollTo(index, 0); 213 final double initialScrollPos = getScrollBarValue(findScrollBar(testedControl.as(Parent.class, Node.class), Orientation.HORIZONTAL, true)); 214 getTableColumnHeaderWrap(name).mouse().click(); 215 getTableColumnHeaderWrap(name).mouse().click(); 216 getTableColumnHeaderWrap(name).mouse().click(); 217 getTableColumnHeaderWrap(name).mouse().click(); 218 new Waiter(new Timeout("", 500)).ensureState(new State() { 219 public Object reached() { 220 if (Math.abs(initialScrollPos - getScrollBarValue(findScrollBar(testedControl.as(Parent.class, Node.class), Orientation.HORIZONTAL, true))) < 0.001) { 221 return true; 222 } else { 223 return null; 224 } 225 } 226 }); 227 } 228 229 @Test(timeout = 300000) 230 /** 231 * This test applies new sortNode and checks, that it was applied. 232 */ 233 public void actualChangeSortNodeTest() throws InterruptedException { 234 setSize(200, 200); 235 String columnName = "column1"; 236 addColumn(columnName, 0, true); 237 setNewDataSize(10); 238 requestFocusOnControl(testedControl); 239 240 final Wrap<? extends TableColumnHeader> header = getTableColumnHeaderWrap(columnName); 241 final Rectangle columnNameCoords = header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds(); 242 243 switchToPropertiesTab(columnName); 244 selectObjectFromChoiceBox(SettingType.SETTER, Properties.sortNode, javafx.scene.shape.Rectangle.class); 245 246 //Direct sort. 247 header.mouse().click(); 248 new Waiter(new Timeout("", 500)).ensureState(new State() { 249 public Object reached() { 250 if (!(header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds().equals(columnNameCoords))) { 251 return true; 252 } else { 253 return null; 254 } 255 } 256 }); 257 checkRectanglesRelation(header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds(), RectanglesRelations.LEFTER, 258 header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).wrap().getScreenBounds()); 259 new Waiter(new Timeout("", 500)).ensureState(new State() { 260 public Object reached() { 261 if (header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).size() == 1) { 262 return true; 263 } else { 264 return null; 265 } 266 } 267 }); 268 269 //Reversed sort. 270 header.mouse().click(); 271 new Waiter(new Timeout("", 500)).ensureState(new State() { 272 public Object reached() { 273 if (!(header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds().equals(columnNameCoords))) { 274 return true; 275 } else { 276 return null; 277 } 278 } 279 }); 280 281 checkRectanglesRelation(header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds(), RectanglesRelations.LEFTER, 282 header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).wrap().getScreenBounds()); 283 284 new Waiter(new Timeout("", 500)).ensureState(new State() { 285 public Object reached() { 286 if (header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).size() == 1) { 287 return true; 288 } else { 289 return null; 290 } 291 } 292 }); 293 294 //Unsort. 295 header.mouse().click(); 296 new Waiter(new Timeout("", 500)).ensureState(new State() { 297 public Object reached() { 298 if (header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds().equals(columnNameCoords)) { 299 return true; 300 } else { 301 return null; 302 } 303 } 304 }); 305 306 new Waiter(new Timeout("", 500)).ensureState(new State() { 307 public Object reached() { 308 if (header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).size() == 0) { 309 return true; 310 } else { 311 return null; 312 } 313 } 314 }); 315 } 316 317 @Test(timeout = 300000) 318 /** 319 * This test checks, that using different types of setting or binding, 320 * sortNode can be set. Standart property test. 321 */ 322 public void sortNodePropertyTest() throws InterruptedException { 323 assertNull(new TableColumn().getSortNode()); 324 setSize(200, 200); 325 String columnName = "column1"; 326 addColumn(columnName, 0, true); 327 setNewDataSize(10); 328 requestFocusOnControl(testedControl); 329 switchToPropertiesTab(columnName); 330 331 selectObjectFromChoiceBox(SettingType.SETTER, Properties.sortNode, javafx.scene.shape.Rectangle.class); 332 checkTextFieldTextContaining(Properties.sortNode, "Rectangle"); 333 334 selectObjectFromChoiceBox(SettingType.BIDIRECTIONAL, Properties.sortNode, Text.class); 335 checkTextFieldTextContaining(Properties.sortNode, "Text"); 336 337 selectObjectFromChoiceBox(SettingType.UNIDIRECTIONAL, Properties.sortNode, Group.class); 338 checkTextFieldTextContaining(Properties.sortNode, "Group"); 339 } 340 341 @Test(timeout = 300000) 342 /** 343 * This test checks, that sort node is applied right at the same moment, as 344 * it was set. 345 */ 346 public void sortNodeImmidiateApplying() throws InterruptedException { 347 setSize(200, 200); 348 String columnName = "column1"; 349 addColumn(columnName, 0, true); 350 setNewDataSize(10); 351 requestFocusOnControl(testedControl); 352 switchToPropertiesTab(columnName); 353 354 //Direct sort. 355 Wrap<? extends TableColumnHeader> header = getTableColumnHeaderWrap(columnName); 356 header.mouse().click(); 357 358 assertTrue(header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).size() == 0); 359 360 selectObjectFromChoiceBox(SettingType.SETTER, Properties.sortNode, javafx.scene.shape.Rectangle.class); 361 assertTrue(header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).size() == 1); 362 header.mouse().click(); 363 assertTrue(header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).size() == 1); 364 selectObjectFromChoiceBox(SettingType.SETTER, Properties.sortNode, null); 365 assertTrue(header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).size() == 0); 366 selectObjectFromChoiceBox(SettingType.BIDIRECTIONAL, Properties.sortNode, javafx.scene.shape.Rectangle.class); 367 assertTrue(header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).size() == 1); 368 } 369 370 @Test(timeout = 300000) 371 /** 372 * This test checks, that if comparator is set, then it is applied 373 * immediately. 374 */ 375 public void comparatorPropertyImmidiateAndCorrectApplyingTest() throws InterruptedException { 376 setSize(200, 200); 377 final int columns = 2; 378 final int rows = 5; 379 for (int i = 0; i < columns; i++) { 380 addColumn("items" + String.valueOf(i), i, true); 381 } 382 setNewDataSize(rows); 383 384 createNestedColumn("nested", 0, 0, 1); 385 requestFocusOnControl(testedControl); 386 387 if (!isTableTests) { 388 switchToPropertiesTab("ROOT"); 389 setPropertyByToggleClick(SettingType.SETTER, Properties.expanded, true); 390 } 391 392 Wrap<? extends TableColumnHeader> header1 = getTableColumnHeaderWrap("items0"); 393 394 checkKeyCellsContent("items0-0", "items1-0", "items0-4", "items1-4", columns, rows); 395 //Direct sort. 396 header1.mouse().click(); 397 checkKeyCellsContent("items0-0", "items1-0", "items0-4", "items1-4", columns, rows); 398 switchToPropertiesTab("items0"); 399 //Change comparator to reversed one. 400 selectObjectFromChoiceBox(SettingType.SETTER, Properties.comparator, CustomReversedComparator.class); 401 checkTextFieldText(Properties.comparator, CustomReversedComparator.comparatorName); 402 //Expect, that reversed sorting will be applied. 403 checkKeyCellsContent("items0-4", "items1-4", "items0-0", "items1-0", columns, rows); 404 header1.mouse().click(); 405 //Expect, that ascending sorting will be applied. 406 checkKeyCellsContent("items0-0", "items1-0", "items0-4", "items1-4", columns, rows); 407 } 408 409 @Test(timeout = 300000) 410 /** 411 * Checks, that comparator property can be set by setter or any of bindings. 412 * That is a standard test. 413 */ 414 public void comparatorPropertyTest() throws InterruptedException { 415 assertTrue(new TableColumn().getComparator().getClass().equals(TableColumn.DEFAULT_COMPARATOR.getClass())); 416 setSize(200, 200); 417 final int rows = 5; 418 addColumn("items0", 0, true); 419 setNewDataSize(rows); 420 421 switchToPropertiesTab("items0"); 422 Wrap<? extends TableColumnHeader> header1 = getTableColumnHeaderWrap("items0"); 423 header1.mouse().click(); 424 checkKeyCellsContent("items0-0", "items0-4", rows); 425 selectObjectFromChoiceBox(SettingType.SETTER, Properties.comparator, CustomReversedComparator.class); 426 checkTextFieldText(Properties.comparator, CustomReversedComparator.comparatorName); 427 checkKeyCellsContent("items0-4", "items0-0", rows); 428 selectObjectFromChoiceBox(SettingType.UNIDIRECTIONAL, Properties.comparator, CustomReversedComparator.class); 429 checkTextFieldText(Properties.comparator, CustomReversedComparator.comparatorName); 430 checkKeyCellsContent("items0-0", "items0-4", rows); 431 } 432 433 protected void checkKeyCellsContent(String upperText, String downText, int rows) { 434 checkTextContainment(getCellWrap(0, 0), upperText); 435 checkTextContainment(getCellWrap(0, rows - 1), downText); 436 } 437 438 @Test(timeout = 300000) 439 /** 440 * Standard test on graphic property: setting with setter, bidirectional of 441 * unidirectional binding, checking with getter. 442 */ 443 public void graphicPropertyTest() throws InterruptedException { 444 assertNull(new TableColumn().getGraphic()); 445 setSize(200, 200); 446 addColumn("items0", 0, true); 447 setNewDataSize(5); 448 449 switchToPropertiesTab("items0"); 450 final Wrap<? extends TableColumnHeader> header = getTableColumnHeaderWrap("items0"); 451 final Rectangle initialColumnNameCoords = header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds(); 452 453 selectObjectFromChoiceBox(SettingType.SETTER, Properties.graphic, javafx.scene.shape.Rectangle.class); 454 checkTextFieldTextContaining(Properties.graphic, "Rectangle"); 455 new Waiter(new Timeout("", 500)).ensureState(new State() { 456 public Object reached() { 457 if (!(header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds().equals(initialColumnNameCoords)) 458 && header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).size() == 1) { 459 return true; 460 } else { 461 return null; 462 } 463 } 464 }); 465 checkRectanglesRelation(header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds(), RectanglesRelations.RIGHTER, 466 header.as(Parent.class, Node.class).lookup(javafx.scene.shape.Rectangle.class).wrap().getScreenBounds()); 467 468 selectObjectFromChoiceBox(SettingType.BIDIRECTIONAL, Properties.graphic, Group.class); 469 checkTextFieldTextContaining(Properties.graphic, "Group"); 470 new Waiter(new Timeout("", 500)).ensureState(new State() { 471 public Object reached() { 472 if (!(header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds().equals(initialColumnNameCoords)) 473 && header.as(Parent.class, Node.class).lookup(Group.class).size() == 1) { 474 return true; 475 } else { 476 return null; 477 } 478 } 479 }); 480 checkRectanglesRelation(header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds(), RectanglesRelations.RIGHTER, 481 header.as(Parent.class, Node.class).lookup(Group.class).wrap().getScreenBounds()); 482 483 selectObjectFromChoiceBox(SettingType.UNIDIRECTIONAL, Properties.graphic, null); 484 checkTextFieldText(Properties.graphic, "null"); 485 new Waiter(new Timeout("", 500)).ensureState(new State() { 486 public Object reached() { 487 488 if ((header.as(Parent.class, Node.class).lookup(Text.class).wrap().getScreenBounds().equals(initialColumnNameCoords)) 489 && header.as(Parent.class, Node.class).lookup(Group.class).size() == 0) { 490 return true; 491 } else { 492 return null; 493 } 494 } 495 }); 496 } 497 498 @Test(timeout = 300000) 499 public void reorderablePropertyTest() throws InterruptedException { 500 final String ITEMS_0 = "items0"; 501 final String ITEMS_1 = "items1"; 502 503 setSize(200, 200); 504 addColumn(ITEMS_0, 0, true); 505 addColumn(ITEMS_1, 1, true); 506 setNewDataSize(5); 507 508 Wrap columnHeader1 = testedControl.as(Parent.class, Node.class).lookup(Text.class, new ByText(ITEMS_0)).wrap(); 509 Wrap columnHeader2 = testedControl.as(Parent.class, Node.class).lookup(Text.class, new ByText(ITEMS_1)).wrap(); 510 511 switchToPropertiesTab(ITEMS_0); 512 setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.reorderable, false); 513 checkTextFieldText(Properties.reorderable, "false"); 514 columnHeader1.drag().dnd(columnHeader2, columnHeader2.getClickPoint()); 515 assertTrue(columnHeader1.getScreenBounds().x < columnHeader2.getScreenBounds().x); 516 517 setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.reorderable, true); 518 checkTextFieldText(Properties.reorderable, "true"); 519 columnHeader1.drag().dnd(columnHeader2, columnHeader2.getClickPoint().translate(5, 0)); 520 521 columnHeader1 = testedControl.as(Parent.class, Node.class).lookup(Text.class, new ByText(ITEMS_0)).wrap(); 522 columnHeader2 = testedControl.as(Parent.class, Node.class).lookup(Text.class, new ByText(ITEMS_1)).wrap(); 523 assertTrue(columnHeader1.getScreenBounds().x > columnHeader2.getScreenBounds().x); 524 } 525 526 @Test(timeout = 300000) 527 /** 528 * Standard test on resizable property test. Checked with getter, setter, 529 * initial value, bindings, behavior is checked too. Checked for resizing of 530 * nested columns and for autosizing cases. 531 */ 532 public void resizablePropertyTest() throws InterruptedException { 533 if (isTableTests) { 534 assertTrue(new TableColumn().isResizable()); 535 } else { 536 assertTrue(new TreeTableColumn().isResizable()); 537 } 538 setSize(200, 200); 539 addColumn("items0", 0, true); 540 addColumn("items1", 1, true); 541 createNestedColumn("nested", 0, 0, 1); 542 setNewDataSize(5); 543 544 final Wrap<? extends TableColumnHeader> items0 = getTableColumnHeaderWrap("items0"); 545 final Wrap<? extends TableColumnHeader> nested = getTableColumnHeaderWrap("nested"); 546 547 switchToPropertiesTab("items0"); 548 checkTextFieldValue(Properties.width, 80, 1); 549 switchToPropertiesTab("nested"); 550 checkTextFieldValue(Properties.width, 160, 1); 551 552 switchToPropertiesTab("items0"); 553 setPropertyByToggleClick(SettingType.SETTER, Properties.resizable, false); 554 checkTextFieldText(Properties.resizable, "false"); 555 DnDInHorizontalDimnsion(getColumnResizablePoint(items0), 10); 556 checkTextFieldValue(Properties.width, 80, 1); 557 DnDInHorizontalDimnsion(getColumnResizablePoint(nested), 10); 558 checkTextFieldValue(Properties.width, 80, 1); 559 switchToPropertiesTab("nested"); 560 checkTextFieldValue(Properties.width, 170, 1); 561 562 switchToPropertiesTab("items0"); 563 setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.resizable, true); 564 checkTextFieldText(Properties.resizable, "true"); 565 DnDInHorizontalDimnsion(getColumnResizablePoint(items0), -10); 566 checkTextFieldValue(Properties.width, 70, 1); 567 DnDInHorizontalDimnsion(getColumnResizablePoint(nested), -10); 568 checkTextFieldValue(Properties.width, 65, 3); 569 switchToPropertiesTab("nested"); 570 checkTextFieldValue(Properties.width, 160, 1); 571 572 switchToPropertiesTab("items0"); 573 setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.resizable, false); 574 checkTextFieldText(Properties.resizable, "false"); 575 DnDInHorizontalDimnsion(getColumnResizablePoint(items0), 10); 576 checkTextFieldValue(Properties.width, 65, 1); 577 DnDInHorizontalDimnsion(getColumnResizablePoint(nested), 10); 578 checkTextFieldValue(Properties.width, 65, 3); 579 switchToPropertiesTab("nested"); 580 checkTextFieldValue(Properties.width, 170, 1); 581 582 switchToPropertiesTab("items0"); 583 setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.resizable, true); 584 checkTextFieldText(Properties.resizable, "true"); 585 DnDInHorizontalDimnsion(getColumnResizablePoint(items0), 50); 586 587 Point endPoint = getColumnResizablePoint(items0); 588 setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.resizable, false); 589 checkTextFieldText(Properties.resizable, "false"); 590 items0.mouse().click(1, getColumnResizablePoint(items0)); 591 items0.mouse().click(1, getColumnResizablePoint(items0)); 592 //Expect, that width doesn't change even on request of autosizing. Issue RT-25###. 593 assertTrue(endPoint.equals(getColumnResizablePoint(items0))); 594 } 595 596 protected Point getColumnResizablePoint(Wrap<? extends TableColumnHeader> wrap) { 597 return new Point(wrap.getScreenBounds().getX() + wrap.getScreenBounds().width, wrap.getScreenBounds().getY() + wrap.getScreenBounds().height / 2); 598 } 599 600 protected void DnDInHorizontalDimnsion(Point initialPoint, int movement) throws InterruptedException, InterruptedException { 601 try { 602 Point point = new Point(initialPoint.x + movement, initialPoint.y); 603 Robot robot = new Robot(); 604 robot.mouseMove(initialPoint.x, initialPoint.y); 605 robot.mousePress(InputEvent.BUTTON1_MASK); 606 Thread.sleep(100); 607 final int STEPS = 20; 608 int differenceX = point.x - initialPoint.x; 609 int differenceY = point.y - initialPoint.y; 610 for (int i = 0; i <= STEPS; i++) { 611 robot.mouseMove(initialPoint.x + differenceX * i / STEPS, initialPoint.y + differenceY * i / STEPS); 612 Thread.sleep(20); 613 } 614 robot.mouseRelease(InputEvent.BUTTON1_MASK); 615 Thread.sleep(SLEEP); 616 } catch (Exception ex) { 617 Logger.getLogger(TableViewNewTest.class.getName()).log(Level.SEVERE, null, ex); 618 } 619 } 620 621 @Test(timeout = 300000) 622 /** 623 * Test on width property - readonly one. Check correct behavior on resizing 624 * for simple and nested columns 625 */ 626 public void widthPropertyTest() throws InterruptedException { 627 setSize(200, 200); 628 addColumn("items0", 0, true); 629 addColumn("items1", 1, true); 630 createNestedColumn("nested", 0, 0, 1); 631 setNewDataSize(5); 632 633 // final Wrap<? extends TableColumnHeader> items0 = getTableColumnHeaderWrap("items0"); 634 // final Wrap<? extends TableColumnHeader> items1 = getTableColumnHeaderWrap("items1"); 635 // final Wrap<? extends TableColumnHeader> nested = getTableColumnHeaderWrap("nested"); 636 switchToPropertiesTab("items0"); 637 checkTextFieldValue(Properties.width, 80, 1); 638 switchToPropertiesTab("items1"); 639 checkTextFieldValue(Properties.width, 80, 1); 640 switchToPropertiesTab("nested"); 641 checkTextFieldValue(Properties.width, 160, 1); 642 643 DnDInHorizontalDimnsion(getResizingPointOfColumn("nested"), +20); 644 switchToPropertiesTab("items0"); 645 checkTextFieldValue(Properties.width, 90, 1); 646 switchToPropertiesTab("items1"); 647 checkTextFieldValue(Properties.width, 90, 1); 648 switchToPropertiesTab("nested"); 649 checkTextFieldValue(Properties.width, 180, 1); 650 651 DnDInHorizontalDimnsion(getResizingPointOfColumn("items0"), -20); 652 switchToPropertiesTab("items0"); 653 checkTextFieldValue(Properties.width, 70, 1); 654 switchToPropertiesTab("items1"); 655 checkTextFieldValue(Properties.width, 90, 1); 656 switchToPropertiesTab("nested"); 657 checkTextFieldValue(Properties.width, 160, 1); 658 } 659 660 @Test(timeout = 300000) 661 /** 662 * This test checks, that TableCell are resized correctly according to the 663 * resizing of the tableColumnHeaders. That is, if you resize headers, do 664 * autosizing, at least left and right borders have the same x-coordinates 665 * as columnHeaders have. 666 */ 667 public void correctAllocationOnResizingTest() throws InterruptedException { 668 setSize(210, 210); 669 addColumn("items0", 0, true); 670 addColumn("items1", 1, true); 671 createNestedColumn("nested", 0, 0, 1); 672 final int rows = 5; 673 setNewDataSize(rows); 674 675 final Wrap<? extends TableColumnHeader> items0 = getTableColumnHeaderWrap("items0"); 676 final Wrap<? extends TableColumnHeader> items1 = getTableColumnHeaderWrap("items1"); 677 checkCorrectCoordinatesAllocation(items0, items1, rows + (isTableTests ? 0 : 1)); 678 679 DnDInHorizontalDimnsion(getResizingPointOfColumn("nested"), +20); 680 checkCorrectCoordinatesAllocation(items0, items1, rows); 681 682 DnDInHorizontalDimnsion(getResizingPointOfColumn("items1"), +20); 683 checkCorrectCoordinatesAllocation(items0, items1, rows); 684 685 DnDInHorizontalDimnsion(getResizingPointOfColumn("items0"), -20); 686 checkCorrectCoordinatesAllocation(items0, items1, rows); 687 688 Point colResizablePoint = items1.toLocal(getColumnResizablePoint(items1)); 689 690 items1.mouse().click(1, colResizablePoint); 691 items1.mouse().click(1, colResizablePoint); 692 693 checkCorrectCoordinatesAllocation(items0, items1, rows); 694 } 695 696 /** 697 * Checks the state of control after removing all its observable data. 698 */ 699 @Test(timeout = 300000) 700 public void testAllDataRemoving() throws Throwable { 701 final int COLS = 4; 702 final int ROWS = 10; 703 final String noContent = isTableTests ? "TableView_no_content" : "TreeTableView_no_content"; 704 final String noColumns = isTableTests ? "TableView_no_columns" : "TreeTableView_no_columns"; 705 706 setSize(200, 200); 707 708 if (!isTableTests) { 709 setPropertyByToggleClick(SettingType.SETTER, Properties.showRoot, false); 710 } 711 712 checkScreenshot(noColumns, testedControl); 713 714 for (boolean bulkClear : new boolean[]{true, false}) { 715 716 for (int i = 0; i < COLS; i++) { 717 addColumn(String.format("column%d", i), i, true); 718 } 719 720 checkScreenshot(noContent, testedControl); 721 722 if (bulkClear) { 723 new GetAction<Object>() { 724 public void run(Object... parameters) throws Exception { 725 if (isTableTests) { 726 ((TableView) testedControl.getControl()).getColumns().clear(); 727 } else { 728 ((TreeTableView) testedControl.getControl()).getColumns().clear(); 729 } 730 } 731 }.dispatch(testedControl.getEnvironment()); 732 } else { 733 for (int i = COLS - 1; i >= 0; --i) { 734 removeColumns(i); 735 } 736 } 737 738 checkScreenshot(noColumns, testedControl); 739 } 740 741 for (int i = 0; i < COLS; i++) { 742 addColumn(String.format("column%d", i), i, true); 743 } 744 745 setNewDataSize(ROWS); 746 747 new GetAction<Object>() { 748 @Override 749 public void run(Object... os) throws Exception { 750 Control control = testedControl.getControl(); 751 752 if (isTableTests) { 753 TableView tv = (TableView) control; 754 tv.getItems().clear(); 755 } else { 756 TreeTableView ttv = (TreeTableView) control; 757 ttv.getRoot().getChildren().clear(); 758 } 759 } 760 }.dispatch(testedControl.getEnvironment()); 761 762 //Wait for animation to finish 763 try { 764 Thread.sleep(100); 765 } catch (Exception e) { 766 } 767 768 checkScreenshot(noContent, testedControl); 769 770 for (int i = COLS - 1; i >= 0; --i) { 771 removeColumns(i); 772 } 773 774 checkScreenshot(noColumns, testedControl); 775 776 throwScreenshotError(); 777 } 778 779 @Test(timeout = 300000) 780 public void columnHeaderAndRowCustomisation() throws InterruptedException { 781 setSize(200, 200); 782 addColumn("items0", 0, true); 783 addColumn("items1", 1, true); 784 createNestedColumn("nested", 0, 0, 1); 785 setNewDataSize(5); 786 787 checkHeaderCustomizedState(false); 788 789 clickButtonForTestPurpose(javafx.commons.Consts.REPLACE_SKIN_IMPLEMENTATION_BUTTON_ID); 790 791 checkHeaderCustomizedState(true); 792 } 793 794 private void checkHeaderCustomizedState(final boolean isCustomized) { 795 Lookup<TableColumnHeader> headers = testedControl.as(Parent.class, Node.class).lookup(TableColumnHeader.class); 796 Wrap<TableHeaderRow> headerRow = testedControl.as(Parent.class, Node.class).lookup(TableHeaderRow.class).wrap(); 797 798 for (int i = 0; i < headers.size(); i++) { 799 final String columnHeaderId = getId(headers.wrap(i)); 800 801 testedControl.waitState(new State() { 802 public Object reached() { 803 final String expectedId = isCustomized ? javafx.commons.Consts.CUSTOM_IMPLEMENTATION_MARKER : null; 804 if (expectedId == null) { 805 if (columnHeaderId == null) { 806 return Boolean.TRUE; 807 } else { 808 return null; 809 } 810 } else { 811 return expectedId.equals(columnHeaderId); 812 } 813 } 814 }); 815 } 816 817 final String headerRowId = getId(headerRow); 818 testedControl.waitState(new State() { 819 public Object reached() { 820 final String expectedId = isCustomized ? javafx.commons.Consts.CUSTOM_IMPLEMENTATION_MARKER : null; 821 if (expectedId == null) { 822 if (headerRowId == null) { 823 return Boolean.TRUE; 824 } else { 825 return null; 826 } 827 } else { 828 return expectedId.equals(headerRowId); 829 } 830 } 831 }); 832 } 833 834 private String getId(final Wrap<? extends Node> node) { 835 return new GetAction<String>() { 836 @Override 837 public void run(Object... os) throws Exception { 838 setResult(node.getControl().getId()); 839 } 840 }.dispatch(Root.ROOT.getEnvironment()); 841 } 842 843 /** 844 * Checks control behavior when sortOrder list is changed. 845 */ 846 @Test(timeout = 300000) 847 public void testSortOrderAPI() throws InterruptedException { 848 testSortTypeCombinations(false); 849 } 850 851 @Test(timeout = 300000) 852 public void testOnEditStartCancel() throws InterruptedException { 853 testDifferentCellEditors(false); 854 } 855 856 @Test(timeout = 300000) 857 public void testOnEditStartCommit() throws InterruptedException { 858 testDifferentCellEditors(true); 859 } 860 861 /** 862 * Tests that sorting in column may be disabled via the API. 863 */ 864 @Test(timeout = 380000) 865 public void columnSortablePropertyTest() throws InterruptedException { 866 testSortTypeCombinations(true); 867 } 868 869 /** 870 * Tests, that cells/rows correctly answer on a question about row, column, 871 * and control. 872 */ 873 @Test(timeout = 300000) 874 public void columnPropertyOfCellTest() throws InterruptedException { 875 setSize(210, 210); 876 addColumn("items0", 0, false); 877 addColumn("items1", 1, false); 878 final int rows = 5; 879 setNewDataSize(rows); 880 881 Class<?> rowClass = isTableTests ? TableRow.class : TreeTableRow.class; 882 Class<?> cellClass = isTableTests ? TableCell.class : TreeTableCell.class; 883 List<Cell> allCells = new ArrayList<Cell>(); 884 final Control control = testedControl.getControl(); 885 List<TableColumnBase> columns = new GetAction<List<TableColumnBase>>() { 886 @Override 887 public void run(Object... os) throws Exception { 888 if (isTableTests) { 889 setResult(((TableView) control).getColumns()); 890 } else { 891 setResult(((TreeTableView) control).getColumns()); 892 } 893 } 894 }.dispatch(Root.ROOT.getEnvironment()); 895 896 final Lookup<?> rowsLookup = testedControl.as(Parent.class, Node.class).lookup(rowClass); 897 for (int i = 0; i < rowsLookup.size(); i++) { 898 Wrap<?> rowWrap = rowsLookup.wrap(i); 899 final Object row = rowWrap.getControl(); 900 Control controlResRow = new GetAction<Control>() { 901 @Override 902 public void run(Object... os) throws Exception { 903 if (isTableTests) { 904 setResult(((TableRow) row).getTableView()); 905 } else { 906 setResult(((TreeTableRow) row).getTreeTableView()); 907 } 908 } 909 }.dispatch(Root.ROOT.getEnvironment()); 910 assertEquals(controlResRow, control); 911 912 final Lookup<Cell> cellsInRowLookup = rowWrap.as(Parent.class, Node.class).lookup(Cell.class); 913 for (int j = 0; j < cellsInRowLookup.size(); j++) { 914 Object rowRes = new GetAction<Object>() { 915 @Override 916 public void run(Object... os) throws Exception { 917 if (isTableTests) { 918 setResult(((TableCell) os[0]).getTableRow()); 919 } else { 920 setResult(((TreeTableCell) os[0]).getTreeTableRow()); 921 } 922 } 923 }.dispatch(Root.ROOT.getEnvironment(), cellsInRowLookup.get(j)); 924 assertEquals(rowRes, row); 925 926 Control controlRes = new GetAction<Control>() { 927 @Override 928 public void run(Object... os) throws Exception { 929 if (isTableTests) { 930 setResult(((TableCell) os[0]).getTableView()); 931 } else { 932 setResult(((TreeTableCell) os[0]).getTreeTableView()); 933 } 934 } 935 }.dispatch(Root.ROOT.getEnvironment(), cellsInRowLookup.get(j)); 936 assertEquals(controlRes, control); 937 938 TableColumnBase column = new GetAction<TableColumnBase>() { 939 @Override 940 public void run(Object... os) throws Exception { 941 if (isTableTests) { 942 setResult(((TableCell) os[0]).getTableColumn()); 943 } else { 944 setResult(((TreeTableCell) os[0]).getTableColumn()); 945 } 946 } 947 }.dispatch(Root.ROOT.getEnvironment(), cellsInRowLookup.get(j)); 948 assertEquals(column, columns.get(j)); 949 950 allCells.add(cellsInRowLookup.get(j)); 951 } 952 } 953 954 assertEquals(testedControl.as(Parent.class, Node.class).lookup(cellClass).size(), allCells.size()); 955 assertTrue(allCells.size() >= 2 * rows); 956 } 957 958 /** 959 * Checks that when columns collection is ordered it will be rendered 960 * properly. 961 */ 962 @Test(timeout = 300000) 963 public void columnsOrderTest() throws InterruptedException { 964 setSize(210, 210); 965 final int COLS = 3; 966 final int ROWS = 5; 967 968 setNewDataSize(ROWS); 969 970 final String[] names = new String[]{"A", "B", "C"}; 971 972 for (String n : names) { 973 addColumn(n, 0); 974 } 975 976 if (isTableTests) { 977 checkKeyCellsContent("C-0", "A-0", "C-4", "A-4", COLS, ROWS); 978 } else { 979 setShowRoot(false); 980 checkKeyCellsContent("C-1", "A-1", "C-5", "A-5", COLS, ROWS); 981 } 982 983 sortColumnsByName(true); 984 985 if (isTableTests) { 986 checkKeyCellsContent("A-0", "C-0", "A-4", "C-4", COLS, ROWS); 987 } else { 988 checkKeyCellsContent("A-1", "C-1", "A-5", "C-5", COLS, ROWS); 989 } 990 991 //check column headers 992 final Lookup<TableColumnHeader> lookup = testedControl.waitState(new State<Lookup<TableColumnHeader>>() { 993 public Lookup reached() { 994 final Lookup lookup = parent.lookup(TableColumnHeader.class, new LookupCriteria<TableColumnHeader>() { 995 public boolean check(TableColumnHeader cntrl) { 996 return (cntrl.getBoundsInLocal().getMaxY() > 15) && (!(cntrl instanceof NestedTableColumnHeader)); 997 } 998 }); 999 1000 return (lookup.size() == 3) ? lookup : null; 1001 } 1002 1003 @Override 1004 public String toString() { 1005 return "[Correct number of column headers]"; 1006 } 1007 }); 1008 1009 for (int i = 0; i < lookup.size(); i++) { 1010 final int x = i; 1011 1012 assertEquals(names[i], new GetAction<String>() { 1013 @Override 1014 public void run(Object... os) throws Exception { 1015 setResult(((Label) lookup.wrap(x).getControl().getChildrenUnmodifiable().get(0)).getText()); 1016 } 1017 }.dispatch(testedControl.getEnvironment())); 1018 } 1019 } 1020 1021 /** 1022 * Checks the public 'sort' method and 'onSort' event. Features are 1023 * described here: 1024 * <a href="http://javafx-jira.kenai.com/browse/RT-26505">RT-19482</a> 1025 * and here <a 1026 * href="http://javafx-jira.kenai.com/browse/RT-26505">RT-17550</a> 1027 */ 1028 @Test(timeout = 300000) 1029 public void onSortTest() throws InterruptedException { 1030 setSize(250, 250); 1031 final int COLS = 3; 1032 1033 createRowsForSortPurposes(COLS); 1034 String[][] testData = NewTableViewApp.getDataForSorting(COLS); 1035 1036 checkCounterValue(COUNTER_ON_SORT, 0); 1037 1038 new GetAction<Void>() { 1039 @Override 1040 public void run(Object... os) throws Exception { 1041 if (isTableTests) { 1042 ((TableView) testedControl.getControl()).setSortPolicy(getAlwaysReverseTableSortPolicy()); 1043 } else { 1044 Callback<TreeTableView<DataItem>, Boolean> treeTableSortPolicy = getAlwaysReverseTreeTableSortPolicy(); 1045 ((TreeTableView) testedControl.getControl()).setSortPolicy(treeTableSortPolicy); 1046 } 1047 } 1048 }.dispatch(testedControl.getEnvironment()); 1049 1050 checkCounterValue(COUNTER_ON_SORT, 1); 1051 reverseTestData(testData); 1052 assertTrue("Sort order is wrong", checkSortResult(testData)); 1053 1054 createRowsForSortPurposes(COLS); 1055 testData = NewTableViewApp.getDataForSorting(COLS); 1056 assertTrue("Sort order is wrong", checkSortResult(testData)); 1057 1058 new GetAction<Void>() { 1059 @Override 1060 public void run(Object... os) throws Exception { 1061 if (isTableTests) { 1062 ((TableView) testedControl.getControl()).sort(); 1063 } else { 1064 ((TreeTableView) testedControl.getControl()).sort(); 1065 } 1066 } 1067 }.dispatch(testedControl.getEnvironment()); 1068 1069 reverseTestData(testData); 1070 checkCounterValue(COUNTER_ON_SORT, 2); 1071 assertTrue("Sort order is wrong", checkSortResult(testData)); 1072 } 1073 1074 /** 1075 * Checks the returning to the unsorted state. 1076 * Feature is described here: <a href="https://javafx-jira.kenai.com/browse/RT-19487">RT-19487</a> 1077 */ 1078 @Test(timeout = 60000) 1079 public void SortedListAsModel() throws InterruptedException { 1080 if (!isTableTests) { 1081 return;//pass all the time as this feature is not applicable to the tree table. 1082 } 1083 setSize(250, 250); 1084 1085 final int COLS = 3; 1086 1087 createRowsForSortPurposes(COLS); 1088 1089 clickButtonForTestPurpose(BTN_SET_SORTED_LIST_FOR_MODEL_ID); 1090 1091 String[][] testData = NewTableViewApp.getDataForSorting(COLS); 1092 1093 List<ColumnState> columnStates = new ArrayList<ColumnState>(COLS); 1094 1095 //Ascending 1096 getTableColumnHeaderWrap("column 2").mouse().click(); 1097 columnStates.add(new ColumnState(2, ColumnState.SortType.ASCENDING)); 1098 sortTestData(testData, columnStates); 1099 assertTrue("Sort order is wrong", checkSortResult(testData)); 1100 1101 //Descending 1102 getTableColumnHeaderWrap("column 2").mouse().click(); 1103 columnStates.clear(); 1104 columnStates.add(new ColumnState(2, ColumnState.SortType.DESCENDING)); 1105 sortTestData(testData, columnStates); 1106 assertTrue("Sort order is wrong", checkSortResult(testData)); 1107 1108 //Initial state 1109 getTableColumnHeaderWrap("column 2").mouse().click(); 1110 testData = NewTableViewApp.getDataForSorting(COLS); 1111 assertTrue("Sort order is wrong", checkSortResult(testData)); 1112 } 1113 1114 /* 1115 * Helper methods 1116 */ 1117 private void testSortTypeCombinations(boolean testSortableProp) throws InterruptedException { 1118 setSize(250, 250); 1119 1120 final int COLS = 3; 1121 createRowsForSortPurposes(COLS); 1122 1123 String[][] testData = NewTableViewApp.getDataForSorting(COLS); 1124 1125 //Check initial state 1126 assertTrue("Initial sort order is wrong", checkSortResult(testData)); 1127 1128 List<ColumnState> columnStates = new ArrayList<ColumnState>(COLS); 1129 ColumnState.SortType[] sortTypes = ColumnState.SortType.values(); 1130 1131 int sortTypesCount = sortTypes.length + 1; 1132 1133 boolean[] sortableCols = {true, true, true}; 1134 1135 for (int col = 0; col < COLS; col++) { 1136 1137 if (!testSortableProp) { 1138 //When all columns are sortable it is enough to 1139 //run outer loop once to test different combinations 1140 //of the sort orders 1141 if (col > 0) { 1142 break; 1143 } 1144 } else { 1145 //Disable sortable property of each col sequentialy and 1146 //test all sort type combinations. 1147 sortableCols[col] = false; 1148 System.out.println(String.format("Column %d.sortable = false", col)); 1149 } 1150 1151 for (int x = 0; x < sortTypesCount; x++) { 1152 for (int y = 0; y < sortTypesCount; y++) { 1153 for (int z = 0; z < sortTypesCount; z++) { 1154 1155 columnStates.clear(); 1156 1157 if (x != 0) { 1158 columnStates.add(new ColumnState(0, sortTypes[x - 1], sortableCols[0])); 1159 } 1160 if (y != 0) { 1161 columnStates.add(new ColumnState(1, sortTypes[y - 1], sortableCols[1])); 1162 } 1163 if (z != 0) { 1164 columnStates.add(new ColumnState(2, sortTypes[z - 1], sortableCols[2])); 1165 } 1166 1167 for (int i = 0; i < columnStates.size(); i++) { 1168 ColumnState pr = columnStates.get(i); 1169 System.out.format("Column %d; Sort type %s; ", pr.columnIndex, pr.sortType); 1170 } 1171 setSortOrder(columnStates); 1172 checkSortNodes(columnStates); 1173 sortTestData(testData, columnStates); 1174 assertTrue("Sort order is wrong", checkSortResult(testData)); 1175 } 1176 } 1177 } 1178 } 1179 } 1180 1181 private void checkSortNodes(final List<ColumnState> columnStates) { 1182 1183 int sortableColsCount = 0; 1184 1185 for (ColumnState state : columnStates) { 1186 if (state.sortable) { 1187 ++sortableColsCount; 1188 } 1189 } 1190 1191 int curPosInSortOrder = 0; 1192 1193 for (final ColumnState state : columnStates) { 1194 Wrap<? extends TableColumnHeader> header = getTableColumnHeaderWrap(String.format("column %d", state.columnIndex)); 1195 final Parent prnt = header.as(Parent.class, Node.class); 1196 1197 header.waitState(new State<Boolean>() { 1198 public Boolean reached() { 1199 return ((state.sortable ? 1 : 0) == prnt.lookup(new ByStyleClass("arrow")).size()) ? Boolean.TRUE : null; 1200 } 1201 1202 public String tiString() { 1203 return state.sortable ? "[Sort node not found in sortable column]" : "[Sort node found in unsortable column]"; 1204 } 1205 }); 1206 1207 if (state.sortable) { 1208 ++curPosInSortOrder; 1209 1210 if (sortableColsCount > 1) { 1211 assertEquals("[Sort order dots container not found]", 1, prnt.lookup(new ByStyleClass("sort-order-dots-container")).size()); 1212 assertEquals("[Sort order dots not found]", curPosInSortOrder, prnt.lookup(new LookupCriteria<Node>() { 1213 public boolean check(Node node) { 1214 return node.getStyleClass().contains("sort-order-dot") 1215 && node.getStyleClass().contains(state.sortType.toString().toLowerCase()); 1216 } 1217 }).size()); 1218 } 1219 } 1220 } 1221 } 1222 1223 void setSortOrder(final List<ColumnState> newColumnStates) { 1224 new GetAction<Object>() { 1225 @Override 1226 public void run(Object... parameters) throws Exception { 1227 ObservableList<TableColumnBase> columns = observableArrayList(getTopLevelColumns()); 1228 1229 ObservableList<TableColumnBase> columnSortOrder 1230 = isTableTests 1231 ? ((TableView) testedControl.getControl()).getSortOrder() 1232 : ((TreeTableView) testedControl.getControl()).getSortOrder(); 1233 1234 columnSortOrder.clear(); 1235 1236 for (ColumnState columnState : newColumnStates) { 1237 TableColumnBase col = columns.get(columnState.columnIndex); 1238 setSortType(col, columnState.sortType); 1239 checkSortType(col, columnState.sortType); 1240 col.setSortable(columnState.sortable); 1241 columnSortOrder.add(col); 1242 } 1243 } 1244 }.dispatch(testedControl.getEnvironment()); 1245 1246 //Animation delay 1247 try { 1248 Thread.sleep(100); 1249 } catch (Exception e) { 1250 } 1251 } 1252 1253 static void checkSortType(TableColumnBase col, ColumnState.SortTypeProvider type) { 1254 if (isTableTests) { 1255 assertTrue(((TableColumn) col).getSortType().equals(type.forTableColumn())); 1256 } else { 1257 assertTrue(((TreeTableColumn) col).getSortType().equals(type.forTreeTableColumn())); 1258 } 1259 } 1260 1261 static void setSortType(TableColumnBase col, ColumnState.SortTypeProvider type) { 1262 if (isTableTests) { 1263 ((TableColumn) col).setSortType(type.forTableColumn()); 1264 } else { 1265 ((TreeTableColumn) col).setSortType(type.forTreeTableColumn()); 1266 } 1267 } 1268 1269 boolean checkSortResult(String[][] testData) { 1270 Boolean state = Boolean.TRUE; 1271 1272 for (int j = 0; j < testData[0].length; j++) { 1273 final int fj = j; 1274 for (int i = 0; i < testData.length; i++) { 1275 final int fi = i; 1276 final Wrap<? extends IndexedCell> cellWrap = getCellWrap(j, i); 1277 final String expected = testData[i][j]; 1278 1279 state = cellWrap.waitState(new State<Boolean>() { 1280 public Boolean reached() { 1281 String actual = cellWrap.getControl().getText(); 1282 if (!expected.equals(actual)) { 1283 System.out.println("i = " + fi + " j = " + fj); 1284 System.out.println(String.format("exp|act:%s|%s", expected, actual)); 1285 } 1286 return expected.equals(actual) ? Boolean.TRUE : Boolean.FALSE; 1287 } 1288 }); 1289 } 1290 1291 if (Boolean.FALSE == state) { 1292 System.out.println(String.format("Column %d ended.", j)); 1293 } 1294 } 1295 return state.booleanValue(); 1296 } 1297 1298 public void checkCorrectCoordinatesAllocation(Wrap<? extends TableColumnHeader> header1, Wrap<? extends TableColumnHeader> header2, int rows) { 1299 for (int i = 0; i < rows; i++) { 1300 Wrap wrap1 = getCellWrap(0, i); 1301 Wrap wrap2 = getCellWrap(1, i); 1302 1303 if (false) { 1304 System.out.println("wrap1.getScreenBounds().x = " + wrap1.getScreenBounds().x); 1305 System.out.println("header1.getScreenBounds().x = " + header1.getScreenBounds().x); 1306 System.out.println("wrap2.getScreenBounds().x = " + wrap2.getScreenBounds().x); 1307 System.out.println("header2.getScreenBounds().x = " + header2.getScreenBounds().x); 1308 System.out.println("wrap1.getScreenBounds().x + wrap1.getScreenBounds().width = " + (wrap1.getScreenBounds().x + wrap1.getScreenBounds().width)); 1309 System.out.println("header1.getScreenBounds().x + header1.getScreenBounds().width = " + (header1.getScreenBounds().x + header1.getScreenBounds().width)); 1310 System.out.println("wrap2.getScreenBounds().x + wrap2.getScreenBounds().width = " + (wrap2.getScreenBounds().x + wrap2.getScreenBounds().width)); 1311 System.out.println("header2.getScreenBounds().x + header2.getScreenBounds().width = " + (header2.getScreenBounds().x + header2.getScreenBounds().width)); 1312 } 1313 1314 if (isTableTests) { 1315 assertEquals(wrap1.getScreenBounds().x, header1.getScreenBounds().x, 0); 1316 } else { 1317 //For treeTable - there are nodes for showing tree structure 1318 //(arrows), so cells are less, and left border is not aligned 1319 //according to the left border of the column header. 1320 assertTrue(wrap1.getScreenBounds().x > header1.getScreenBounds().x); 1321 assertTrue(wrap1.getScreenBounds().x < wrap2.getScreenBounds().x); 1322 assertTrue(wrap1.getScreenBounds().x < wrap1.getScreenBounds().x + wrap1.getScreenBounds().width); 1323 } 1324 assertEquals(wrap2.getScreenBounds().x, header2.getScreenBounds().x, 0); 1325 assertEquals(wrap1.getScreenBounds().x + wrap1.getScreenBounds().width, header1.getScreenBounds().x + header1.getScreenBounds().width, 0); 1326 assertEquals(wrap2.getScreenBounds().x + wrap2.getScreenBounds().width, header2.getScreenBounds().x + header2.getScreenBounds().width, 0); 1327 } 1328 } 1329 1330 protected void testDifferentCellEditors(boolean commit) throws InterruptedException { 1331 setSize(212.5, 209.3); 1332 setPropertyByToggleClick(SettingType.SETTER, Properties.editable, true); 1333 1334 addColumn("colA", 0, true); 1335 addColumn("colB", 1, true); 1336 addColumn("colC", 2, true); 1337 1338 final int ROWS = 10; 1339 setNewDataSize(ROWS); 1340 1341 clickButtonForTestPurpose(BTN_SET_ON_EDIT_EVENT_HANDLERS); 1342 1343 int editStartCounter = 0; 1344 int editCancelCounter = 0; 1345 int editCommitCounter = 0; 1346 1347 final class GetCellControlClassAction extends GetAction<Class> { 1348 1349 int rowIndex = -1; 1350 int columnIndex = -1; 1351 1352 public GetCellControlClassAction(int rowIndex, int columnIndex) { 1353 this.columnIndex = columnIndex; 1354 this.rowIndex = rowIndex; 1355 } 1356 1357 @Override 1358 public void run(Object... os) throws Exception { 1359 TableCell cell = getCellWrap(columnIndex, rowIndex).getControl(); 1360 setResult((null != cell.getGraphic()) ? cell.getGraphic().getClass() : Object.class); 1361 } 1362 1363 } 1364 1365 Wrap<? extends TableCell> cellWrap; 1366 for (CellEditorType type : CellEditorType.values()) { 1367 1368 for (boolean isCustom : new boolean[]{true, false}) { 1369 1370 switch (type) { 1371 case TEXT_FIELD: 1372 setCellEditor(CellEditorType.TEXT_FIELD, isCustom); 1373 cellWrap = getCellWrap(1, 4); 1374 String initialText = getCellText(cellWrap); 1375 1376 cellWrap.mouse().click(); 1377 cellWrap.keyboard().pushKey(KeyboardButtons.F2); 1378 cellWrap.keyboard().pushKey(KeyboardButtons.A, KeyboardModifiers.CTRL_DOWN_MASK); 1379 cellWrap.keyboard().pushKey(KeyboardButtons.A); 1380 cellWrap.keyboard().pushKey(KeyboardButtons.B); 1381 cellWrap.keyboard().pushKey(KeyboardButtons.C); 1382 1383 final TextField textField = (TextField) cellWrap.as(Parent.class, Node.class).lookup(TextField.class).get(); 1384 cellWrap.waitState(new State() { 1385 1386 @Override 1387 public Object reached() { 1388 if (textField == null) { 1389 System.out.println("TextField null"); 1390 return null; 1391 } 1392 if (textField.getText().equals("abc")) { 1393 return true; 1394 } else { 1395 return null; 1396 } 1397 } 1398 }); 1399 1400 cellWrap.keyboard().pushKey(commit ? KeyboardButtons.ENTER : KeyboardButtons.ESCAPE); 1401 1402 if (commit) { 1403 assertEquals("Text didn't changed", "abc", getCellText(cellWrap)); 1404 } else { 1405 assertEquals("[Text changed unexpectedly]", initialText, getCellText(cellWrap)); 1406 } 1407 break; 1408 case COMBOBOX: 1409 setCellEditor(CellEditorType.COMBOBOX, isCustom); 1410 cellWrap = getCellWrap(1, 4); 1411 1412 GetAction<Class> getCellClassAction = new GetCellControlClassAction(4, 1); 1413 Class cellControlType = getCellClassAction.dispatch(cellWrap.getEnvironment()); 1414 while ( !ComboBox.class.equals(cellControlType) ) 1415 { 1416 cellWrap.mouse().click(); 1417 cellControlType = getCellClassAction.dispatch(cellWrap.getEnvironment()); 1418 } 1419 1420 Wrap<ComboBox> combobox = cellWrap.as(Parent.class, Node.class).lookup(ComboBox.class).wrap(); 1421 1422 //Select nothing 1423 if (!commit) { 1424 combobox.mouse().click(); 1425 assertTrue("Popup hasn't appeared", 1426 new GetAction<Boolean>() { 1427 @Override 1428 public void run(Object... os) throws Exception { 1429 Wrap<? extends Scene> popupScene = Root.ROOT.lookup(new ByWindowType(PopupWindow.class)).lookup(Scene.class).wrap(0); 1430 setResult(popupScene.getControl().getWindow().showingProperty().getValue()); 1431 } 1432 }.dispatch(Root.ROOT.getEnvironment())); 1433 1434 //First escape to close popup 1435 scene.keyboard().pushKey(KeyboardButtons.ESCAPE); 1436 //Second escape to cancel editing 1437 scene.keyboard().pushKey(KeyboardButtons.ESCAPE); 1438 } else { 1439 combobox.as(Selectable.class).selector().select("colB-1"); 1440 } 1441 break; 1442 case CHOICEBOX: 1443 setCellEditor(CellEditorType.CHOICEBOX, isCustom); 1444 cellWrap = getCellWrap(1, 4); 1445 1446 getCellClassAction = new GetCellControlClassAction(4, 1); 1447 cellControlType = getCellClassAction.dispatch(cellWrap.getEnvironment()); 1448 while ( !ChoiceBox.class.equals(cellControlType) ) 1449 { 1450 cellWrap.mouse().click(); 1451 cellControlType = getCellClassAction.dispatch(cellWrap.getEnvironment()); 1452 } 1453 1454 Wrap<ChoiceBox> choicebox = cellWrap.as(Parent.class, Node.class).lookup(ChoiceBox.class).wrap(); 1455 1456 //Select nothing 1457 if (!commit) { 1458 choicebox.mouse().click(); 1459 1460 choicebox.waitState(new State<Boolean>() { 1461 @Override 1462 public Boolean reached() { 1463 return new GetAction<Boolean>() { 1464 @Override 1465 public void run(Object... os) throws Exception { 1466 Wrap<? extends Scene> popupScene = Root.ROOT.lookup(new ByWindowType(PopupWindow.class)).lookup(Scene.class).wrap(0); 1467 setResult(popupScene.getControl().getWindow().showingProperty().getValue()); 1468 } 1469 }.dispatch(Root.ROOT.getEnvironment()) 1470 ? Boolean.TRUE : null; 1471 } 1472 1473 @Override 1474 public String toString() { 1475 return "[Popup expected to appear]"; 1476 } 1477 }); 1478 //First escape to close popup 1479 scene.keyboard().pushKey(KeyboardButtons.ESCAPE); 1480 //Second escape to cancel editing 1481 scene.keyboard().pushKey(KeyboardButtons.ESCAPE); 1482 } else { 1483 choicebox.as(Selectable.class).selector().select("colB-1"); 1484 } 1485 break; 1486 } 1487 1488 checkCounterValue(COUNTER_EDIT_START, ++editStartCounter); 1489 1490 if (commit) { 1491 ++editCommitCounter; 1492 } else { 1493 ++editCancelCounter; 1494 } 1495 1496 checkCounterValue(COUNTER_EDIT_CANCEL, editCancelCounter); 1497 checkCounterValue(COUNTER_EDIT_COMMIT, editCommitCounter); 1498 } 1499 } 1500 } 1501 1502 @Smoke 1503 @Test(timeout = 300000) 1504 public void fixedCellSizePropertyTest() throws InterruptedException { 1505 setSize(200, 200); 1506 addColumn("items0", 0, true); 1507 addColumn("items1", 1, true); 1508 createNestedColumn("nested", 0, 0, 1); 1509 setNewDataSize(5); 1510 fixedCellSizePropertyTestCommon(testedControl, Properties.fixedCellSize, 24); 1511 } 1512 1513 @Smoke 1514 @Test(timeout = 300000) 1515 public void fixedCellSizePropertyCSSTest() throws InterruptedException { 1516 setSize(200, 200); 1517 addColumn("items0", 0, true); 1518 addColumn("items1", 1, true); 1519 createNestedColumn("nested", 0, 0, 1); 1520 setNewDataSize(5); 1521 fixedCellSizePropertyTestCommon(testedControl, Properties.fixedCellSize, 24); 1522 } 1523 1524 @Test(timeout = 300000) 1525 public void styleOnCellsApplyingTest() throws InterruptedException, Throwable { 1526 setSize(200, 200); 1527 addColumn("items0", 0, true); 1528 addColumn("items1", 1, true); 1529 createNestedColumn("nested", 0, 0, 1); 1530 setNewDataSize(5); 1531 1532 final Wrap<? extends TableColumnHeader> nested = getTableColumnHeaderWrap("nested"); 1533 final Wrap<? extends TableColumnHeader> items0 = getTableColumnHeaderWrap("items1"); 1534 1535 applyStyleOnColumn(nested.getControl().getTableColumn(), "-fx-background-color: blue;"); 1536 applyStyleOnColumn(items0.getControl().getTableColumn(), "-fx-background-color: red;"); 1537 1538 checkScreenshot((isTableTests ? "TableView-" : "TreeTableView-") + "styleOnColumnApplication", testedControl); 1539 throwScreenshotError(); 1540 } 1541 1542 protected void applyStyleOnColumn(final TableColumnBase column, final String style) { 1543 new GetAction() { 1544 @Override 1545 public void run(Object... os) throws Exception { 1546 column.setStyle(style); 1547 } 1548 }.dispatch(testedControl.getEnvironment()); 1549 } 1550 }