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 java.time.LocalDate;
  28 import java.time.Month;
  29 import java.time.chrono.Chronology;
  30 import java.util.Arrays;
  31 import java.util.Comparator;
  32 import java.util.HashMap;
  33 import java.util.logging.Level;
  34 import java.util.logging.Logger;
  35 import javafx.scene.Node;
  36 import javafx.scene.control.DateCell;
  37 import javafx.scene.control.DatePicker;
  38 import javafx.scene.control.TextInputControl;
  39 import javafx.scene.control.test.datepicker.DatePickerApp.DummyConverter;
  40 import javafx.scene.control.test.datepicker.DatePickerApp.LocalDateConverter;
  41 import javafx.scene.control.test.datepicker.DatePickerApp.WorkingDays;
  42 import static javafx.scene.control.test.datepicker.TestBase.testedControl;
  43 import javafx.scene.control.test.util.PropertyTest;
  44 import javafx.scene.control.test.utils.ptables.AbstractPropertyController.SettingType;
  45 import javafx.util.Callback;
  46 import javafx.util.StringConverter;
  47 import org.jemmy.Point;
  48 import org.jemmy.action.GetAction;
  49 import org.jemmy.control.Wrap;
  50 import org.jemmy.fx.ByStyleClass;
  51 import org.jemmy.fx.control.TextInputControlDock;
  52 import org.jemmy.interfaces.Keyboard.KeyboardButton;
  53 import org.jemmy.interfaces.Keyboard.KeyboardButtons;
  54 import org.jemmy.interfaces.Keyboard.KeyboardModifiers;
  55 import org.jemmy.interfaces.Modifier;
  56 import org.jemmy.interfaces.Parent;
  57 import org.jemmy.timing.State;
  58 import static org.junit.Assert.*;
  59 import org.junit.Test;
  60 import org.junit.runner.RunWith;
  61 import test.javaclient.shared.FilteredTestRunner;
  62 
  63 /**
  64  * @author Alexander Kirov, Dmitry Zinkevich
  65  *
  66  */
  67 @RunWith(FilteredTestRunner.class)
  68 public class DatePickerTest extends TestBase {
  69     Double width;
  70 
  71     void checkFinalState() {
  72         checkTextFieldValue(Properties.width, width.doubleValue());
  73         defaultController.check();
  74     }
  75 
  76     void rememberInitialState(Enum... excludePropertiesList) {
  77         width = new GetAction<Double>() {
  78             @Override
  79             public void run(Object... parameters) throws Exception {
  80                 setResult(Double.valueOf(testedControl.getControl().getWidth()));
  81             }
  82         }.dispatch(testedControl.getEnvironment());
  83 
  84         initChangingController(parent);
  85         defaultController.include().allTables().allProperties().allCounters().apply();
  86         defaultController.exclude().allTables().properties(excludePropertiesList).apply();
  87         defaultController.fixCurrentState();
  88     }
  89 
  90     /**
  91      * Checks that week numbers have been rendered.
  92      */
  93     @Test(timeout = 10000)
  94     public void weekNumbersScreenshotTest() throws Throwable {
  95         setDate(LocalDate.of(1990, Month.OCTOBER, 11));
  96         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
  97         setPropertyByToggleClick(SettingType.SETTER, Properties.showWeekNumbers, Boolean.TRUE);
  98         showPopup();
  99 
 100         checkFinalState();
 101 
 102         checkScreenshot("DatePicker-weekNumbers", getRootWrap(getPopupWrap()));
 103         throwScreenshotError();
 104     }
 105 
 106     /**
 107      * Checks that the current date is shown by default in the DateChooser.
 108      */
 109     @Test(timeout = 10000)
 110     public void currentDateShownTest() throws InterruptedException {
 111         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 112         clickDropDownButton();
 113         waitPopupShowingState(true);
 114 
 115         PopupSceneDescription description = new PopupSceneDescription();
 116         final PopupInfoDescription infoDescription = description.getInfoDescription();
 117         LocalDate now = LocalDate.now();
 118 
 119         assertEquals(Integer.parseInt(infoDescription.year), now.getYear());
 120         assertEquals(infoDescription.monthName.toLowerCase(), now.getMonth().toString().toLowerCase());
 121         assertEquals(infoDescription.today.mainDate, now.getDayOfMonth());
 122 
 123         boolean found = false;
 124         for (DateCellDescription descriptionVar : infoDescription.currentMonthDays) {
 125             if (descriptionVar.mainDate == now.getDayOfMonth()) {
 126                 found = true;
 127             }
 128         }
 129         assertTrue(found);
 130 
 131         checkFinalState();
 132     }
 133 
 134     /**
 135      * Checks that previous month button works as expected.
 136      */
 137     @Test(timeout = 10000)
 138     public void correctPreviousMonthTest() throws InterruptedException {
 139         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 140         clickDropDownButton();
 141         waitPopupShowingState(true);
 142 
 143         final PopupSceneDescription description = new PopupSceneDescription();
 144         final PopupInfoDescription infoDescription = description.getInfoDescription();
 145 
 146         final int initialDaysNum = description.currentMonthDays.size();
 147 
 148         description.previousMonthWrap.mouse().click();
 149 
 150         testedControl.waitState(new State() {
 151             public Object reached() {
 152                 PopupInfoDescription infoDescription2 = null;
 153                 try {
 154                     infoDescription2 = description.getInfoDescription();
 155                 } catch (InterruptedException ex) {
 156                     Logger.getLogger(DatePickerTest.class.getName()).log(Level.SEVERE, null, ex);
 157                 }
 158 
 159                 if (Month.valueOf(infoDescription.monthName.toUpperCase()).minus(1).equals(Month.valueOf(infoDescription2.monthName.toUpperCase()))
 160                     && (initialDaysNum != description.currentMonthDays.size()
 161                         || infoDescription.monthName.equalsIgnoreCase("AUGUST")
 162                         || infoDescription.monthName.equalsIgnoreCase("JANUARY"))) {
 163                     return true;
 164                 } else {
 165                     return null;
 166                 }
 167             }
 168         });
 169 
 170         checkFinalState();
 171     }
 172 
 173     /**
 174      * Checks that next month button works as expected.
 175      */
 176     @Test(timeout = 10000)
 177     public void correctNextMonthTest() throws InterruptedException {
 178         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 179         clickDropDownButton();
 180         waitPopupShowingState(true);
 181 
 182         final PopupSceneDescription description = new PopupSceneDescription();
 183         final PopupInfoDescription infoDescription = description.getInfoDescription();
 184 
 185         final int initialDaysNum = description.currentMonthDays.size();
 186 
 187         description.nextMonthWrap.mouse().click();
 188 
 189         testedControl.waitState(new State() {
 190             public Object reached() {
 191                 PopupInfoDescription infoDescription2 = null;
 192                 try {
 193                     infoDescription2 = description.getInfoDescription();
 194                 } catch (InterruptedException ex) {
 195                     Logger.getLogger(DatePickerTest.class.getName()).log(Level.SEVERE, null, ex);
 196                 }
 197                 if (Month.valueOf(infoDescription.monthName.toUpperCase()).plus(1).equals(Month.valueOf(infoDescription2.monthName.toUpperCase()))
 198                     && (initialDaysNum != description.currentMonthDays.size()
 199                         || infoDescription.monthName.equalsIgnoreCase("JULY")
 200                         || infoDescription.monthName.equalsIgnoreCase("DECEMBER"))) {
 201                     return true;
 202                 } else {
 203                     return null;
 204                 }
 205             }
 206         });
 207 
 208         checkFinalState();
 209     }
 210 
 211     /**
 212      * Checks that arrows which increase/decrease year work correctly
 213      */
 214     @Test(timeout = 10000)
 215     public void yearNavigationTest() throws InterruptedException {
 216         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 217         setDate(LocalDate.of(2012, 5, 9));
 218         clickDropDownButton();
 219 
 220         PopupSceneDescription description = new PopupSceneDescription();
 221         description.extractData();
 222         description.previousYearWrap.mouse().click();
 223 
 224         HashMap<String, String> expectedState = new HashMap<String, String>(2);
 225         expectedState.put("monthName", "May");
 226         expectedState.put("year", "2011");
 227         testedControl.waitState(new DateState(expectedState, description));
 228 
 229         description.extractData(); description.currentMonthDays.get(30).mouse().click();
 230         waitShownText("5/31/2011");
 231 
 232         setDate(LocalDate.of(2012, 2, 29));
 233         clickDropDownButton();
 234         description = new PopupSceneDescription();
 235         description.extractData(); description.nextYearWrap.mouse().click();
 236         expectedState.put("monthName", "February");
 237         expectedState.put("year", "2013");
 238         testedControl.waitState(new DateState(expectedState, description));
 239 
 240         description.extractData(); description.currentMonthDays.get(27).mouse().click();
 241         waitShownText("2/28/2013");
 242 
 243         checkFinalState();
 244     }
 245 
 246     /**
 247      * Checks that when mouse clicks the first or the last cell
 248      * in the DateChooser then the current month is set to the previous or
 249      * to the next from current respectively.
 250      */
 251     @Test(timeout = 10000)
 252     public void extremeDateCellsChangeCurrentMonth() throws InterruptedException {
 253         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 254         setDate(LocalDate.of(2000, 1, 27));
 255         clickDropDownButton();
 256 
 257         PopupSceneDescription description = new PopupSceneDescription();
 258         description.extractData(); description.previousMonthDays.get(0).mouse().click();
 259 
 260         HashMap<String, String> expectedState = new HashMap<String, String>(2);
 261         expectedState.put("monthName", "December");
 262         expectedState.put("year", "1999");
 263         testedControl.waitState(new DateState(expectedState, description));
 264 
 265         clickDropDownButton();
 266         description.extractData(); description.currentMonthDays.get(30).mouse().click();
 267         waitShownText("12/31/1999");
 268 
 269         setDate(LocalDate.of(2019, 12, 20));
 270         clickDropDownButton();
 271 
 272         description = new PopupSceneDescription();
 273         description.extractData(); description.nextMonthDays.get(description.nextMonthDays.size() - 1).mouse().click();
 274         expectedState.put("monthName", "January");
 275         expectedState.put("year", "2020");
 276         testedControl.waitState(new DateState(expectedState, description));
 277 
 278         clickDropDownButton();
 279         description.extractData(); description.currentMonthDays.get(26).mouse().click();
 280         waitShownText("1/27/2020");
 281         checkFinalState();
 282     }
 283 
 284     /**
 285      * Checks that when navigating in horizontal or vertical direction
 286      * the switching between days and months occurs correctly.
 287      *
 288      * Also, tests for month/year navigation, respectively Control+PgUp/Control+PgDn and PgUp/PgDn
 289      * @see <a href="https://javafx-jira.kenai.com/browse/RT-32493">RT-32493</a> and <a href="https://javafx-jira.kenai.com/browse/RT-32492">RT-32492</a>
 290      */
 291     @Test(timeout = 20000)
 292     public void keyboardNavigation() throws InterruptedException {
 293         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 294         setDate(LocalDate.of(2013, 01, 06));
 295         clickDropDownButton();
 296         waitPopupShowingState(true);
 297 
 298         scene.keyboard().pushKey(KeyboardButtons.LEFT);
 299         PopupSceneDescription description = new PopupSceneDescription();
 300         description.extractData();
 301 
 302         //Focus must be on 1/5/2013
 303         description.currentMonthDays.get(4).waitProperty("isFocused", Boolean.TRUE);
 304 
 305         for (int i = 0; i < 5; i++) scene.keyboard().pushKey(KeyboardButtons.LEFT);
 306 
 307         //Expect switching to the previous month and year
 308         HashMap<String, String> expectedState = new HashMap<String, String>(3);
 309         expectedState.put("monthName", "december");
 310         expectedState.put("year", "2012");
 311         expectedState.put("focusedDay", "31");
 312         description.extractData();
 313         testedControl.waitState(new DateState(expectedState, description));
 314 
 315         //Expect to switch to the next month and year
 316         scene.keyboard().pushKey(KeyboardButtons.DOWN);
 317         expectedState.put("monthName", "january");
 318         expectedState.put("year", "2013");
 319         expectedState.put("focusedDay", "7");
 320         description.extractData();
 321         testedControl.waitState(new DateState(expectedState, description));
 322 
 323         for (int i = 0; i < 6; i++) scene.keyboard().pushKey(KeyboardButtons.RIGHT);
 324 
 325         //Expect to move to the next week
 326         expectedState.put("monthName", "january");
 327         expectedState.put("year", "2013");
 328         expectedState.put("focusedDay", "13");
 329         description.extractData();
 330         testedControl.waitState(new DateState(expectedState, description));
 331 
 332         for (int i = 0; i < 2; i++) scene.keyboard().pushKey(KeyboardButtons.DOWN);
 333         for (int i = 0; i < 5; i++) scene.keyboard().pushKey(KeyboardButtons.RIGHT);
 334 
 335         //Expect to move to the next month
 336         expectedState.put("monthName", "february");
 337         expectedState.put("year", "2013");
 338         expectedState.put("focusedDay", "1");
 339         description.extractData();
 340         testedControl.waitState(new DateState(expectedState, description));
 341 
 342         scene.keyboard().pushKey(KeyboardButtons.RIGHT);
 343         scene.keyboard().pushKey(KeyboardButtons.UP);
 344 
 345         //Expect to move to the prev month
 346         expectedState.put("monthName", "january");
 347         expectedState.put("year", "2013");
 348         expectedState.put("focusedDay", "26");
 349         description.extractData();
 350         testedControl.waitState(new DateState(expectedState, description));
 351 
 352         for (int i = 0; i < 3; ++i)
 353             scene.keyboard().pushKey(KeyboardButtons.PAGE_DOWN, KeyboardModifiers.CTRL_DOWN_MASK);
 354 
 355         //Expect to move forward in three years
 356         expectedState.put("monthName", "january");
 357         expectedState.put("year", "2016");
 358         expectedState.put("focusedDay", "26");
 359         description.extractData();
 360         testedControl.waitState(new DateState(expectedState, description));
 361 
 362         scene.keyboard().pushKey(KeyboardButtons.PAGE_UP, KeyboardModifiers.CTRL_DOWN_MASK);
 363 
 364         //Expect to move backward for one years
 365         expectedState.put("monthName", "january");
 366         expectedState.put("year", "2015");
 367         expectedState.put("focusedDay", "26");
 368         description.extractData();
 369         testedControl.waitState(new DateState(expectedState, description));
 370 
 371         for (int i = 0; i < 4; ++i)
 372             scene.keyboard().pushKey(KeyboardButtons.PAGE_UP);
 373 
 374         //Expect to move backward for four months
 375         expectedState.put("monthName", "september");
 376         expectedState.put("year", "2014");
 377         expectedState.put("focusedDay", "26");
 378         description.extractData();
 379         testedControl.waitState(new DateState(expectedState, description));
 380 
 381         for (int i = 0; i < 6; ++i)
 382             scene.keyboard().pushKey(KeyboardButtons.PAGE_DOWN);
 383 
 384         //Expect to move forward for six months
 385         expectedState.put("monthName", "march");
 386         expectedState.put("year", "2015");
 387         expectedState.put("focusedDay", "26");
 388         description.extractData();
 389         testedControl.waitState(new DateState(expectedState, description));
 390         checkFinalState();
 391     }
 392 
 393     /**
 394      * Checks all possible ways to select a date with the keyboard.
 395      */
 396     @Test(timeout = 10000)
 397     public void keyboardDateSelection() throws InterruptedException {
 398         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 399 
 400         clickDropDownButton();
 401         waitPopupShowingState(true);
 402 
 403         PopupSceneDescription description = new PopupSceneDescription();
 404         description.extractData();
 405         description.currentMonthDays.get(14).mouse().click();
 406         waitPopupShowingState(false);
 407         checkExpectedDate(LocalDate.now().withDayOfMonth(15));
 408 
 409         clickDropDownButton();
 410         scene.keyboard().pushKey(KeyboardButtons.DOWN);
 411         scene.keyboard().pushKey(KeyboardButtons.SPACE);
 412         checkExpectedDate(LocalDate.now().withDayOfMonth(22));
 413 
 414         clickDropDownButton();
 415         for (int i = 0; i < 2; i++) scene.keyboard().pushKey(KeyboardButtons.UP);
 416         scene.keyboard().pushKey(KeyboardButtons.ENTER);
 417         checkExpectedDate(LocalDate.now().withDayOfMonth(8));
 418 
 419         clickDropDownButton();
 420         scene.keyboard().pushKey(KeyboardButtons.DOWN);
 421         scene.keyboard().pushKey(KeyboardButtons.ESCAPE);
 422         checkExpectedDate(LocalDate.now().withDayOfMonth(8));
 423 
 424         checkFinalState();
 425     }
 426 
 427     /**
 428      * Check that after typing a correct date
 429      * the DateChooser will also show it.
 430      * First time the default converter is used which
 431      * reads date in en_US format according to test default locale.
 432      * The second time a custom converter is used in the format yyyy-MM-dd.
 433      */
 434     @Test(timeout = 20000)
 435     public void customConverter() throws InterruptedException {
 436         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 437 
 438         final StringConverter converter = new DummyConverter();
 439         setConverter(converter);
 440         assertSame(converter, getConverter());
 441         selectObjectFromChoiceBox(SettingType.UNIDIRECTIONAL, Properties.converter, null);
 442 
 443         String dates[][] = {{"7/4/1776", "July", "4", "1776"}, {"1779-07-14", "July", "14", "1779"}};
 444 
 445         TextInputControlDock text = new TextInputControlDock(parent, new ByStyleClass<TextInputControl>("date-picker-display-node"));
 446         HashMap<String, String> expectedState = new HashMap<String, String>(3);
 447 
 448         for (int i = 0; i < 2; i++) {
 449             String[] dateParts = dates[i];
 450             text.clear();
 451             text.asSelectionText().type(dateParts[0]);
 452             text.keyboard().pushKey(KeyboardButtons.ENTER);
 453             waitShownText(dateParts[0]);
 454 
 455             clickDropDownButton();
 456             PopupSceneDescription description = new PopupSceneDescription();
 457             description.extractData();
 458 
 459             expectedState.put("monthName", dateParts[1]);
 460             expectedState.put("selectedDay", dateParts[2]);
 461             expectedState.put("year", dateParts[3]);
 462 
 463             testedControl.waitState(new DateState(expectedState, description));
 464 
 465             testedControl.keyboard().pushKey(KeyboardButtons.ESCAPE);
 466             waitPopupShowingState(false);
 467 
 468             //The second time test custom converter
 469             selectObjectFromChoiceBox(SettingType.UNIDIRECTIONAL, Properties.converter, LocalDateConverter.class);
 470         }
 471         checkFinalState();
 472     }
 473 
 474     /**
 475      * Checks that disabled DateCell can't be selected and
 476      * that state doesn't change after.
 477      */
 478     @Test(timeout = 10000)
 479     public void daysRestriction() throws InterruptedException {
 480         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 481 
 482         final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() {
 483             public DateCell call(DatePicker param) { return new DateCell(); }
 484         };
 485         setDayCellFactory(dayCellFactory);
 486         assertSame(dayCellFactory, getDayCellFactory());
 487 
 488         selectObjectFromChoiceBox(SettingType.BIDIRECTIONAL, Properties.dayCellFactory, WorkingDays.class);
 489         setDate(LocalDate.of(2020, 10, 31));
 490         clickDropDownButton();
 491         waitPopupShowingState(true);
 492 
 493         PopupSceneDescription description = new PopupSceneDescription();
 494         description.extractData();
 495         Wrap<? extends DateCell> cellWrap = description.currentMonthDays.get(24);
 496         DateCellDescription cell = new DateCellDescription(cellWrap);
 497         assertEquals("[Selected wrong day]", 25, cell.mainDate);
 498 
 499         cellWrap.mouse().click();
 500         waitPopupShowingState(true);
 501 
 502         HashMap<String, String> expectedState = new HashMap<String, String>(2);
 503         expectedState.put("selectedDay", "31");
 504         expectedState.put("monthName", "October");
 505         expectedState.put("year", "2020");
 506         testedControl.waitState(new DateState(expectedState, description));
 507         waitShownText("10/31/2020");
 508 
 509         testedControl.keyboard().pushKey(KeyboardButtons.ESCAPE);
 510         setDate(LocalDate.of(2020, Month.OCTOBER, 25));
 511         checkFinalState();
 512     }
 513 
 514     /**
 515      * Changes value of the property 'showWeekNumbers'
 516      * and checks that DateChooser is rendered correctly.
 517      * The value is set via api and via context menu.
 518      */
 519     @Test(timeout = 20000)
 520     public void showWeekNumbersProperty() throws InterruptedException {
 521         assertFalse(new GetAction<Boolean>() {
 522             @Override public void run(Object... parameters) throws Exception {
 523                 setResult(new DatePicker().isShowWeekNumbers());
 524             }
 525         }.dispatch(testedControl.getEnvironment()).booleanValue());
 526 
 527         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 528 
 529         setDate(LocalDate.of(2013, Month.DECEMBER, 31));
 530         for(SettingType settingType : SettingType.values()) {
 531             System.out.format("Testing binding:%s\n", settingType.toString());
 532             setPropertyByToggleClick(settingType, Properties.showWeekNumbers, Boolean.TRUE);
 533 
 534             checkTextFieldText(Properties.showWeekNumbers, "true");
 535 
 536             clickDropDownButton(); waitPopupShowingState(true);
 537 
 538             PopupSceneDescription description = new PopupSceneDescription();
 539             description.extractData();
 540             assertEquals("[Incorrect count of week numbers]", 6, description.weeksNumbers.size());
 541 
 542             description.weeksNumbers.sort(new Comparator<Wrap<? extends DateCell>>() {
 543                 public int compare(Wrap<? extends DateCell> o1, Wrap<? extends DateCell> o2) {
 544                     return o1.getScreenBounds().y - o2.getScreenBounds().y;
 545                 }
 546             });
 547 
 548             Integer[] expectedNumbers = {49, 50, 51, 52, 1, 2};
 549             assertEquals("[Weeks are not in correct order]", Arrays.asList(expectedNumbers), description.getInfoDescription().weekNumbers);
 550 
 551             setPropertyByToggleClick(settingType, Properties.showWeekNumbers, Boolean.FALSE);
 552 
 553             description.extractData();
 554             assertEquals("[No week numbers expected]", 0, description.weeksNumbers.size());
 555 
 556             scene.mouse().click(1, new Point(2, 2));
 557             switchOffBinding(settingType, Properties.showWeekNumbers);
 558         }
 559         checkFinalState();
 560     }
 561 
 562     /**
 563      * Checks bindings of the 'chronology' property.
 564      */
 565     @Test(timeout = 10000)
 566     public void chronologyProperty() {
 567         rememberInitialState();
 568 
 569         final String PROPERTY_NAME = "ThaiBuddhist";
 570         final Chronology CHRONOLOGY = Chronology.of(PROPERTY_NAME);
 571         for(SettingType settingType : SettingType.values()) {
 572             System.out.format("Testing binding:%s\n", settingType.toString());
 573             selectObjectFromChoiceBox(settingType, Properties.chronology, CHRONOLOGY);
 574 
 575             checkTextFieldText(Properties.chronology, PROPERTY_NAME);
 576 
 577             switchOffBinding(settingType, Properties.chronology);
 578             selectObjectFromChoiceBox(SettingType.SETTER, Properties.chronology, Chronology.of("ISO"));
 579         }
 580         checkFinalState();
 581     }
 582 
 583     /**
 584      * Check value of the 'showing' property.
 585      */
 586     @Test(timeout = 20000)
 587     public void showingProperty() throws InterruptedException {
 588         assertFalse(new GetAction<Boolean>() {
 589             @Override public void run(Object... parameters) throws Exception {
 590                 setResult(new DatePicker().showingProperty().getValue());
 591             }
 592         }.dispatch(testedControl.getEnvironment()).booleanValue());
 593 
 594         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 595 
 596         clickDropDownButton();
 597         waitPopupShowingState(true);
 598 
 599         clickDropDownButton();
 600         waitPopupShowingState(false);
 601 
 602         testedControl.mouse().click();
 603         waitPopupShowingState(false);
 604 
 605         Object[][] keyCombinations = {
 606             {KeyboardButtons.F4},
 607             {KeyboardButtons.DOWN, KeyboardModifiers.ALT_DOWN_MASK},
 608             {KeyboardButtons.UP, KeyboardModifiers.ALT_DOWN_MASK}
 609         };
 610 
 611         for(Object[] keyCombo : keyCombinations) {
 612             System.out.println(Arrays.toString(keyCombo));
 613             if (keyCombo.length == 1) {
 614                 testedControl.keyboard().pushKey((KeyboardButton) keyCombo[0]);
 615             } else {
 616                 testedControl.keyboard().pushKey((KeyboardButton) keyCombo[0], (Modifier) keyCombo[1]);
 617             }
 618             waitPopupShowingState(true);
 619             testedControl.keyboard().pushKey(KeyboardButtons.ESCAPE);
 620             waitPopupShowingState(false);
 621         }
 622 
 623         checkFinalState();
 624     }
 625 
 626     /**
 627      * Checks bindings of the 'editable' property.
 628      */
 629     @Test(timeout = 20000)
 630     public void editableProperty() {
 631         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 632         final LocalDate INITIAL_DATE = LocalDate.of(2041, Month.SEPTEMBER, 22);
 633         final String INITIAL_DATE_TEXT = "9/22/2041";
 634         final LocalDate TESTED_DATE = LocalDate.of(2000, Month.JANUARY, 1);
 635         final String DATE_TEXT = "1/1/2000";
 636 
 637         setDate(INITIAL_DATE);
 638         waitShownText(INITIAL_DATE_TEXT);
 639         setPropertyByToggleClick(SettingType.SETTER, Properties.editable, Boolean.FALSE);
 640 
 641         //Test non editable state
 642         TextInputControlDock input = new TextInputControlDock(testedControl.as(Parent.class, Node.class));
 643         selectAllText(input);
 644         assertEquals("[Text was not selected]", INITIAL_DATE_TEXT, input.asSelectionText().selection());
 645         input.keyboard().pushKey(KeyboardButtons.A);
 646         input.keyboard().pushKey(KeyboardButtons.ENTER);
 647 
 648         waitShownText(INITIAL_DATE_TEXT);
 649 
 650         for(SettingType settingType : SettingType.values()) {
 651             System.out.format("Testing binding:%s\n", settingType.toString());
 652             setPropertyByToggleClick(settingType, Properties.editable, Boolean.TRUE);
 653 
 654             checkTextFieldText(Properties.editable, "true");
 655 
 656             input = new TextInputControlDock(testedControl.as(Parent.class, Node.class));
 657             selectAllText(input);
 658             assertEquals("[Text was not selected]", INITIAL_DATE_TEXT, input.asSelectionText().selection());
 659 
 660             input.type(DATE_TEXT);
 661             input.keyboard().pushKey(KeyboardButtons.ENTER);
 662             assertEquals("[Date was not typed]", TESTED_DATE, getDate());
 663             waitShownText(DATE_TEXT);
 664 
 665             switchOffBinding(settingType, Properties.editable);
 666             setPropertyByToggleClick(SettingType.SETTER, Properties.editable, Boolean.FALSE);
 667 
 668             //Restore initial state
 669             setDate(INITIAL_DATE);
 670             waitShownText(INITIAL_DATE_TEXT);
 671         }
 672         setPropertyByToggleClick(SettingType.SETTER, Properties.editable, Boolean.TRUE);
 673         checkFinalState();
 674     }
 675 
 676     /**
 677      * Check bindings of the 'prompt text' property
 678      */
 679     @Test(timeout = 10000)
 680     public void promptTextProperty() {
 681         rememberInitialState();
 682         assertTrue("[Propmpt text is empty by default]", new GetAction<Boolean>() {
 683             @Override public void run(Object... parameters) throws Exception {
 684                 setResult(new DatePicker().promptTextProperty().getValue().isEmpty());
 685             }
 686         }.dispatch(testedControl.getEnvironment()).booleanValue());
 687 
 688         final String TESTED_TEXT = "MM_dd_YY";
 689         final String DEFAULT_TEXT = "default";
 690 
 691         for(SettingType settingType : SettingType.values()) {
 692             System.out.format("Testing binding:%s\n", settingType.toString());
 693 
 694             setPropertyByTextField(settingType, Properties.prompttext, TESTED_TEXT);
 695             checkTextFieldText(Properties.prompttext, TESTED_TEXT);
 696 
 697             switchOffBinding(settingType, Properties.prompttext);
 698             setPropertyByTextField(SettingType.SETTER, Properties.prompttext, DEFAULT_TEXT);
 699         }
 700         checkFinalState();
 701     }
 702 
 703     /**
 704      * Test that TextField returned by getEditor() method remains the same after
 705      * changing editable property
 706      */
 707     @Test(timeout = 10000)
 708     public void editorProperty() throws Throwable {
 709         rememberInitialState(Properties.showing, Properties.hover, Properties.pressed, Properties.armed);
 710 
 711         new PropertyTest.EditorPropertyTest(testedControl).test();
 712 
 713         checkFinalState();
 714     }
 715 };