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 com.sun.javafx.scene.control.skin.NestedTableColumnHeader; 28 import com.sun.javafx.scene.control.skin.TableColumnHeader; 29 import java.util.Collection; 30 import java.util.Comparator; 31 import java.util.concurrent.TimeUnit; 32 import java.util.logging.Level; 33 import java.util.logging.Logger; 34 import javafx.collections.FXCollections; 35 import static javafx.commons.Consts.*; 36 import static javafx.commons.Consts.Cell.EDITING_CHOICEBOX_CELL_ID; 37 import javafx.commons.Consts.CellEditorType; 38 import javafx.scene.Node; 39 import javafx.scene.Scene; 40 import javafx.scene.control.CheckBox; 41 import javafx.scene.control.ComboBox; 42 import javafx.scene.control.Control; 43 import javafx.scene.control.Label; 44 import javafx.scene.control.Labeled; 45 import javafx.scene.control.ScrollBar; 46 import javafx.scene.control.TableCell; 47 import javafx.scene.control.TableColumnBase; 48 import javafx.scene.control.TableView; 49 import javafx.scene.control.TextField; 50 import javafx.scene.control.TreeTableView; 51 import static javafx.scene.control.test.treetable.ResetButtonNames.HARD_RESET_BUTTON_ID; 52 import static javafx.scene.control.test.treetable.ResetButtonNames.SOFT_RESET_BUTTON_ID; 53 import javafx.scene.control.test.treetable.TreeTableNewApp; 54 import javafx.scene.control.test.utils.ptables.AbstractPropertyController.SettingType; 55 import javafx.stage.PopupWindow; 56 import org.jemmy.Point; 57 import org.jemmy.Rectangle; 58 import org.jemmy.action.GetAction; 59 import org.jemmy.control.Wrap; 60 import org.jemmy.env.Environment; 61 import org.jemmy.fx.ByID; 62 import org.jemmy.fx.ByWindowType; 63 import org.jemmy.fx.Root; 64 import org.jemmy.interfaces.Parent; 65 import org.jemmy.lookup.Lookup; 66 import org.jemmy.lookup.LookupCriteria; 67 import org.jemmy.timing.State; 68 import org.junit.After; 69 import org.junit.Before; 70 import org.junit.BeforeClass; 71 72 /** 73 * @author Alexander Kirov 74 */ 75 public class ApplicationInteractionFunctions extends TestBaseCommon { 76 77 protected static Wrap<? extends Scene> scene; 78 protected static Wrap<? extends Control> testedControl; 79 protected static boolean isTableTests = true; 80 81 protected boolean resetHardByDefault = true;//switcher of hard and soft reset mode. 82 protected boolean doNextResetHard = resetHardByDefault; 83 84 protected static enum Properties { 85 86 prefWidth, prefHeight, width, sortNode, comparator, sortOrder, graphic, 87 resizable, showRoot, expanded, editable, value, sortable, fixedCellSize, reorderable}; 88 89 @BeforeClass 90 public static void setUpClass() throws Exception { 91 if (isTableTests) { 92 System.out.println("Starting a TableView application with properties control."); 93 NewTableViewApp.main(null); 94 } else { 95 System.out.println("Starting a TreeTable application with properties control."); 96 TreeTableNewApp.main(null); 97 } 98 } 99 100 @Before 101 public void setUp() { 102 initWrappers(); 103 Environment.getEnvironment().setTimeout("wait.state", 2000); 104 Environment.getEnvironment().setTimeout("wait.control", 1000); 105 scene.mouse().move(new Point(0, 0)); 106 } 107 108 @After 109 public void tearDown() { 110 if (doNextResetHard) { 111 resetSceneHard(); 112 } else { 113 resetSceneSoft(); 114 } 115 116 doNextResetHard = resetHardByDefault; 117 currentSettingOption = SettingOption.PROGRAM; 118 } 119 120 protected void initWrappers() { 121 scene = Root.ROOT.lookup().wrap(); 122 parent = scene.as(Parent.class, Node.class); 123 if (isTableTests) { 124 testedControl = parent.lookup(TableView.class, new ByID<TableView>(NewTableViewApp.TESTED_TABLE_VIEW_ID)).wrap(); 125 } else { 126 testedControl = parent.lookup(TreeTableView.class, new ByID<TreeTableView>(TreeTableNewApp.TESTED_TREETABLEVIEW_ID)).wrap(); 127 } 128 } 129 130 /** 131 * Set size if tested control using bidirectional bindings. 132 */ 133 protected void setSize(double width, double height) throws InterruptedException { 134 setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.prefHeight, height); 135 setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.prefWidth, width); 136 } 137 138 protected void setNewDataSize(int newSize) { 139 setText(findTextField(NEW_DATA_SIZE_TEXTFIELD_ID), String.valueOf(newSize)); 140 clickButtonForTestPurpose(NEW_DATA_SIZE_BUTTON_ID); 141 } 142 143 public static void addColumn(String name, int index) { 144 addColumn(name, index, false); 145 } 146 147 public static void addColumn(String name, int index, boolean createPropertiesTab) { 148 setText(findTextField(NEW_COLUMN_NAME_TEXTFIELD_ID), name); 149 setText(findTextField(NEW_COLUMN_INDEX_TEXTFIELD_UD), String.valueOf(index)); 150 setCheckBoxState(NEW_COLUMN_GET_COLUMN_PROPERTIES_TAB_ID, createPropertiesTab); 151 clickButtonForTestPurpose(NEW_COLUMN_ADD_BUTTON_ID); 152 } 153 154 protected void createNestedColumn(String newColumnName, int index, int... indicesOfColumns) { 155 setText(findTextField(NESTED_COLUMN_NAME_TEXT_FIELD_ID), newColumnName); 156 setText(findTextField(NESTED_COLUMN_INDEX_TEXT_FIELD_ID), String.valueOf(index)); 157 setText(findTextField(CREATE_NESTED_COLUMN_MULTIPLE_TEXTFIELD_ID), convertMultiIndicesToString(indicesOfColumns)); 158 clickButtonForTestPurpose(CREATE_NESTED_COLUMN_MULTIPLE_ACTION_BUTTON_ID); 159 } 160 161 protected void removeColumns(int... indicesOfColumns) { 162 setText(findTextField(REMOVE_MULTIPLE_COLUMNS_TEXT_FIELD_ID), convertMultiIndicesToString(indicesOfColumns)); 163 clickButtonForTestPurpose(REMOVE_MULTIPLE_COLUMNS_ACTION_BUTTON_ID); 164 } 165 166 protected void removeDataItems(int... indicesOfColumns) { 167 setText(findTextField(REMOVE_DATA_ITEMS_MULTIPLE_TEXT_FIELD_ID), convertMultiIndicesToString(indicesOfColumns)); 168 clickButtonForTestPurpose(REMOVE_DATA_ITEMS_MULTIPLE_ACTION_BUTTON_ID); 169 } 170 171 private void resetSceneHard() { 172 clickButtonForTestPurpose(HARD_RESET_BUTTON_ID); 173 initWrappers(); 174 } 175 176 private void resetSceneSoft() { 177 clickButtonForTestPurpose(SOFT_RESET_BUTTON_ID); 178 initWrappers(); 179 } 180 181 protected void scrollTo(final int column, final int row) { 182 scrollTo(testedControl, column, row); 183 } 184 185 protected Wrap<? extends TableCell> getCellWrap(final int column, final int row) { 186 return getCellWrap(testedControl, column, row); 187 } 188 189 protected Point getResizingPointOfColumn(String columnName) { 190 Rectangle rec = getTableColumnHeaderWrap(columnName).getScreenBounds(); 191 return new Point(rec.x + rec.width, rec.y + rec.height / 2); 192 } 193 194 protected double getScrollBarValue(final Wrap<? extends ScrollBar> scroll) { 195 return new GetAction<Double>() { 196 @Override 197 public void run(Object... os) throws Exception { 198 setResult(scroll.getControl().getValue()); 199 } 200 }.dispatch(Root.ROOT.getEnvironment()); 201 } 202 203 protected Wrap<? extends TableColumnHeader> getTableColumnHeaderWrap(final String name) { 204 return testedControl.as(Parent.class, Node.class).lookup(TableColumnHeader.class, new LookupCriteria<TableColumnHeader>() { 205 public boolean check(TableColumnHeader cntrl) { 206 if ((cntrl.getBoundsInLocal().getMaxY() > 15) && (!(cntrl instanceof NestedTableColumnHeader))) { 207 return ((Label) (cntrl.getChildrenUnmodifiable().get(0))).getText().equals(name); 208 } else { 209 return false; 210 } 211 } 212 }).wrap(); 213 } 214 215 /* 216 * Clears all the content and then 217 * creates COLS columns and respective numver of rows 218 * with different string literals; 219 * @param COLS number of columns 220 */ 221 void createRowsForSortPurposes(final int COLS) { 222 Integer colsCount = new GetAction<Integer>() { 223 @Override 224 public void run(Object... parameters) throws Exception { 225 if (isTableTests) { 226 TableView tv = (TableView) testedControl.getControl(); 227 setResult(Integer.valueOf(tv.getColumns().size())); 228 } else { 229 TreeTableView ttv = (TreeTableView) testedControl.getControl(); 230 setResult(Integer.valueOf(ttv.getColumns().size())); 231 ttv.setShowRoot(false); 232 } 233 } 234 }.dispatch(testedControl.getEnvironment()); 235 236 //Remove columns if exist 237 if (colsCount.intValue() > 0) { 238 StringBuilder sb = new StringBuilder(); 239 for (int i = 0; i < colsCount.intValue(); i++) { 240 if (0 != i) { 241 sb.append(";"); 242 } 243 sb.append(i); 244 } 245 246 Wrap wrap = parent.lookup(TextField.class, new ByID(REMOVE_MULTIPLE_COLUMNS_TEXT_FIELD_ID)).wrap(); 247 setText(wrap, sb.toString()); 248 clickButtonForTestPurpose(REMOVE_MULTIPLE_COLUMNS_ACTION_BUTTON_ID); 249 } 250 251 Wrap wrap = parent.lookup(CheckBox.class, new ByID(NEW_COLUMN_GET_COLUMN_PROPERTIES_TAB_ID)).wrap(); 252 wrap.mouse().click(); 253 254 for (int i = 0; i < COLS; i++) { 255 wrap = parent.lookup(TextField.class, new ByID(NEW_COLUMN_NAME_TEXTFIELD_ID)).wrap(); 256 257 String tabName = String.format("column %d", i); 258 setText(wrap, tabName); 259 260 wrap = parent.lookup(TextField.class, new ByID(NEW_COLUMN_INDEX_TEXTFIELD_UD)).wrap(); 261 setText(wrap, String.valueOf(i)); 262 263 clickButtonForTestPurpose(NEW_COLUMN_ADD_BUTTON_ID); 264 switchToPropertiesTab(tabName); 265 try { 266 setPropertyBySlider(SettingType.SETTER, Properties.prefWidth, 50.0); 267 } catch (InterruptedException ex) { 268 Logger.getLogger(ApplicationInteractionFunctions.class.getName()).log(Level.SEVERE, null, ex); 269 } 270 } 271 272 clickButtonForTestPurpose(BTN_CREATE_SORTABLE_ROWS_ID); 273 } 274 275 protected void setCellEditor(final CellEditorType type, final boolean isCustom) { 276 277 new GetAction<Object>() { 278 @Override 279 public void run(Object... parameters) throws Exception { 280 Wrap<? extends Node> cmbEditors 281 = parent.lookup(new ByID(CMB_EDITORS_ID)).wrap(); 282 283 ((ComboBox) cmbEditors.getControl()).setValue(type); 284 } 285 }.dispatch(testedControl.getEnvironment()); 286 287 new GetAction<Object>() { 288 @Override 289 public void run(Object... parameters) throws Exception { 290 Wrap<? extends Node> chbCustom = parent.lookup(new ByID(CHB_IS_CUSTOM_ID)).wrap(); 291 ((CheckBox)chbCustom.getControl()).setSelected(isCustom); 292 } 293 }.dispatch(testedControl.getEnvironment()); 294 295 clickButtonForTestPurpose(BTN_SET_CELLS_EDITOR_ID); 296 297 if (isCustom) { 298 testedControl.waitState(new State<Object>() { 299 String id = null; 300 { 301 if (type == CellEditorType.CHOICEBOX) { 302 id = Cell.EDITING_CHOICEBOX_CELL_ID; 303 } else if (type == CellEditorType.COMBOBOX) { 304 id = Cell.EDITING_COMBOBOX_CELL_ID; 305 } else if (type == CellEditorType.TEXT_FIELD) { 306 id = Cell.EDITING_TEXTFIELD_CELL_ID; 307 } else { 308 throw new RuntimeException("Something went wrong"); 309 } 310 } 311 @Override 312 public Object reached() { 313 return (testedControl.as(Parent.class, Node.class).lookup(Node.class, new ByID(id)).size() > 0) 314 ? 42 : null; 315 } 316 }); 317 318 } 319 } 320 321 protected String getCellText(final Wrap<? extends Labeled> wrap) { 322 return new GetAction<String>() { 323 @Override 324 public void run(Object... parameters) throws Exception { 325 setResult(((Labeled)wrap.getControl()).getText()); 326 } 327 }.dispatch(testedControl.getEnvironment()); 328 } 329 330 protected void checkPopup() throws Exception { 331 Lookup<Scene> lookup = Root.ROOT.lookup(new ByWindowType(PopupWindow.class)) 332 .lookup(Scene.class); 333 if (lookup.size() != 1) { 334 throw new Exception("Popup is expected to appear."); 335 } 336 } 337 338 /* 339 * Doesn't take nested columns into consideration. 340 */ 341 protected Collection<TableColumnBase> getTopLevelColumns() { 342 return new GetAction<Collection<TableColumnBase>>() { 343 344 @Override 345 public void run(Object... parameters) throws Exception { 346 Collection<TableColumnBase> cols; 347 Control control = testedControl.getControl(); 348 349 if (isTableTests) { 350 cols = ((TableView) control).getColumns(); 351 } else { 352 cols = ((TreeTableView) control).getColumns(); 353 } 354 setResult(cols); 355 } 356 }.dispatch(testedControl.getEnvironment()); 357 } 358 359 protected void setShowRoot(final boolean value) { 360 if (!isTableTests) { 361 new GetAction<Object>() { 362 363 @Override 364 public void run(Object... os) throws Exception { 365 ((TreeTableView) testedControl.getControl()).setShowRoot(value); 366 } 367 }.dispatch(testedControl.getEnvironment()); 368 369 try { 370 TimeUnit.MILLISECONDS.sleep(1000); 371 } catch (Exception e) { 372 } 373 } 374 } 375 376 protected void sortColumnsByName(final boolean isAscending) { 377 new GetAction<Object>() { 378 private Comparator<TableColumnBase> comparator = new Comparator<TableColumnBase>() { 379 public int compare(TableColumnBase o1, TableColumnBase o2) { 380 int result = o1.getText().compareTo(o2.getText()); 381 return isAscending ? result : -result; 382 } 383 }; 384 385 @Override 386 public void run(Object... os) throws Exception { 387 if (isTableTests) { 388 FXCollections.sort(((TableView) testedControl.getControl()).getColumns(), comparator); 389 } else { 390 FXCollections.sort(((TreeTableView) testedControl.getControl()).getColumns(), comparator); 391 } 392 } 393 }.dispatch(testedControl.getEnvironment()); 394 395 try { 396 TimeUnit.MILLISECONDS.sleep(1000); 397 } catch (Exception e) { 398 } 399 } 400 }