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.datepicker; 26 27 import com.sun.javafx.scene.control.skin.LabeledText; 28 import java.time.LocalDate; 29 import java.time.Month; 30 import java.time.YearMonth; 31 import java.time.chrono.Chronology; 32 import java.util.ArrayList; 33 import java.util.HashMap; 34 import java.util.List; 35 import java.util.Locale; 36 import java.util.Map; 37 import java.util.logging.Level; 38 import java.util.logging.Logger; 39 import javafx.scene.Node; 40 import javafx.scene.Scene; 41 import javafx.scene.control.Button; 42 import javafx.scene.control.DateCell; 43 import javafx.scene.control.DatePicker; 44 import javafx.scene.control.Label; 45 import javafx.scene.control.TextField; 46 import static javafx.scene.control.test.datepicker.DatePickerApp.*; 47 import javafx.scene.control.test.util.UtilTestFunctions; 48 import javafx.scene.layout.Pane; 49 import javafx.scene.layout.Region; 50 import javafx.scene.text.Text; 51 import javafx.util.Callback; 52 import javafx.util.StringConverter; 53 import org.jemmy.Point; 54 import org.jemmy.action.GetAction; 55 import org.jemmy.control.Wrap; 56 import org.jemmy.env.Environment; 57 import org.jemmy.fx.ByID; 58 import org.jemmy.fx.ByStyleClass; 59 import org.jemmy.fx.Root; 60 import org.jemmy.fx.control.TextInputControlDock; 61 import org.jemmy.interfaces.Keyboard; 62 import org.jemmy.interfaces.Mouse.MouseButtons; 63 import org.jemmy.interfaces.Parent; 64 import org.jemmy.lookup.Lookup; 65 import org.jemmy.lookup.LookupCriteria; 66 import org.jemmy.timing.State; 67 import org.junit.After; 68 import static org.junit.Assert.*; 69 import org.junit.Before; 70 import org.junit.BeforeClass; 71 import org.junit.runner.RunWith; 72 import test.javaclient.shared.FilteredTestRunner; 73 import test.javaclient.shared.JemmyUtils; 74 import static test.javaclient.shared.TestUtil.isEmbedded; 75 import test.javaclient.shared.Utils; 76 77 /** 78 * @author Alexander Kirov 79 */ 80 @RunWith(FilteredTestRunner.class) 81 public class TestBase extends UtilTestFunctions { 82 83 static Wrap<? extends DatePicker> testedControl; 84 static Wrap<? extends Scene> scene; 85 static Wrap<? extends Scene> popupScene; 86 protected boolean resetHardByDefault = true;//switcher of hard and soft reset mode. 87 protected boolean doNextResetHard = resetHardByDefault; 88 static final LocalDate DEFAULT_DATE = LocalDate.of(1990, Month.OCTOBER, 11); 89 90 //WIN7 : W : 249.0 H : 228.0 ; 8.0b109 ; (H-U:W:270.0;H:297.0) 91 //LIN : TODO: 92 //MAC : TODO: 93 static final int POPUP_MIN_EXPECTED_WIDTH = 240; 94 static final int POPUP_MAX_EXPECTED_WIDTH = 260; 95 static final int POPUP_MIN_EXPECTED_HEIGHT = 220; 96 static final int POPUP_MAX_EXPECTED_HEIGHT = 240; 97 98 @Before 99 public void setUp() { 100 initWrappers(); 101 Environment.getEnvironment().setTimeout("wait.state", isEmbedded() ? 60000 : 2000); 102 Environment.getEnvironment().setTimeout("wait.control", isEmbedded() ? 60000 : 1000); 103 scene.mouse().move(new Point(0, 0)); 104 Locale.setDefault(Locale.ENGLISH); 105 } 106 107 @BeforeClass 108 public static void setUpClass() throws Exception { 109 JemmyUtils.setJemmyComparatorByDistance(0.01f); 110 DatePickerApp.main(null); 111 currentSettingOption = SettingOption.PROGRAM; 112 } 113 114 @After 115 public void tearDown() throws InterruptedException { 116 if (isPopupVisible()) { 117 scene.mouse().click(1, new Point(0, 0)); 118 } 119 120 if (doNextResetHard) { 121 resetSceneHard(); 122 } else { 123 resetSceneSoft(); 124 } 125 126 doNextResetHard = resetHardByDefault; 127 } 128 129 protected void initWrappers() { 130 scene = Root.ROOT.lookup().wrap(); 131 parent = scene.as(Parent.class, Node.class); 132 133 testedControl = (Wrap<? extends DatePicker>) parent.lookup(DatePicker.class, new ByID<DatePicker>(TESTED_DATEPICKER_ID)).wrap(); 134 } 135 136 // ACTIONS 137 protected void resetSceneSoft() { 138 clickButtonForTestPurpose(SOFT_RESET_BUTTON_ID); 139 } 140 141 protected void resetSceneHard() { 142 clickButtonForTestPurpose(HARD_RESET_BUTTON_ID); 143 } 144 145 protected void doNextResetHard() { 146 doNextResetHard = true; 147 } 148 149 protected void doNextResetSoft() { 150 doNextResetHard = false; 151 } 152 153 protected void clickControl() { 154 testedControl.mouse().click(); 155 } 156 157 protected void clickDropDownButton() { 158 testedControl.as(Parent.class, Node.class).lookup(Region.class, new ByStyleClass("arrow-button")).wrap().mouse().click(); 159 } 160 161 protected Wrap<? extends Scene> getPopupWrap() throws InterruptedException { 162 try { 163 return Root.ROOT.lookup(new LookupCriteria<Scene>() { 164 int shift; 165 int widthAddition; 166 int heightAddition; 167 168 { 169 Boolean weekNumbersShowing = new GetAction<Boolean>() { 170 @Override 171 public void run(Object... parameters) throws Exception { 172 setResult(Boolean.valueOf(testedControl.getControl().isShowWeekNumbers())); 173 } 174 }.dispatch(testedControl.getEnvironment()); 175 176 Boolean isHijrahUmalqura = new GetAction<Boolean>() { 177 @Override 178 public void run(Object... parameters) throws Exception { 179 setResult(Boolean.valueOf(testedControl.getControl().getChronology().equals(Chronology.of("Hijrah-umalqura")))); 180 } 181 }.dispatch(testedControl.getEnvironment()); 182 183 if (weekNumbersShowing == Boolean.TRUE) { 184 shift = 27; 185 } 186 187 if (isHijrahUmalqura) { 188 widthAddition = 20; 189 heightAddition = 77; 190 } 191 } 192 193 public boolean check(Scene cntrl) { 194 return cntrl.lookup(".date-picker-popup") != null; 195 } 196 }).wrap(); 197 } catch (Exception e) { 198 return null; 199 } 200 } 201 202 protected boolean isPopupVisible() throws InterruptedException { 203 if ((popupScene = getPopupWrap()) != null) { 204 System.out.println("Popup was found"); 205 Boolean res = new GetAction<Boolean>() { 206 @Override 207 public void run(Object... os) throws Exception { 208 setResult(popupScene.getControl().getWindow().showingProperty().getValue()); 209 } 210 }.dispatch(Root.ROOT.getEnvironment()); 211 if (res) { 212 System.out.println("Checking coordinates"); 213 checkPopupCoordinates(popupScene); 214 } 215 return res; 216 } else { 217 System.out.println("Popup was not found."); 218 return false; 219 } 220 } 221 222 public void checkPopupVisibility(boolean expectedVisibility) throws InterruptedException { 223 assertEquals(expectedVisibility, isPopupVisible()); 224 } 225 226 protected void showPopup() throws InterruptedException { 227 if (!isPopupVisible()) { 228 clickDropDownButton(); 229 waitPopupShowingState(true); 230 final Wrap<? extends Scene> popupWrap = getPopupWrap(); 231 assertNotNull(popupWrap); 232 checkPopupCoordinates(popupWrap); 233 } 234 } 235 236 protected void waitPopupShowingState(final boolean showing) throws InterruptedException { 237 testedControl.waitState(new State() { 238 public Object reached() { 239 if (testedControl.getControl().isShowing() == showing) { 240 try { 241 if (showing == isPopupVisible()) { 242 return true; 243 } 244 } catch (InterruptedException ex) { 245 return null; 246 } 247 return true; 248 } else { 249 return null; 250 } 251 } 252 253 @Override public String toString() { return String.format("[Popup menu is showing = %b]", showing); } 254 }); 255 } 256 257 /* 258 * Checks alignment of the popup with the date field 259 */ 260 protected void checkPopupCoordinates(final Wrap<? extends Scene> popupWrap) throws InterruptedException { 261 System.out.println("popupWrap = " + popupWrap); 262 System.out.println("popupWrap.as(Parent.class, Pane.class) = " + popupWrap.as(Parent.class, Pane.class)); 263 Lookup lookup = popupWrap.as(Parent.class, Pane.class).lookup(new ByStyleClass("date-picker-popup")); 264 assertEquals("[Popup content not found]", 1, lookup.size()); 265 266 Wrap content = lookup.wrap(); 267 268 assertEquals(testedControl.getScreenBounds().x, content.getScreenBounds().x, 1); 269 assertEquals(testedControl.getScreenBounds().y + testedControl.getScreenBounds().height, content.getScreenBounds().y, 1); 270 } 271 272 Wrap getRootWrap(final Wrap<? extends Scene> popupWrap) { 273 return popupWrap.as(Parent.class, Node.class).lookup(new ByStyleClass("date-picker-popup")).wrap(); 274 } 275 276 void selectAllText(TextInputControlDock input) { 277 input.keyboard().pushKey(Keyboard.KeyboardButtons.A, Utils.isMacOS() ? Keyboard.KeyboardModifiers.META_DOWN_MASK : Keyboard.KeyboardModifiers.CTRL_DOWN_MASK); 278 } 279 280 public class DateCellDescription { 281 282 public final int mainDate; 283 public final int secondaryDate; 284 285 public DateCellDescription(Wrap<? extends DateCell> dateCellWrap) { 286 Lookup lookup = dateCellWrap.as(Parent.class, Node.class).lookup(); 287 if (lookup.lookup(LabeledText.class).size() > 0) { 288 final Wrap<? extends LabeledText> mainText = lookup.lookup(LabeledText.class).wrap(); 289 mainDate = Integer.parseInt(getText(mainText)); 290 } else { 291 mainDate = -1; 292 } 293 294 if (lookup.lookup(Text.class, new ByStyleClass("secondary-text")).size() > 0) { 295 final Wrap<? extends Text> secondaryText = lookup.lookup(Text.class, new ByStyleClass("secondary-text")).wrap(); 296 secondaryDate = Integer.parseInt(getText(secondaryText)); 297 } else { 298 secondaryDate = -1; 299 } 300 } 301 302 @Override 303 public String toString() { 304 return String.format("%d", mainDate); 305 } 306 } 307 308 public class PopupInfoDescription { 309 310 public final String monthName; 311 public final String year; 312 public final String secondaryLabel; 313 public final List<Integer> weekNumbers; 314 public final List<String> dayNames; 315 public final List<DateCellDescription> previousMonthDays; 316 public final List<DateCellDescription> currentMonthDays; 317 public final List<DateCellDescription> nextMonthDays; 318 public final DateCellDescription today; 319 public final DateCellDescription selectedDay; 320 public final DateCellDescription focusedDay; 321 322 public PopupInfoDescription(PopupSceneDescription sceneDescription) { 323 if (sceneDescription.today != null) { 324 today = new DateCellDescription(sceneDescription.today); 325 } else { 326 today = null; 327 } 328 329 monthName = getLabelText(sceneDescription.currentMonthWrap); 330 year = getLabelText(sceneDescription.currentYearWrap); 331 332 if (sceneDescription.weeksNumbers.size() > 0) { 333 assertEquals(sceneDescription.weeksNumbers.size(), 6); 334 } 335 336 weekNumbers = new ArrayList(); 337 for (Wrap<? extends DateCell> dateCell : sceneDescription.weeksNumbers) { 338 weekNumbers.add(new DateCellDescription(dateCell).mainDate); 339 } 340 341 currentMonthDays = new ArrayList(); 342 for (Wrap<? extends DateCell> cell : sceneDescription.currentMonthDays) { 343 currentMonthDays.add(new DateCellDescription(cell)); 344 } 345 346 previousMonthDays = new ArrayList(); 347 for (Wrap<? extends DateCell> cell : sceneDescription.previousMonthDays) { 348 previousMonthDays.add(new DateCellDescription(cell)); 349 } 350 351 nextMonthDays = new ArrayList(); 352 for (Wrap<? extends DateCell> cell : sceneDescription.nextMonthDays) { 353 nextMonthDays.add(new DateCellDescription(cell)); 354 } 355 356 if (sceneDescription.secondaryLabel != null) { 357 secondaryLabel = getLabelText(sceneDescription.secondaryLabel); 358 } else { 359 secondaryLabel = null; 360 } 361 362 dayNames = new ArrayList(); 363 assertEquals(sceneDescription.daysNames.size(), 7); 364 for (Wrap<? extends DateCell> cell : sceneDescription.daysNames) { 365 dayNames.add(getText(cell.as(Parent.class, Node.class).lookup(Text.class).wrap())); 366 } 367 368 assertEquals(sceneDescription.nextMonthDays.size() 369 + sceneDescription.previousMonthDays.size() 370 + sceneDescription.currentMonthDays.size(), 371 6 * 7); 372 373 selectedDay = new GetAction<DateCellDescription>() { 374 @Override 375 public void run(Object... parameters) throws Exception { 376 for (Wrap<? extends DateCell> cell : ((PopupSceneDescription) parameters[0]).currentMonthDays) { 377 if (cell.getControl().getStyleClass().contains("selected")) { 378 setResult(new DateCellDescription(cell)); 379 } 380 } 381 } 382 }.dispatch(testedControl.getEnvironment(), sceneDescription); 383 384 focusedDay = new GetAction<DateCellDescription>() { 385 @Override 386 public void run(Object... parameters) throws Exception { 387 for (Wrap<? extends DateCell> cell : ((PopupSceneDescription) parameters[0]).previousMonthDays) { 388 if (cell.getControl().isFocused()) { 389 setResult(new DateCellDescription(cell)); 390 } 391 } 392 for (Wrap<? extends DateCell> cell : ((PopupSceneDescription) parameters[0]).currentMonthDays) { 393 if (cell.getControl().isFocused()) { 394 setResult(new DateCellDescription(cell)); 395 } 396 } 397 for (Wrap<? extends DateCell> cell : ((PopupSceneDescription) parameters[0]).nextMonthDays) { 398 if (cell.getControl().isFocused()) { 399 setResult(new DateCellDescription(cell)); 400 } 401 } 402 } 403 }.dispatch(testedControl.getEnvironment(), sceneDescription); 404 } 405 } 406 407 public class PopupSceneDescription { 408 409 public List<Wrap<? extends DateCell>> previousMonthDays; 410 public List<Wrap<? extends DateCell>> currentMonthDays; 411 public List<Wrap<? extends DateCell>> nextMonthDays; 412 public List<Wrap<? extends DateCell>> weeksNumbers; 413 public List<Wrap<? extends DateCell>> daysNames; 414 public Wrap<? extends Button> nextMonthWrap; 415 public Wrap<? extends Label> currentMonthWrap; 416 public Wrap<? extends Button> previousMonthWrap; 417 public Wrap<? extends Button> nextYearWrap; 418 public Wrap<? extends Label> currentYearWrap; 419 public Wrap<? extends Button> previousYearWrap; 420 public Wrap<? extends DateCell> today; 421 public Wrap<? extends Label> secondaryLabel; 422 423 /** 424 * Performs the exploration of the popup and wraps it graphical 425 * components 426 */ 427 public void extractData() throws InterruptedException { 428 checkPopupVisibility(true); 429 popupScene = getPopupWrap(); 430 Parent<Node> sceneParent = popupScene.as(Parent.class, Node.class); 431 432 previousMonthWrap = sceneParent.lookup(Button.class, new ByStyleClass("left-button")).wrap(0); 433 previousYearWrap = sceneParent.lookup(Button.class, new ByStyleClass("left-button")).wrap(1); 434 435 nextMonthWrap = sceneParent.lookup(Button.class, new ByStyleClass("right-button")).wrap(0); 436 nextYearWrap = sceneParent.lookup(Button.class, new ByStyleClass("right-button")).wrap(1); 437 438 currentMonthWrap = sceneParent.lookup(Label.class, new ByStyleClass("spinner-label")).wrap(0); 439 currentYearWrap = sceneParent.lookup(Label.class, new ByStyleClass("spinner-label")).wrap(1); 440 441 weeksNumbers = new ArrayList<Wrap<? extends DateCell>>(); 442 Lookup weekNumbersLookup = sceneParent.lookup(DateCell.class, new ByStyleClass("week-number-cell")); 443 for (int i = 0; i < weekNumbersLookup.size(); i++) { 444 weeksNumbers.add(weekNumbersLookup.wrap(i)); 445 } 446 447 previousMonthDays = new ArrayList<Wrap<? extends DateCell>>(); 448 currentMonthDays = new ArrayList<Wrap<? extends DateCell>>(); 449 nextMonthDays = new ArrayList<Wrap<? extends DateCell>>(); 450 Lookup monthDaysLookup = sceneParent.lookup(DateCell.class, new ByStyleClass("day-cell")); 451 for (int i = 0; i < monthDaysLookup.size(); i++) { 452 if (((Wrap<? extends DateCell>) monthDaysLookup.wrap(i)).getControl().getStyleClass().contains("previous-month")) { 453 previousMonthDays.add(monthDaysLookup.wrap(i)); 454 } else if (((Wrap<? extends DateCell>) monthDaysLookup.wrap(i)).getControl().getStyleClass().contains("next-month")) { 455 nextMonthDays.add(monthDaysLookup.wrap(i)); 456 } else { 457 currentMonthDays.add(monthDaysLookup.wrap(i)); 458 } 459 } 460 461 daysNames = new ArrayList<Wrap<? extends DateCell>>(); 462 Lookup daysNamesLookup = sceneParent.lookup(DateCell.class, new ByStyleClass("day-name-cell")); 463 for (int i = 0; i < daysNamesLookup.size(); i++) { 464 daysNames.add(daysNamesLookup.wrap(i)); 465 } 466 467 final Lookup todayLookup = sceneParent.lookup(DateCell.class, new ByStyleClass("today")); 468 if (todayLookup.size() > 0) { 469 today = todayLookup.wrap(); 470 } else { 471 today = null; 472 } 473 474 final Lookup secondaryLabelLookup = sceneParent.lookup(Label.class, new ByStyleClass("secondary-text")); 475 if (secondaryLabelLookup.size() > 0) { 476 secondaryLabel = todayLookup.wrap(); 477 } else { 478 secondaryLabel = null; 479 } 480 } 481 482 public PopupInfoDescription getInfoDescription() throws InterruptedException { 483 extractData(); 484 return new PopupInfoDescription(this); 485 } 486 } 487 488 protected String getControlText() { 489 final Wrap<? extends TextField> tf = testedControl.as(Parent.class, Node.class).lookup(TextField.class).wrap(); 490 return new GetAction<String>() { 491 @Override 492 public void run(Object... os) throws Exception { 493 setResult(tf.getControl().getText()); 494 } 495 }.dispatch(testedControl.getEnvironment()); 496 } 497 498 protected void setDefaultDate() { 499 setDate(DEFAULT_DATE); 500 } 501 502 protected LocalDate getDate() { 503 return new GetAction<LocalDate>() { 504 @Override 505 public void run(Object... os) throws Exception { 506 setResult(testedControl.getControl().getValue()); 507 } 508 }.dispatch(testedControl.getEnvironment()); 509 } 510 511 protected void setDate(final LocalDate date) { 512 new GetAction() { 513 @Override 514 public void run(Object... os) throws Exception { 515 testedControl.getControl().setValue(date); 516 } 517 }.dispatch(testedControl.getEnvironment()); 518 } 519 520 protected void setChronology(final Chronology ch) { 521 new GetAction() { 522 @Override 523 public void run(Object... os) throws Exception { 524 testedControl.getControl().setChronology(ch); 525 } 526 }.dispatch(testedControl.getEnvironment()); 527 } 528 529 protected void waitShownText(final String expectedText) { 530 testedControl.waitState(new State<String>() { 531 public String reached() { 532 return getControlText(); 533 } 534 535 @Override 536 public String toString() { 537 return String.format("Waiting [%s] to be shown in the editor." 538 + "Got [%s]", expectedText, getControlText()); 539 } 540 }, expectedText); 541 } 542 543 void checkExpectedDate(LocalDate expected) { 544 LocalDate actual = new GetAction<LocalDate>() { 545 @Override public void run(Object... parameters) throws Exception { 546 setResult(testedControl.getControl().getValue()); 547 } 548 }.dispatch(testedControl.getEnvironment()); 549 assertEquals(expected, actual); 550 } 551 552 private int determineDaysInMonth(YearMonth month) { 553 return month.atDay(1).plusMonths(1).minusDays(1).getDayOfMonth(); 554 } 555 556 protected void getDays() { 557 } 558 559 private String getText(final Wrap<? extends Text> textNodeWrap) { 560 return new GetAction<String>() { 561 @Override 562 public void run(Object... os) throws Exception { 563 setResult(textNodeWrap.getControl().getText()); 564 } 565 }.dispatch(textNodeWrap.getEnvironment()); 566 } 567 568 private String getLabelText(final Wrap<? extends Label> labelNodeWrap) { 569 return new GetAction<String>() { 570 @Override 571 public void run(Object... os) throws Exception { 572 setResult(labelNodeWrap.getControl().getText()); 573 } 574 }.dispatch(labelNodeWrap.getEnvironment()); 575 } 576 577 protected enum Properties { 578 579 prefWidth, prefHeight, chronology, dayCellFactory, 580 converter, showWeekNumbers, hover, showing, editable, 581 prompttext, focused, pressed, armed, width} 582 583 /** 584 * By providing correct map of checked fields it is possible to examine 585 * PopupInfoDescription instance. 586 */ 587 public static class DateState implements State<Boolean> { 588 589 Map<String, String> expectedState; 590 Map<String, String> actualState; 591 PopupSceneDescription description; 592 PopupInfoDescription info; 593 594 public DateState(Map<String, String> expectedState, PopupSceneDescription description) { 595 this.expectedState = expectedState; 596 this.description = description; 597 actualState = new HashMap<String, String>(expectedState.size()); 598 } 599 600 public Boolean reached() { 601 boolean isReached = true; 602 try { 603 info = description.getInfoDescription(); 604 for (String checkedField : expectedState.keySet()) { 605 actualState.put(checkedField, String.valueOf(info.getClass().getField(checkedField).get(info)).toLowerCase()); 606 isReached &= expectedState.get(checkedField).toLowerCase().equals(actualState.get(checkedField)); 607 } 608 } catch(InterruptedException iex) { 609 Logger.getLogger(TestBase.class.getName()).log(Level.SEVERE, null, iex); 610 } finally { 611 return isReached ? Boolean.TRUE : null; 612 } 613 } 614 615 @Override 616 public String toString() { 617 StringBuilder sb = new StringBuilder("["); 618 for (String key : expectedState.keySet()) { 619 sb.append(String.format("Expected: [%s], Actual: [%s]", expectedState.get(key), actualState.get(key))); 620 sb.append("\n"); 621 } 622 623 sb.append("]"); 624 return sb.toString(); 625 } 626 } 627 628 /* 629 * Context menu methods. 630 */ 631 632 final Lookup<Scene> contextMenuLookup = Root.ROOT.lookup( 633 new LookupCriteria<Scene>() { 634 public boolean check(Scene cntrl) { 635 return cntrl.getWidth() <= 175.0 + (Utils.isLinux() ? 7 : 0) 636 && cntrl.getHeight() <= 82.0 + (Utils.isLinux() ? 5 : 0); 637 } 638 }); 639 640 /* 641 * Makes right mouse click on the popup. 642 */ 643 void openContextMenu() throws InterruptedException { 644 waitPopupShowingState(true); 645 final Wrap<? extends Scene> popupWrap = getPopupWrap(); 646 popupWrap.mouse().click(1, popupWrap.getClickPoint(), MouseButtons.BUTTON3); 647 waitPopupShowingState(true); 648 } 649 650 void waitContextMenuShowing(final boolean showing) { 651 testedControl.waitState(new State<Boolean>() { 652 public Boolean reached() { 653 int expected = showing ? 1 : 0; 654 return (contextMenuLookup.size() == expected) ? Boolean.TRUE : null; 655 } 656 657 @Override 658 public String toString() { return String.format("[Context menu is showing = %b]", showing); } 659 }); 660 } 661 662 Wrap getMenuItemLabelWrap(final String itemText) { 663 if (null == itemText) { 664 throw new IllegalArgumentException("[Cannot lookup 'null' menu item]"); 665 } 666 667 Wrap<? extends Scene> wrap = contextMenuLookup.wrap(); 668 Lookup lookup = wrap.as(Parent.class, Label.class).lookup(Label.class, new LookupCriteria<Label>() { 669 public boolean check(Label control) { 670 return control.getParent().getStyleClass().contains("menu-item") 671 && itemText.equals(control.getText()); 672 } 673 }); 674 675 assertEquals("[Context menu item 'Show Today' not fonud]", 1, lookup.size()); 676 677 return lookup.wrap(); 678 } 679 680 Wrap getMenuItemWrap(final String itemText) { 681 Wrap<? extends Scene> wrap = contextMenuLookup.wrap(); 682 Lookup lookup = wrap.as(Parent.class, Region.class).lookup(Region.class, new LookupCriteria<Region>() { 683 public boolean check(Region control) { 684 685 if (!control.getStyleClass().contains("menu-item")) return false; 686 687 for (Object object : control.getChildrenUnmodifiable()) { 688 if (Label.class.isAssignableFrom(object.getClass()) 689 && itemText.equals(((Label) object).getText())) { 690 691 return true; 692 } 693 } 694 695 return false; 696 } 697 }); 698 699 assertEquals(String.format("[Context menu item '%s' not fonud]", itemText), 1, lookup.size()); 700 701 return lookup.wrap(); 702 } 703 704 void contextMenuShowToday() throws InterruptedException { 705 openContextMenu(); 706 getMenuItemWrap("Show Today").mouse().click(); 707 } 708 709 void contextMenuShowWeekNumbers() throws InterruptedException { 710 openContextMenu(); 711 getMenuItemWrap("Show Week Numbers").mouse().click(); 712 } 713 714 Wrap<? extends Scene> getContextMenuWrap() { 715 return contextMenuLookup.wrap(); 716 } 717 718 Wrap getContextMenuContentWrap() { 719 return getContextMenuWrap().as(Parent.class, Region.class) 720 .lookup(Region.class, new ByStyleClass("context-menu")).wrap(); 721 } 722 723 /* 724 * Getter and setter wrappers 725 */ 726 void setDayCellFactory(Callback<DatePicker, DateCell> dayCellFactory) { 727 new GetAction<Void>() { 728 @Override public void run(Object... parameters) throws Exception { 729 testedControl.getControl().setDayCellFactory((Callback<DatePicker, DateCell>) parameters[0]); 730 } 731 }.dispatch(testedControl.getEnvironment(), dayCellFactory); 732 } 733 734 Callback<DatePicker, DateCell> getDayCellFactory() { 735 return new GetAction<Callback<DatePicker, DateCell>>() { 736 @Override public void run(Object... parameters) throws Exception { 737 setResult(testedControl.getControl().getDayCellFactory()); 738 } 739 }.dispatch(testedControl.getEnvironment()); 740 } 741 742 void setConverter(StringConverter<LocalDate> converter) { 743 new GetAction<Void>() { 744 @Override public void run(Object... parameters) throws Exception { 745 testedControl.getControl().setConverter((StringConverter<LocalDate>) parameters[0]); 746 } 747 }.dispatch(testedControl.getEnvironment(), converter); 748 } 749 750 StringConverter<LocalDate> getConverter() { 751 return new GetAction<StringConverter>() { 752 @Override public void run(Object... parameters) throws Exception { 753 setResult(testedControl.getControl().getConverter()); 754 } 755 }.dispatch(testedControl.getEnvironment()); 756 } 757 }