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