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.combobox;
  26 
  27 import client.test.ScreenshotCheck;
  28 import client.test.Smoke;
  29 import java.text.Format;
  30 import java.text.MessageFormat;
  31 import java.util.ArrayList;
  32 import java.util.EnumSet;
  33 import java.util.HashMap;
  34 import java.util.List;
  35 import java.util.Map;
  36 import javafx.beans.value.ObservableValue;
  37 import javafx.collections.FXCollections;
  38 import javafx.collections.ObservableList;
  39 import javafx.commons.SortValidator;
  40 import javafx.event.Event;
  41 import javafx.event.EventHandler;
  42 import javafx.geometry.Orientation;
  43 import javafx.scene.Node;
  44 import javafx.scene.control.ComboBox;
  45 import javafx.scene.control.Label;
  46 import javafx.scene.control.ListCell;
  47 import javafx.scene.control.ListView;
  48 import javafx.scene.control.ScrollBar;
  49 import javafx.scene.control.TextField;
  50 import static javafx.scene.control.test.combobox.ComboBoxApp.*;
  51 import static javafx.scene.control.test.combobox.TestBase.ITER;
  52 import javafx.scene.control.test.combobox.TestBase.Properties;
  53 import static javafx.scene.control.test.combobox.TestBase.testedControl;
  54 import javafx.scene.control.test.util.PropertyTest;
  55 import javafx.scene.control.test.utils.CustomMultipleSelectionModel;
  56 import javafx.scene.control.test.utils.CustomStringConverter;
  57 import static javafx.scene.control.test.utils.CustomStringConverter.FROM_STRING_PREFIX;
  58 import static javafx.scene.control.test.utils.CustomStringConverter.TO_STRING_PREFIX;
  59 import javafx.scene.control.test.utils.ptables.AbstractPropertyController.SettingType;
  60 import javafx.scene.shape.Polygon;
  61 import javafx.scene.shape.Rectangle;
  62 import javafx.util.Callback;
  63 import javafx.util.StringConverter;
  64 import javafx.util.converter.FormatStringConverter;
  65 import org.jemmy.Point;
  66 import org.jemmy.action.GetAction;
  67 import org.jemmy.control.Wrap;
  68 import org.jemmy.fx.ByStyleClass;
  69 import org.jemmy.fx.ByText;
  70 import org.jemmy.fx.NodeWrap;
  71 import org.jemmy.fx.Root;
  72 import org.jemmy.fx.control.ChoiceBoxWrap;
  73 import org.jemmy.fx.control.ListItemWrap.ListItemByObjectLookup;
  74 import org.jemmy.input.AbstractScroll;
  75 import org.jemmy.interfaces.Keyboard.KeyboardButton;
  76 import org.jemmy.interfaces.Keyboard.KeyboardButtons;
  77 import org.jemmy.interfaces.Keyboard.KeyboardModifiers;
  78 import org.jemmy.interfaces.Parent;
  79 import org.jemmy.interfaces.Selectable;
  80 import org.jemmy.interfaces.Text;
  81 import org.jemmy.lookup.Lookup;
  82 import org.jemmy.lookup.LookupCriteria;
  83 import org.jemmy.resources.StringComparePolicy;
  84 import org.jemmy.timing.State;
  85 import static org.junit.Assert.*;
  86 import org.junit.Test;
  87 import org.junit.runner.RunWith;
  88 import test.javaclient.shared.FilteredTestRunner;
  89 
  90 /**
  91  * @author Alexander Kirov
  92  *
  93  */
  94 @RunWith(FilteredTestRunner.class)
  95 public class ComboBoxTest extends TestBase {
  96 
  97     @ScreenshotCheck
  98     @Test(timeout = 300000)
  99     public void editablePropertyTest() throws Throwable {
 100         assertEquals((new ComboBox()).editableProperty().getValue(), false);
 101 
 102         testedControl.getEnvironment().setTimeout(Wrap.WAIT_STATE_TIMEOUT, 2000);
 103 
 104         for (SettingType btype : EnumSet.of(SettingType.BIDIRECTIONAL, SettingType.SETTER, SettingType.UNIDIRECTIONAL)) {
 105             for (int i = 0; i < 4; i++) {
 106                 setPropertyByToggleClick(btype, Properties.editable);
 107                 checkEditable(i % 2 == 0 ? true : false);
 108                 checkScreenshot("ComboBox_editable_[" + (i % 2 == 0 ? true : false) + "]", testedControl);
 109             }
 110         }
 111 
 112         throwScreenshotError();
 113     }
 114 
 115     @Smoke
 116     @Test(timeout = 300000)
 117     public void showingPropertyTest() throws InterruptedException {
 118         assertEquals((new ComboBox()).showingProperty().getValue(), false);
 119 
 120         clickDropDownButton();
 121         checkPopupShowing(true);
 122         clickDropDownButton();
 123         checkPopupShowing(false);
 124         testedControl.mouse().click();
 125         checkPopupShowing(true);
 126         checkButtonForPopupShowing(KeyboardButtons.F4);
 127         checkButtonForPopupShowing(KeyboardButtons.DOWN, KeyboardModifiers.ALT_DOWN_MASK);
 128         checkButtonForPopupShowing(KeyboardButtons.UP, KeyboardModifiers.ALT_DOWN_MASK);
 129 
 130         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 131         //We switched property and need to wait, until it will be applied, to click on buttons.
 132         Thread.sleep(1000);
 133 
 134         testedControl.mouse().click();
 135         checkPopupShowing(false);
 136         clickDropDownButton();
 137         checkPopupShowing(true);
 138         clickDropDownButton();
 139         checkPopupShowing(false);
 140     }
 141 
 142     private void checkButtonForPopupShowing(KeyboardButtons button, KeyboardModifiers... mdfs) throws InterruptedException {
 143         testedControl.keyboard().pushKey(button, mdfs);
 144         checkPopupShowing(false);
 145         testedControl.keyboard().pushKey(button, mdfs);
 146         checkPopupShowing(true);
 147     }
 148 
 149     @Smoke
 150     @Test(timeout = 300000)
 151     public void armedTest() {
 152         assertEquals((new ComboBox()).armedProperty().getValue(), false);
 153 
 154         testedControl.mouse().move();
 155         testedControl.mouse().press();
 156 
 157         checkTextFieldText(Properties.armed, "true");
 158 
 159         testedControl.mouse().release();
 160 
 161         checkTextFieldText(Properties.armed, "false");
 162         checkTextFieldText(Properties.showing, "true");
 163 
 164         testedControl.mouse().press();
 165 
 166         checkTextFieldText(Properties.armed, "true");
 167         checkTextFieldText(Properties.showing, "false");
 168 
 169         testedControl.mouse().release();
 170 
 171         checkTextFieldText(Properties.armed, "false");
 172         checkTextFieldText(Properties.showing, "false");
 173 
 174         testedControl.mouse().press();
 175         org.jemmy.Rectangle bounds = testedControl.getScreenBounds();
 176         testedControl.mouse().move(new Point(bounds.getWidth() + 5, testedControl.getScreenBounds().getHeight() + 5));
 177 
 178         checkTextFieldText(Properties.armed, "false");
 179     }
 180 
 181     @Smoke
 182     @Test(timeout = 300000)//RT-18945
 183     public void valuePropertyTest() throws InterruptedException {
 184         assertEquals((new ComboBox()).getValue(), null);
 185 
 186         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 187 
 188         setPropertyByTextField(SettingType.BIDIRECTIONAL, Properties.value, NEW_VALUE_1);
 189         checkTextFieldText(Properties.value, NEW_VALUE_1);
 190         assertEquals(getTextFieldText(), NEW_VALUE_1);
 191 
 192         setPropertyByTextField(SettingType.UNIDIRECTIONAL, Properties.value, NEW_VALUE_2);
 193         checkTextFieldText(Properties.value, NEW_VALUE_2);
 194         assertEquals(getTextFieldText(), NEW_VALUE_2);
 195 
 196         setPropertyByTextField(SettingType.SETTER, Properties.value, NEW_VALUE_1);
 197         checkTextFieldText(Properties.value, NEW_VALUE_1);
 198         assertEquals(getTextFieldText(), NEW_VALUE_1);
 199 
 200         switchOffBinding(SettingType.UNIDIRECTIONAL, Properties.value);
 201 
 202         for (int i = 0; i < ITER; i++) {
 203             addElement(String.valueOf(i), i);
 204         }
 205 
 206         for (int i = 0; i < ITER; i++) {
 207             testedControl.as(Selectable.class).selector().select(String.valueOf(i));
 208             assertEquals(getValue(), String.valueOf(i));
 209         }
 210 
 211         testedControl.as(Selectable.class).selector().select(String.valueOf(ITER - 1));
 212 
 213         //Do some actions to change state of control and verify value
 214         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 215         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 216         setPropertyByTextField(SettingType.BIDIRECTIONAL, Properties.promptText, "some text");
 217         clickDropDownButton();
 218         applyCustomSelectionModel();
 219         applyCustomStringConverter();
 220 
 221         assertEquals(getValue().toString(), "null");
 222         assertEquals(getTextFieldText(), "");
 223     }
 224 
 225     @ScreenshotCheck
 226     @Test(timeout = 300000)//RT-19225
 227     public void promptPropertyTest() throws Throwable {
 228         assertEquals((new ComboBox()).promptTextProperty().getValue(), null);
 229 
 230         //move focus from control. otherwise, we will not see prompt.
 231         requestFocusOnControl(testedControl);
 232         testedControl.keyboard().pushKey(KeyboardButtons.TAB);
 233 
 234         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 235 
 236         for (SettingType btype : EnumSet.of(SettingType.BIDIRECTIONAL, SettingType.SETTER, SettingType.UNIDIRECTIONAL)) {
 237             setPropertyByTextField(btype, Properties.promptText, btype.name());
 238             checkTextFieldText(Properties.promptText, btype.name());
 239             assertEquals(btype.name(), getTextFieldPrompt());
 240             checkScreenshot("ComboBox_PromptText_[" + btype.name() + "]", testedControl);
 241         }
 242         throwScreenshotError();
 243     }
 244 
 245     @ScreenshotCheck
 246     @Test(timeout = 300000)
 247     public void visibleRowCountPropertyTest() throws InterruptedException, Throwable {
 248         assertEquals((long) (new ComboBox()).visibleRowCountProperty().getValue(), 10);
 249 
 250         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.visibleRowCount, 6);
 251         checkTextFieldValue(Properties.visibleRowCount, 6);
 252 
 253         addElements(1, 2, 3, 4, 5, 6, 7);
 254 
 255         clickDropDownButton();
 256         checkScrollBarVisibility(true);
 257 
 258         Wrap<? extends ListView> list = getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap();
 259         Wrap<? extends ListCell> cell = list.as(Parent.class, Node.class).lookup(ListCell.class, new ListItemByObjectLookup<String>("1")).wrap();
 260         assertEquals(cell.getScreenBounds().getHeight() * 6, list.getScreenBounds().getHeight(), 4);
 261 
 262         removeFromPos(2);
 263 
 264         clickDropDownButton();
 265         checkScrollBarVisibility(false);
 266 
 267         setPropertyBySlider(SettingType.SETTER, Properties.visibleRowCount, 5);
 268         checkTextFieldValue(Properties.visibleRowCount, 5);
 269 
 270         clickDropDownButton();
 271         checkScrollBarVisibility(true);
 272         removeFromPos(5);
 273 
 274         setPropertyBySlider(SettingType.UNIDIRECTIONAL, Properties.visibleRowCount, 4);
 275         checkTextFieldValue(Properties.visibleRowCount, 4);
 276 
 277         testedControl.as(Selectable.class).selector().select("2");
 278 
 279         clickDropDownButton();
 280         checkScrollBarVisibility(true);
 281 
 282         checkScreenshot("ComboBox_visibleRowCount_4_visible_and_5_elements_and_3_removed", getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap());
 283         throwScreenshotError();
 284     }
 285 
 286     @ScreenshotCheck
 287     @Test(timeout = 300000)
 288     public void emptyDropDownScreenshotTest() throws InterruptedException, Throwable {
 289         clickDropDownButton();
 290         checkPopupShowing(true);
 291         checkScreenshot("ComboBox_emptyDropDown", getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap());
 292         throwScreenshotError();
 293     }
 294 
 295     @Smoke
 296     @Test(timeout = 300000)
 297     public void converterPropertyTest() throws InterruptedException {
 298         assertNotSame((new ComboBox()).getConverter(), null);
 299 
 300         assertTrue(new GetAction<Object>() {
 301             @Override
 302             public void run(Object... os) throws Exception {
 303                 setResult(((ComboBox) os[0]).getConverter());
 304             }
 305         }.dispatch(Root.ROOT.getEnvironment(),
 306                 testedControl.getControl()) instanceof StringConverter);
 307 
 308         String element = "Random element 1";
 309         addElement(element, 0);
 310 
 311         testedControl.as(Selectable.class).selector().select(element);
 312         checkSimpleListenerValue(Properties.selectedItem, element);
 313 
 314         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 315 
 316         assertTrue(new GetAction<Object>() {
 317             @Override
 318             public void run(Object... os) throws Exception {
 319                 setResult(((ComboBox) os[0]).getConverter());
 320             }
 321         }.dispatch(Root.ROOT.getEnvironment(),
 322                 testedControl.getControl()) instanceof StringConverter);
 323 
 324         String element2 = "Random element 2";
 325         addElement(element2, 1);
 326         testedControl.as(Selectable.class).selector().select(element2);
 327         checkSimpleListenerValue(Properties.selectedItem, element2);
 328         assertEquals(getTextFieldText(), element2);
 329 
 330         applyCustomStringConverter();
 331 
 332         assertTrue(new GetAction<Object>() {
 333             @Override
 334             public void run(Object... os) throws Exception {
 335                 setResult(((ComboBox) os[0]).converterProperty().getValue());
 336             }
 337         }.dispatch(Root.ROOT.getEnvironment(),
 338                 testedControl.getControl()) instanceof CustomStringConverter);
 339 
 340         String element3 = "Random element 3";
 341         addElement(element3, 2);
 342         testedControl.as(Selectable.class).selector().select(element3);
 343         checkSimpleListenerValue(Properties.selectedItem, element3);
 344         assertEquals(getTextFieldText(), TO_STRING_PREFIX + "3");
 345 
 346         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 347         testedControl.as(Selectable.class).selector().select(element2);
 348         checkSimpleListenerValue(Properties.selectedItem, element2);
 349     }
 350 
 351     @Smoke
 352     @Test(timeout = 300000)
 353     public void itemsPropertyTest() throws InterruptedException {
 354         assertNotSame((new ComboBox()).getItems(), null);
 355         assertTrue((new ComboBox()).getItems() instanceof ObservableList);
 356 
 357         checkListsEquality();
 358         for (int i = 0; i < 5; i++) {
 359             for (int j = 0; j < 5; j++) {
 360                 addElement(String.valueOf(j), j);
 361                 checkListsEquality();
 362             }
 363 
 364             for (int j = 0; j < 5; j++) {
 365                 removeFromPos(0);
 366                 checkListsEquality();
 367             }
 368         }
 369 
 370     }
 371 
 372     private void checkListsEquality() throws InterruptedException {
 373         //Equality: both are lists, size are equal, elements each by each are equal
 374         if (!testedControl.getProperty(Boolean.class, ChoiceBoxWrap.IS_SHOWING_PROP_NAME)) {
 375             clickDropDownButton();
 376         }
 377         assertEquals(((ListView) getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap().getControl()).getItems(), ((ComboBox) testedControl.getControl()).getItems());
 378     }
 379 
 380     //Test//Jonathan said, that there is no support for multiple
 381     // selection model now. So I'll wait until he will write it and check my
 382     // customMultipleSelection model class. So to write test now is impossible.
 383     public void customMultipleSelectionModelTest() throws InterruptedException {
 384         assertNotSame((new ComboBox()).getItems(), null);
 385 
 386         clickDropDownButton();
 387 
 388         applyCustomSelectionModel();
 389         clickDropDownButton();
 390 
 391         assertTrue(new GetAction<Object>() {
 392             @Override
 393             public void run(Object... os) throws Exception {
 394                 setResult(((ComboBox) os[0]).getSelectionModel());
 395             }
 396         }.dispatch(Root.ROOT.getEnvironment(),
 397                 testedControl.getControl()) instanceof CustomMultipleSelectionModel);
 398 
 399         addElements(1, 2, 3);
 400 
 401         for (int i = 1; i <= 3; i++) {
 402             testedControl.as(Selectable.class).selector().select(String.valueOf(i));
 403         }
 404     }
 405 
 406     @Smoke
 407     @Test(timeout = 300000)
 408     public void onActionPropertyTest() {
 409         assertTrue((new ComboBox()).getOnAction() == null);
 410         assertTrue(testedControl.getControl().getOnAction() instanceof EventHandler);
 411         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 0);
 412 
 413         addElements(1, 2, 3);
 414         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 0);
 415         testedControl.mouse().click();
 416         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 0);
 417         testedControl.as(Selectable.class).selector().select("2");
 418         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 1);
 419         testedControl.keyboard().pushKey(KeyboardButtons.UP);
 420         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 2);
 421         testedControl.keyboard().pushKey(KeyboardButtons.DOWN);
 422         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 3);
 423         testedControl.keyboard().pushKey(KeyboardButtons.UP, KeyboardModifiers.ALT_DOWN_MASK);
 424         testedControl.keyboard().pushKey(KeyboardButtons.DOWN, KeyboardModifiers.ALT_DOWN_MASK);
 425         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 3);
 426         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 427 
 428         testedControl.mouse().click();
 429         testedControl.mouse().click();
 430 
 431         testedControl.keyboard().pushKey(KeyboardButtons.A);
 432         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 3);
 433         testedControl.keyboard().pushKey(KeyboardButtons.ENTER);
 434         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 4);
 435         setPropertyByTextField(SettingType.BIDIRECTIONAL, Properties.value, NEW_VALUE_1);
 436         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 6);
 437         setPropertyByTextField(SettingType.UNIDIRECTIONAL, Properties.value, NEW_VALUE_2);
 438         checkCounterValue(ON_ACTION_EVENT_COUNTER_ID, 8);
 439     }
 440 
 441     @Smoke
 442     @Test(timeout = 300000)//RT-19227
 443     public void selectionTest() throws InterruptedException, Exception {
 444         final int number = 10;
 445         for (int i = 0; i < number; i++) {
 446             addElement(String.valueOf(i), i);
 447         }
 448         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.visibleRowCount, 4);
 449 
 450         for (int i = 0; i < number * 2; i++) {
 451             testedControl.as(Selectable.class).selector().select(String.valueOf(i % number));
 452             try {
 453                 checkSelectionState(i % number, i % number);
 454             } catch (Exception e) {
 455                 System.out.println("Exception was thrown on step " + i);
 456                 throw e;
 457             }
 458         }
 459     }
 460 
 461     @Smoke
 462     @Test(timeout = 300000)
 463     public void selection2Test() throws InterruptedException, Exception {
 464         clickDropDownButton();
 465         ListView lw = ((ListView) getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap().getControl());
 466         final int number = 10;
 467         for (int i = 0; i < number; i++) {
 468             addElement(String.valueOf(i), i);
 469         }
 470         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.visibleRowCount, 4);
 471 
 472         for (int i = 0; i < number * 3; i++) {
 473             testedControl.as(Selectable.class).selector().select(String.valueOf(i % number));
 474             clickDropDownButton();
 475             clickDropDownButton();
 476             try {
 477                 assertEquals(i % number, lw.getSelectionModel().getSelectedIndex());
 478                 assertEquals(String.valueOf(i % number), lw.getSelectionModel().getSelectedItem());
 479             } catch (Exception e) {
 480                 System.out.println("Exception was thrown on step " + i);
 481                 throw e;
 482             }
 483         }
 484     }
 485 
 486     @Smoke
 487     @Test(timeout = 300000)
 488     public void keyboardF4Tests() throws Exception {
 489         popupShowingOnKeyPressCommonTest(KeyboardButtons.F4);
 490     }
 491 
 492     @Smoke
 493     @Test(timeout = 300000)//RT-18176
 494     public void keyboardAltUpTest() throws Exception {
 495         popupShowingOnKeyPressCommonTest(KeyboardButtons.UP, KeyboardModifiers.ALT_DOWN_MASK);
 496     }
 497 
 498     @Smoke
 499     @Test(timeout = 300000)//RT-18176
 500     public void keyboardAltDownTest() throws Exception {
 501         popupShowingOnKeyPressCommonTest(KeyboardButtons.DOWN, KeyboardModifiers.ALT_DOWN_MASK);
 502     }
 503 
 504     private void popupShowingOnKeyPressCommonTest(KeyboardButtons button, KeyboardModifiers... mdfs) throws Exception {
 505         requestFocusOnControl(testedControl);
 506         for (int j = 0; j <= 1; j++) { //to switch editable property
 507             setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 508             for (int i = 0; i < ITER; i++) {
 509                 testedControl.keyboard().pushKey(button, mdfs);
 510                 if (j == 0) {//editable state.
 511                     assertEquals(getTextFieldText(), "");
 512                 }
 513                 checkTextFieldText(Properties.value, "null");
 514 
 515                 try {
 516                     checkPopupShowing(i % 2 == 0 ? true : false);
 517                 } catch (Exception e) {
 518                     System.out.println("Exception was thrown on step " + i);
 519                     throw e;
 520                 }
 521             }
 522         }
 523     }
 524 
 525     @Smoke
 526     @Test(timeout = 300000)
 527     public void keyboardUpDownTest() throws InterruptedException {
 528         final int number = 10;
 529         for (int i = 0; i < number; i++) {
 530             addElement(String.valueOf(i), i);
 531         }
 532 
 533         int currentItem = -1;
 534 
 535         testedControl.mouse().click();
 536         testedControl.mouse().click();
 537         testedControl.keyboard().pushKey(KeyboardButtons.DOWN);
 538 
 539         for (int k = 0; k < 3; k++) {
 540             for (KeyboardButton key : EnumSet.of(KeyboardButtons.DOWN, KeyboardButtons.UP)) {
 541                 for (int i = 0; i < ITER; i++) {
 542                     if (key == KeyboardButtons.UP) {
 543                         currentItem -= 1;
 544                     } else {
 545                         currentItem += 1;
 546                     }
 547                     currentItem = (int) Math.round(adjustValue(0, number - 1, currentItem));
 548 
 549                     testedControl.keyboard().pushKey(key);
 550 
 551                     checkSelectionState(currentItem, currentItem);
 552                 }
 553             }
 554         }
 555     }
 556 
 557     @Smoke
 558     @Test(timeout = 300000)
 559     public void keyboardPopupCloseTest() throws InterruptedException {
 560         //According to spec: [Active list is open] close the active list.
 561         for (int i = 0; i < 2; i++) {
 562             for (KeyboardButton button : EnumSet.of(KeyboardButtons.ENTER, KeyboardButtons.ESCAPE, KeyboardButtons.SPACE)) {
 563                 clickDropDownButton();
 564                 checkPopupShowing(true);
 565 
 566                 requestFocusOnControl(testedControl);
 567                 testedControl.keyboard().pushKey(button);
 568                 checkPopupShowing(false);
 569             }
 570         }
 571 
 572         //ANTITEST:
 573         requestFocusOnControl(testedControl);
 574         for (int i = 0; i < 2; i++) {
 575             for (KeyboardButton button : EnumSet.of(KeyboardButtons.ENTER, KeyboardButtons.ESCAPE, KeyboardButtons.SPACE)) {
 576                 checkPopupShowing(false);
 577                 testedControl.keyboard().pushKey(button);
 578                 checkPopupShowing(false);
 579             }
 580         }
 581     }
 582 
 583     @Smoke
 584     @Test(timeout = 300000)
 585     public void onEscapeNotSelectingTest() throws InterruptedException {
 586         selectOnKeyboardCommonTest(KeyboardButtons.ESCAPE);
 587     }
 588 
 589     @Smoke
 590     @Test(timeout = 300000)
 591     public void onEnterSelectTest() throws InterruptedException {
 592         selectOnKeyboardCommonTest(KeyboardButtons.ENTER);
 593     }
 594 
 595     @Smoke
 596     @Test(timeout = 300000)
 597     public void onSpaceSelectTest() throws InterruptedException {
 598         selectOnKeyboardCommonTest(KeyboardButtons.SPACE);
 599     }
 600 
 601     private void selectOnKeyboardCommonTest(KeyboardButtons button) throws InterruptedException {
 602         int number = 10;
 603         for (int i = 0; i < number; i++) {
 604             addElement(String.valueOf(i), i);
 605         }
 606 
 607         for (int i = 1; i < number; i++) {
 608             testedControl.keyboard().pushKey(KeyboardButtons.F4);
 609             testedControl.keyboard().pushKey(KeyboardButtons.DOWN);
 610             testedControl.keyboard().pushKey(button);
 611             checkPopupShowing(false);
 612             checkTextFieldText(Properties.value, String.valueOf((i - 1) % number));
 613         }
 614     }
 615 
 616     //RT-18064 that would be a feature, so that is not a test//Ok.
 617     public void keyboardAnyKeyTest() {
 618         addElements("aaa", "bbb", "ccc");
 619 
 620         requestFocusOnControl(testedControl);
 621         testedControl.keyboard().pushKey(KeyboardButtons.B);
 622         checkSimpleListenerValue(Properties.selectedItem, "bbb");
 623     }
 624 
 625     @Smoke
 626     @Test(timeout = 300000)
 627     public void mouseTest() throws InterruptedException {
 628 
 629         //common click
 630         testedControl.mouse().click();
 631         checkTextFieldText(Properties.showing, "true");
 632         testedControl.mouse().click();
 633         checkTextFieldText(Properties.showing, "false");
 634 
 635         //drop down button test
 636         clickDropDownButton();
 637         checkTextFieldText(Properties.showing, "true");
 638         clickDropDownButton();
 639         checkTextFieldText(Properties.showing, "false");
 640 
 641         //select test
 642         addElement("0", 0);
 643         testedControl.as(Selectable.class).selector().select("0");
 644         assertEquals("0", getCurrentValue());
 645 
 646         //scrollbar interaction test
 647         addElements(1, 2, 3, 4, 5, 6);
 648         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.visibleRowCount, 5);
 649         clickDropDownButton();
 650         Wrap<? extends ScrollBar> sb = findScrollBar(
 651                 ((Parent<Node>) ((Wrap<? extends ListView>) ((Parent<Node>) getPopupWrap().as(Parent.class, Node.class))
 652                 .lookup(ListView.class).wrap()).as(Parent.class, Node.class)), Orientation.VERTICAL, true);
 653         sb.as(AbstractScroll.class).caret().to(1);
 654         checkTextFieldText(Properties.showing, "true");
 655         testedControl.as(Selectable.class).selector().select("6");
 656         checkTextFieldText(Properties.showing, "false");
 657 
 658         //selection in editable state
 659         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 660         requestFocusOnControl(testedControl);
 661         testedControl.as(Text.class).type("a");
 662         assertEquals(getTextFieldText(), "a");
 663 
 664         //drop down in editable state
 665         clickDropDownButton();
 666         testedControl.as(Selectable.class).selector().select("3");
 667         checkTextFieldText(Properties.value, "3");
 668     }
 669 
 670     @ScreenshotCheck
 671     @Smoke
 672     @Test(timeout = 300000)//RT-19227
 673     public void commonNonEditableTest() throws InterruptedException, Throwable {
 674         addElements(1, 2, 3, 4, 5, 6);
 675         checkScreenshot("ComboBox_initial", testedControl);
 676 
 677         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.visibleRowCount, 3);
 678 
 679         testedControl.mouse().click();
 680         testedControl.mouse().click();
 681 
 682         testedControl.keyboard().pushKey(KeyboardButtons.UP, KeyboardModifiers.ALT_DOWN_MASK);
 683         checkScrollBarVisibility(true);
 684         checkTextFieldText(Properties.showing, "true");
 685 
 686         testedControl.as(Selectable.class).selector().select("6");
 687         checkSelectionState(5, 6);
 688         checkTextFieldText(Properties.value, "6");
 689 
 690         clickDropDownButton();
 691         checkScreenshot("ComboBox_combobox_noneditable[6_is_selected]", testedControl);
 692         Wrap wrap = getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap();
 693 
 694         checkScreenshot("ComboBox_popup_noneditable[6_is_selected]", wrap);
 695         throwScreenshotError();
 696     }
 697 
 698     @ScreenshotCheck
 699     @Smoke
 700     @Test(timeout = 300000)
 701     public void commonEditableTest() throws InterruptedException, Throwable {
 702         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 703         addElements(1, 2, 3, 4, 5, 6);
 704         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.visibleRowCount, 4);
 705 
 706         testedControl.as(Selectable.class).selector().select("6");
 707         checkSelectionState(5, 6);
 708         assertEquals(getTextFieldText(), "6");
 709         checkTextFieldText(Properties.value, "6");
 710         checkSimpleListenerValue(Properties.selectedIndex, 5);
 711 
 712         testedControl.mouse().click();
 713         testedControl.as(Text.class).type("abc");
 714         testedControl.keyboard().pushKey(KeyboardButtons.ENTER);
 715 
 716         checkSimpleListenerValue(Properties.selectedItem, "6abc");
 717         checkTextFieldText(Properties.value, "6abc");
 718 
 719         clickDropDownButton();
 720 
 721         checkScreenshot("ComboBox_combobox_editable", testedControl);
 722         checkScreenshot("ComboBox_popup_editable", getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap());
 723         throwScreenshotError();
 724     }
 725 
 726     @ScreenshotCheck
 727     @Test(timeout = 300000)
 728     public void initialAndFinalSizeTest() throws Throwable {
 729         String commonScreenShotName = "ComboBox_initial";
 730         //checkScreenshot(commonScreenShotName, testedControl);//Removed, as size of empty is different.
 731 
 732         int size = 10;
 733         for (int i = 0; i < size; i++) {
 734             addElement(String.valueOf(i), i);
 735             checkScreenshot(commonScreenShotName, testedControl);
 736         }
 737         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.visibleRowCount, 5);
 738 
 739         for (int i = 0; i < size; i++) {
 740             removeFromPos(0);
 741             checkScreenshot(commonScreenShotName, testedControl);
 742         }
 743 
 744         checkScreenshot(commonScreenShotName, testedControl);
 745         throwScreenshotError();
 746     }
 747 
 748     @Smoke
 749     @Test(timeout = 300000)
 750     public void consistentAndEmptySelectionTest() {
 751         //seems, the only way to do empty selection is using keyboard.UP.
 752         int number = 5;
 753         for (int i = 0; i < number; i++) {
 754             addElement(String.valueOf(i), i);
 755         }
 756 
 757         requestFocusOnControl(testedControl);
 758         testedControl.keyboard().pushKey(KeyboardButtons.DOWN);
 759         for (int j = 1; j < number; j++) {
 760             for (int k = 0; k < j; k++) {
 761                 testedControl.keyboard().pushKey(KeyboardButtons.DOWN);
 762                 checkTextFieldText(Properties.value, String.valueOf(k + 1));
 763             }
 764 
 765             for (int k = 0; k < number; k++) {
 766                 testedControl.keyboard().pushKey(KeyboardButtons.UP);
 767                 if (k + 1 < j) {
 768                     checkTextFieldText(Properties.value, String.valueOf(j - k - 1));
 769                 } else {
 770                     checkTextFieldText(Properties.value, String.valueOf(0));
 771                 }
 772             }
 773 
 774             checkTextFieldText(Properties.value, "0");
 775         }
 776     }
 777 
 778     @Smoke
 779     @Test(timeout = 300000)
 780     public void addElementsInDropDownTest() {
 781         addElements(0, 1, 2, 3, 4, 5, 6);
 782 
 783         testedControl.as(Selectable.class).selector().select("3");
 784         checkSelectionState(3, 3);
 785         addElement("2,5", 2);
 786         checkSelectionState(4, 3);
 787         addElement("3,5", 4);
 788         checkSelectionState(5, 3);
 789         addElement("4,5", 6);
 790         checkSelectionState(5, 3);
 791     }
 792 
 793     @Smoke
 794     @Test(timeout = 300000)//RT-18944, RT-19227
 795     public void removeElementsFromDropDownTest() {
 796         addElements(0, 1, 2, 3, 4, 5, 6);
 797 
 798         testedControl.as(Selectable.class).selector().select("3");
 799         checkSelectionState(3, 3);
 800         removeFromPos(5);
 801         checkSelectionState(3, 3);
 802         removeFromPos(4);
 803         checkSelectionState(3, 3);
 804         removeFromPos(2);
 805         checkSelectionState(2, 3);
 806         removeFromPos(2);
 807         checkSimpleListenerValue(Properties.selectedIndex, -1);
 808         checkTextFieldText(Properties.value, "null");
 809     }
 810 
 811     @Smoke
 812     @Test(timeout = 300000)//RT-18972
 813     public void editingChangeModeText() {
 814         currentSettingOption = SettingOption.MANUAL;//That is needed because otherwise test fails
 815         addElements(1, 2, 3);
 816         //initial state is uneditable
 817         testedControl.as(Selectable.class).selector().select("3");
 818         checkValue("3");
 819 
 820         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 821         //editable
 822         checkValue("null");
 823         assertEquals(getTextFieldText(), "");
 824         testedControl.as(Text.class).type(NEW_VALUE_1);
 825         checkValue("null");
 826         testedControl.keyboard().pushKey(KeyboardButtons.ENTER);
 827         checkValue(NEW_VALUE_1);
 828         testedControl.as(Selectable.class).selector().select("1");
 829         assertEquals(getTextFieldText(), "1");
 830         checkValue("1");
 831         testedControl.as(Text.class).type(NEW_VALUE_2);
 832         testedControl.keyboard().pushKey(KeyboardButtons.ENTER);
 833         checkValue(NEW_VALUE_2 + "1");
 834 
 835         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 836         //non-editable
 837         checkValue("null");
 838         testedControl.as(Selectable.class).selector().select("2");
 839         checkValue("2");
 840 
 841         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
 842         //editable
 843         checkValue("null");
 844         testedControl.as(Selectable.class).selector().select("1");
 845         checkValue("1");
 846     }
 847 
 848     @ScreenshotCheck
 849     @Test(timeout = 300000)
 850     public void customCellAPIApplying() throws Throwable {
 851         assertTrue((new ComboBox()).getCellFactory() == null);
 852         assertTrue(testedControl.getControl().getCellFactory() == null);
 853         applyCustomCellAPI();
 854         assertTrue(testedControl.getControl().getCellFactory() instanceof Callback);
 855         addElements(1, 2, 3);
 856 
 857         testedControl.as(Selectable.class).selector().select("3");
 858         checkValue("3");
 859 
 860         testedControl.mouse().click();
 861 
 862         checkScreenshot("ComboBox_Custom_CellAPI_[3]", testedControl);
 863         Wrap wrap = getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap();
 864 
 865         checkScreenshot("ComboBox_Custom_CellAPI_[Custom3]", wrap);
 866         throwScreenshotError();
 867     }
 868     //add cell factory testing
 869     static private final String NEW_VALUE_1 = "new value 1";
 870     static private final String NEW_VALUE_2 = "new value 2";
 871 
 872     @Smoke
 873     @Test(timeout = 300000)
 874     public void testOnShowingEvent() throws Throwable {
 875         testEvents(new CheckFunctor.IdCounter("SET_ON_SHOWING_COUNTER"),
 876                 new CheckFunctor.NullCounter());
 877     }
 878 
 879     @Smoke
 880     @Test(timeout = 300000)
 881     public void testOnShownEvent() throws Throwable {
 882         testEvents(new CheckFunctor.IdCounter("SET_ON_SHOWN_COUNTER"),
 883                 new CheckFunctor.NullCounter());
 884     }
 885 
 886     @Smoke
 887     @Test(timeout = 300000)
 888     public void testOnHiding() throws Throwable {
 889         testEvents(new CheckFunctor.NullCounter(),
 890                 new CheckFunctor.IdCounter("SET_ON_HIDING_COUNTER"));
 891     }
 892 
 893     @Smoke
 894     @Test(timeout = 300000)
 895     public void testOnHidden() throws Throwable {
 896         testEvents(new CheckFunctor.NullCounter(),
 897                 new CheckFunctor.IdCounter("SET_ON_HIDEN_COUNTER"));
 898     }
 899 
 900     @Smoke
 901     @Test(timeout = 300000)
 902     public void testEventsSequence() throws Throwable {
 903 
 904         /**
 905          * Save default event handlers
 906          */
 907         final EventHandler<Event> onShowing = new GetAction<EventHandler<Event>>() {
 908             @Override
 909             public void run(Object... os) throws Exception {
 910                 setResult(testedControl.getControl().getOnShowing());
 911             }
 912         }.dispatch(Root.ROOT.getEnvironment());
 913 
 914         final EventHandler<Event> onShown = new GetAction<EventHandler<Event>>() {
 915             @Override
 916             public void run(Object... os) throws Exception {
 917                 setResult(testedControl.getControl().getOnShown());
 918             }
 919         }.dispatch(Root.ROOT.getEnvironment());
 920 
 921         final EventHandler<Event> onHiding = new GetAction<EventHandler<Event>>() {
 922             @Override
 923             public void run(Object... os) throws Exception {
 924                 setResult(testedControl.getControl().getOnHiding());
 925             }
 926         }.dispatch(Root.ROOT.getEnvironment());
 927 
 928         final EventHandler<Event> onHidden = new GetAction<EventHandler<Event>>() {
 929             @Override
 930             public void run(Object... os) throws Exception {
 931                 setResult(testedControl.getControl().getOnHidden());
 932             }
 933         }.dispatch(Root.ROOT.getEnvironment());
 934 
 935         final Map<EventHandler<Event>, Long> timestampsOfEvents =
 936                 new HashMap<EventHandler<Event>, Long>();
 937 
 938         /**
 939          * Assing new event handlers to get timestamps
 940          */
 941         new GetAction<Object>() {
 942             @Override
 943             public void run(Object... os) throws Exception {
 944                 testedControl.getControl().setOnShowing(new EventHandler() {
 945                     public void handle(Event t) {
 946                         timestampsOfEvents.put(onShowing, System.nanoTime());
 947                     }
 948                 });
 949 
 950                 testedControl.getControl().setOnShown(new EventHandler() {
 951                     public void handle(Event t) {
 952                         timestampsOfEvents.put(onShown, System.nanoTime());
 953                     }
 954                 });
 955 
 956                 testedControl.getControl().setOnHiding(new EventHandler() {
 957                     public void handle(Event t) {
 958                         timestampsOfEvents.put(onHiding, System.nanoTime());
 959                     }
 960                 });
 961 
 962                 testedControl.getControl().setOnHidden(new EventHandler() {
 963                     public void handle(Event t) {
 964                         timestampsOfEvents.put(onHidden, System.nanoTime());
 965                     }
 966                 });
 967             }
 968         }.dispatch(Root.ROOT.getEnvironment());
 969 
 970         testEvents(new CheckFunctor.NullCounter(),
 971                 new CheckFunctor() {
 972             @Override
 973             public void call(int conterVal) throws Throwable {
 974                 /**
 975                  * Compare timestamps of events
 976                  */
 977                 Long onShowingTime = timestampsOfEvents.get(onShowing);
 978                 Long onShownTime = timestampsOfEvents.get(onShown);
 979                 Long onHidingTime = timestampsOfEvents.get(onHiding);
 980                 Long onHiddenTime = timestampsOfEvents.get(onHidden);
 981 
 982                 assertEquals(true, onShowingTime < onShownTime);
 983                 assertEquals(true, onShownTime < onHidingTime);
 984                 assertEquals(true, onHidingTime < onHiddenTime);
 985             }
 986         });
 987         /**
 988          * Restore default event handlers
 989          */
 990         new GetAction<Object>() {
 991             @Override
 992             public void run(Object... os) throws Exception {
 993                 testedControl.getControl().setOnShowing(onShowing);
 994                 testedControl.getControl().setOnShown(onShown);
 995                 testedControl.getControl().setOnHiding(onHiding);
 996                 testedControl.getControl().setOnHidden(onHidden);
 997             }
 998         }.dispatch(Root.ROOT.getEnvironment());
 999     }
1000 
1001     /**
1002      * Method sets four counters to zero
1003      */
1004     private void clearCounters() {
1005         final String counterInitVal = "0";
1006         changeTextFieldText("SET_ON_SHOWING_COUNTER_COUNTER_TEXT_FIELD_ID", counterInitVal);
1007         changeTextFieldText("SET_ON_SHOWN_COUNTER_COUNTER_TEXT_FIELD_ID", counterInitVal);
1008         changeTextFieldText("SET_ON_HIDING_COUNTER_COUNTER_TEXT_FIELD_ID", counterInitVal);
1009         changeTextFieldText("SET_ON_HIDEN_COUNTER_COUNTER_TEXT_FIELD_ID", counterInitVal);
1010     }
1011 
1012     /**
1013      * Method opens and closes ComboBox by all possible means and calls passed
1014      * functors after each opening or closing.
1015      *
1016      * @param checkCountersAfterOpening
1017      * @param checkCountersAfterClosing
1018      * @throws Throwable
1019      */
1020     private void testEvents(CheckFunctor checkCountersAfterOpening,
1021             CheckFunctor checkCountersAfterClosing) throws Throwable {
1022         /**
1023          * make sure that comboBox is closed
1024          */
1025         assertFalse(new GetAction<Boolean>() {
1026             @Override
1027             public void run(Object... os) throws Exception {
1028                 setResult(testedControl.getControl().showingProperty().getValue());
1029             }
1030         }.dispatch(Root.ROOT.getEnvironment()));
1031 
1032         /**
1033          * Fill ComboBox with elements
1034          */
1035         addElements("aaa", "bbb", "ccc", "ddd", "eee");
1036 
1037         clearCounters();
1038 
1039         int counterVal = 1;
1040 
1041         /**
1042          * Open ComboBox by clicking on it's text field
1043          */
1044         testedControl.mouse().click();
1045         checkPopupShowing(true);
1046         checkCountersAfterOpening.call(counterVal);
1047         /**
1048          * Close it the same way
1049          */
1050         testedControl.mouse().click();
1051         checkPopupShowing(false);
1052         checkCountersAfterClosing.call(counterVal);
1053 
1054         /**
1055          * Counter should have increased
1056          */
1057         counterVal++;
1058 
1059         /**
1060          * Click on drop down arrow
1061          */
1062         clickDropDownButton();
1063         checkPopupShowing(true);
1064         checkCountersAfterOpening.call(counterVal);
1065 
1066         clickDropDownButton();
1067         checkPopupShowing(false);
1068         checkCountersAfterClosing.call(counterVal);
1069 
1070         counterVal++;
1071 
1072         /**
1073          * Press f4
1074          */
1075         testedControl.keyboard().pushKey(KeyboardButtons.F4);
1076         checkPopupShowing(true);
1077         checkCountersAfterOpening.call(counterVal);
1078 
1079         testedControl.keyboard().pushKey(KeyboardButtons.F4);
1080         checkPopupShowing(false);
1081         checkCountersAfterClosing.call(counterVal);
1082 
1083         counterVal++;
1084 
1085         /**
1086          * Alt+down arrow
1087          */
1088         testedControl.keyboard().pushKey(KeyboardButtons.DOWN, KeyboardModifiers.ALT_DOWN_MASK);
1089         checkPopupShowing(true);
1090         checkCountersAfterOpening.call(counterVal);
1091 
1092         testedControl.keyboard().pushKey(KeyboardButtons.DOWN, KeyboardModifiers.ALT_DOWN_MASK);
1093         checkPopupShowing(false);
1094         checkCountersAfterClosing.call(counterVal);
1095 
1096         counterVal++;
1097 
1098         /**
1099          * Alt+up arrow
1100          */
1101         testedControl.keyboard().pushKey(KeyboardButtons.UP, KeyboardModifiers.ALT_DOWN_MASK);
1102         checkPopupShowing(true);
1103         checkCountersAfterOpening.call(counterVal);
1104 
1105         testedControl.keyboard().pushKey(KeyboardButtons.UP, KeyboardModifiers.ALT_DOWN_MASK);
1106         checkPopupShowing(false);
1107         checkCountersAfterClosing.call(counterVal);
1108     }
1109 
1110     private static interface CheckFunctor {
1111 
1112         public void call(int counterVal) throws Throwable;
1113 
1114         static class NullCounter implements CheckFunctor {
1115 
1116             public void call(int counterVal) throws Throwable {
1117             }
1118         };
1119 
1120         static class IdCounter implements CheckFunctor {
1121 
1122             private final String id;
1123 
1124             public IdCounter(String id) {
1125                 this.id = id;
1126             }
1127 
1128             public void call(int counterVal) throws Throwable {
1129                 ComboBoxTest.checkCounterValue(id, counterVal);
1130             }
1131         }
1132     };
1133 
1134     /**
1135      * Test adds an element to ComboBox when onShowing event is fired and checks
1136      * that new element was rendered properly
1137      *
1138      * @throws Throwable
1139      */
1140     @Smoke
1141     @Test(timeout = 300000)
1142     public void testOnShowingByModifyingContent() throws Throwable {
1143 
1144         final int initialSize = 4;
1145         addElements("1", "2", "3", "4");
1146 
1147         clickButtonForTestPurpose(SET_ADDING_ELEMENTS_ON_SHOWING);
1148         testedControl.mouse().click();
1149         checkPopupShowing(true);
1150 
1151         Wrap<? extends ListView> list = getPopupWrap()
1152                 .as(Parent.class, Node.class)
1153                 .lookup(ListView.class)
1154                 .wrap();
1155 
1156         Wrap<? extends ListCell> testCell = list
1157                 .as(Parent.class, Node.class)
1158                 .lookup(ListCell.class, new ListItemByObjectLookup<String>(INITIAL_VALUE))
1159                 .wrap();
1160 
1161         Wrap<? extends ListCell> previousCell = list
1162                 .as(Parent.class, Node.class)
1163                 .lookup(ListCell.class, new ListItemByObjectLookup<String>("4"))
1164                 .wrap();
1165 
1166         assertTrue(testCell.getScreenBounds().getY()
1167                 >= previousCell.getScreenBounds().getY()
1168                 + previousCell.getScreenBounds().getHeight());
1169 
1170         /* Check that size of ComboBox list has increased */
1171         Boolean result = new GetAction<Boolean>() {
1172             @Override
1173             public void run(Object... os) throws Exception {
1174                 setResult(testedControl.getControl().getItems().size() == (initialSize + 1));
1175             }
1176         }.dispatch(Root.ROOT.getEnvironment());
1177         assertTrue(result);
1178 
1179         clickButtonForTestPurpose(RESTORE_ON_SHOWING_EVENT_HANDLER);
1180     }
1181 
1182     /**
1183      * Test that not editable ComboBox's getEditor() method must return null
1184      */
1185     @Smoke
1186     @Test(timeout = 300000)
1187     public void testNotEditableGetEditorMethod() {
1188         setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.editable, false);
1189         checkTextFieldText(Properties.text, "");
1190     }
1191 
1192     /**
1193      * Test that text entered in TextField doesn't change ComboBox's value
1194      */
1195     @Smoke
1196     @Test(timeout = 300000)
1197     public void testInputByEditorProperty() throws Throwable {
1198         addElements("1", "2", "3", "4");
1199 
1200         setPropertyByToggleClick(SettingType.BIDIRECTIONAL, Properties.editable);
1201 
1202         final String selectedVal = "2";
1203         testedControl.as(Selectable.class).selector().select(selectedVal);
1204 
1205         /**
1206          * Change text in TextField
1207          */
1208         final String testedText = "aaa";
1209         setPropertyByTextField(SettingType.SETTER, Properties.text, testedText);
1210 
1211         /**
1212          * Value shouldn't have changed
1213          */
1214         checkTextFieldText(Properties.value, selectedVal);
1215 
1216         checkTextFieldText(Properties.text, testedText);
1217     }
1218 
1219     /**
1220      * Test that TextField returned by getEditor() method remains the same after
1221      * changing editable property
1222      */
1223     @Smoke
1224     @Test(timeout = 300000)
1225     public void testEditorProperty() throws Throwable {
1226         new PropertyTest.EditorPropertyTest(testedControl).test();
1227     }
1228 
1229     /**
1230      * Test that TextField's parent remains the same after changing editable
1231      * property
1232      *
1233      */
1234     @Smoke
1235     @Test(timeout = 300000)
1236     public void testEditorPropertyParent() throws Throwable {
1237         new PropertyTest.EditorParentPropertyTest(testedControl).test();
1238     }
1239 
1240     /**
1241      * Test that text entered via TextField becomes ComboBox's value when
1242      * ComboBox looses focus
1243      */
1244     @Smoke
1245     @Test(timeout = 300000)
1246     public void textEditorPropertyCommitOnFocusLost() throws Throwable {
1247         setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.editable);
1248 
1249         final String testedText = "test test test";
1250         getEditTextFieldWrap().as(Text.class).type(testedText);
1251 
1252         Wrap<? extends TextField> textFieldWrap = findTextField("ARMED_LISTENER_ID");
1253         textFieldWrap.mouse().click();
1254 
1255         checkTextFieldText(Properties.value, testedText);
1256 
1257         final String anotherText = "another string";
1258         setPropertyByTextField(SettingType.SETTER, Properties.text, anotherText);
1259 
1260         testedControl.keyboard().pushKey(KeyboardButtons.TAB);
1261         checkTextFieldText(Properties.value, anotherText);
1262     }
1263 
1264     /**
1265      * Test different cell rendering of ComboBox button and list (pop up) Button
1266      * height must remain the same. Height of cells of ComboBox must increase.
1267      *
1268      * http://javafx-jira.kenai.com/browse/RT-24528
1269      */
1270     @Smoke
1271     @Test(timeout = 300000)
1272     public void testCellRenderingHeight() throws Throwable {
1273 
1274         clickButtonForTestPurpose(POPULATE_COMBOBOX_WITH_FONT_SIZES);
1275 
1276         for (boolean isEditable : new boolean[]{false, true}) {
1277 
1278             if (!isEditable) {
1279                 setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.editable, false);
1280             } else {
1281                 setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.editable);
1282             }
1283 
1284             final double initialButtonHeight = testedControl.getScreenBounds().getHeight();
1285             double prevCellTextHeight = 0f;
1286 
1287             for (int fontSize = INITIAL_FONT_SIZE; fontSize <= MAX_FONT_SIZE; fontSize += 2) {
1288                 String testVal = String.valueOf(fontSize);
1289 
1290                 testedControl.as(Selectable.class).selector().select(String.valueOf(fontSize));
1291 
1292                 /* check heighgt of the button */
1293                 assertEquals(initialButtonHeight, testedControl.getScreenBounds().getHeight(), 0.001);
1294 
1295                 /* text node should be alwas rendered inside ComboBox button */
1296                 Wrap<? extends javafx.scene.text.Text> textFieldWrap = testedControl.as(Parent.class, Node.class)
1297                     .lookup(javafx.scene.text.Text.class).wrap();
1298                 assertTrue(textFieldWrap.getScreenBounds().getY() >= testedControl.getScreenBounds().getY());
1299                 assertTrue(textFieldWrap.getScreenBounds().getY() + textFieldWrap.getScreenBounds().getHeight()
1300                         <= testedControl.getScreenBounds().getY() + testedControl.getScreenBounds().getHeight());
1301 
1302                 /* get wraps of cell and cell text node to compare coordinates */
1303                 clickDropDownButton();
1304 
1305                 Wrap<? extends ListView> listWrap = getPopupWrap().as(Parent.class, Node.class)
1306                         .lookup(ListView.class).wrap();
1307 
1308                 Wrap<? extends ListCell> cellWrap = listWrap.as(Parent.class, Node.class)
1309                         .lookup(ListCell.class, new ByText(testVal, StringComparePolicy.EXACT)).wrap();
1310 
1311                 Wrap<? extends javafx.scene.text.Text> cellTextWrap = cellWrap.as(Parent.class, Node.class)
1312                         .lookup(javafx.scene.text.Text.class).wrap();
1313 
1314                 /* cell text should be always inside cell */
1315                 assertTrue(cellTextWrap.getScreenBounds().getY() >= cellWrap.getScreenBounds().getY());
1316                 assertTrue(cellWrap.getScreenBounds().getY() + cellWrap.getScreenBounds().getHeight()
1317                         >= cellTextWrap.getScreenBounds().getY() + cellTextWrap.getScreenBounds().getHeight());
1318 
1319                 if (prevCellTextHeight == 0) {
1320                     prevCellTextHeight = cellTextWrap.getScreenBounds().getHeight();
1321                 } else {
1322                     assertTrue(prevCellTextHeight < cellTextWrap.getScreenBounds().getHeight());
1323                     prevCellTextHeight = cellTextWrap.getScreenBounds().getHeight();
1324                 }
1325 
1326                 if (fontSize == INITIAL_FONT_SIZE) {
1327                     continue;
1328                 }
1329 
1330                 Wrap<? extends ListCell> prevCellWrap = listWrap.as(Parent.class, Node.class)
1331                         .lookup(ListCell.class, new ByText(String.valueOf(fontSize - 2), StringComparePolicy.EXACT)).wrap();
1332 
1333                 /* compare cell coordinates with previous cell coordinates */
1334                 assertTrue(cellWrap.getScreenBounds().getY()
1335                         >= prevCellWrap.getScreenBounds().getY() + prevCellWrap.getScreenBounds().getHeight());
1336             }
1337         }
1338     }
1339 
1340     /**
1341      * Test different cell rendering of ComboBox button and list (pop up).
1342      * Button width must remain the same. Width of cells of ComboBox must also
1343      * remain the same.
1344      *
1345      * http://javafx-jira.kenai.com/browse/RT-24528
1346      */
1347     @Test(timeout = 300000)
1348     public void testCellRenderingWidth() throws Throwable {
1349 
1350         clickButtonForTestPurpose(POPULATE_COMBOBOX_WITH_FONT_SIZES);
1351 
1352         for (boolean isEditable : new boolean[]{false, true}) {
1353 
1354             if (!isEditable) {
1355                 setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.editable, false);
1356             } else {
1357                 setPropertyByToggleClick(SettingType.UNIDIRECTIONAL, Properties.editable, true);
1358             }
1359 
1360             //Wait editable state application.
1361             Thread.sleep(1000);
1362 
1363             final double initialButtonWidth = testedControl.getScreenBounds().getWidth();
1364 
1365             if (!isPopupVisible()) {
1366                 clickDropDownButton();
1367             }
1368             final double initialPopupWidth = getPopupWrap().getScreenBounds().getWidth();
1369             clickDropDownButton();
1370 
1371             for (int fontSize = INITIAL_FONT_SIZE; fontSize <= MAX_FONT_SIZE; fontSize += 2) {
1372                 String testVal = String.valueOf(fontSize);
1373 
1374                 testedControl.as(Selectable.class).selector().select(String.valueOf(fontSize));
1375 
1376                 /* check width of the button */
1377                 assertEquals(initialButtonWidth, testedControl.getScreenBounds().getWidth(), 2.001);
1378 
1379                 if (!isPopupVisible()) {
1380                     clickDropDownButton();
1381                 }
1382 
1383                 /* check width of the popup */
1384                 assertEquals(initialPopupWidth, getPopupWrap().getScreenBounds().getWidth(), 1.001);
1385 
1386                 /* get wraps of cell and cell text node to compare coordinates */
1387                 Wrap<? extends ListView> listWrap = getPopupWrap().as(Parent.class, Node.class)
1388                         .lookup(ListView.class).wrap();
1389 
1390                 Wrap<? extends ListCell> cellWrap = listWrap.as(Parent.class, Node.class)
1391                         .lookup(ListCell.class, new ByText(testVal, StringComparePolicy.EXACT)).wrap();
1392 
1393                 Wrap<? extends javafx.scene.text.Text> cellTextWrap = cellWrap.as(Parent.class, Node.class)
1394                         .lookup(javafx.scene.text.Text.class).wrap();
1395 
1396                 /* cell text should be always inside cell */
1397                 assertTrue(cellTextWrap.getScreenBounds().getX() >= cellWrap.getScreenBounds().getX());
1398                 assertTrue(cellWrap.getScreenBounds().getY() + cellWrap.getScreenBounds().getHeight()
1399                         >= cellTextWrap.getScreenBounds().getY() + cellTextWrap.getScreenBounds().getHeight());
1400 
1401                 if (fontSize == INITIAL_FONT_SIZE) {
1402                     continue;
1403                 }
1404 
1405                 Wrap<? extends ListCell> prevCellWrap = listWrap.as(Parent.class, Node.class)
1406                         .lookup(ListCell.class, new ByText(String.valueOf(fontSize - 2), StringComparePolicy.EXACT)).wrap();
1407 
1408                 /* compare cell coordinates with previous cell coordinates */
1409                 assertEquals(prevCellWrap.getScreenBounds().getX(), cellWrap.getScreenBounds().getX(), 0.001);
1410                 assertEquals(prevCellWrap.getScreenBounds().getWidth(), cellWrap.getScreenBounds().getWidth(), 0.001);
1411             }
1412         }
1413     }
1414 
1415     /**
1416      * This test checks that a custom string converter fromString() method is
1417      * called only once when some value is entered in the editable ComboBox
1418      */
1419     @Smoke
1420     @Test(timeout = 300000)
1421     public void testStringConvertersFromStringMethod() throws InterruptedException {
1422         setPropertyBySlider(SettingType.SETTER, Properties.prefWidth, 150);
1423 
1424         applyCustomStringConverter();
1425 
1426         setPropertyByToggleClick(SettingType.SETTER, Properties.editable, true);
1427 
1428         final String testString = "test";
1429         setPropertyByTextField(SettingType.SETTER, Properties.text, testString);
1430 
1431         testedControl.keyboard().pushKey(KeyboardButtons.ENTER);
1432 
1433         checkTextFieldText(Properties.value, FROM_STRING_PREFIX);
1434     }
1435 
1436     /**
1437      * Tests format string converter and checks that transformation is performed
1438      * properly
1439      */
1440     @Smoke
1441     @Test(timeout = 300000)
1442     public void testFormatStringConverter() throws InterruptedException {
1443         setPropertyBySlider(SettingType.SETTER, Properties.prefWidth, 150);
1444 
1445         int itemsCount = 3;
1446         String prefix = "value #";
1447 
1448         final List<String> testedValues = new ArrayList<String>(itemsCount);
1449         for (int i = 0; i < itemsCount; i++) {
1450             testedValues.add(prefix + i);
1451         }
1452 
1453         final String pattern = "Before text. {0} After text.";
1454         MessageFormat m = new MessageFormat(pattern);
1455         final Format fmt = new ComboBoxApp.MyMessageFormat(m);
1456 
1457         //Set format string converter
1458         new GetAction<Object>() {
1459             @Override
1460             public void run(Object... parameters) throws Exception {
1461 
1462                 testedControl.getControl().setConverter(new FormatStringConverter<String>(fmt));
1463 
1464                 //populate control
1465                 testedControl.getControl().getItems().addAll(testedValues);
1466             }
1467         }.dispatch(Root.ROOT.getEnvironment());
1468 
1469         setPropertyByToggleClick(SettingType.SETTER, Properties.editable, true);
1470 
1471         //#toString
1472         for (int i = 0; i < testedValues.size(); i++) {
1473             testedControl.as(Selectable.class).selector().select(testedValues.get(i));
1474             assertEquals(getTextFieldText(), fmt.format(testedValues.get(i)));
1475         }
1476 
1477         //#fromString
1478         for (int i = 0; i < testedValues.size(); i++) {
1479             testedControl.as(Text.class).clear();
1480             testedControl.as(Text.class).type(fmt.format(testedValues.get(i)));
1481             testedControl.keyboard().pushKey(KeyboardButtons.ENTER);
1482 
1483             checkTextFieldText(Properties.value, testedValues.get(i));
1484         }
1485 
1486         doNextResetHard();
1487     }
1488 
1489     /**
1490      * Checks that when the sorting is applied to the underlying data collection
1491      * the cells are rendered in the right order.
1492      */
1493     @Smoke
1494     @Test(timeout = 30000)
1495     public void renderingAfterSortingTest() {
1496         addElements("1", "2", "3", "4", "1", "2", "3", "4", "1", "42");
1497 
1498         final int ITEMS_COUNT = 9;
1499 
1500         StringConverter<String> conv = new StringConverter<String>() {
1501             @Override
1502             public String toString(String s) {
1503                 return s;
1504             }
1505 
1506             @Override
1507             public String fromString(String s) {
1508                 return s;
1509             }
1510         };
1511 
1512         SortValidator<String, ListCell> validator = new SortValidator<String, ListCell>(ITEMS_COUNT, conv) {
1513             @Override
1514             protected void setControlData(final ObservableList<String> ls) {
1515                 new GetAction<Object>() {
1516                     @Override
1517                     public void run(Object... parameters) throws Exception {
1518                         testedControl.getControl().setItems(ls);
1519                     }
1520                 }.dispatch(testedControl.getEnvironment());
1521             }
1522 
1523             @Override
1524             protected Lookup<? extends ListCell> getCellsLookup() {
1525                 testedControl.mouse().click();
1526 
1527                 Wrap<? extends ListView> listWrap = getPopupWrap().as(Parent.class, Node.class)
1528                         .lookup(ListView.class).wrap();
1529 
1530                 Lookup lookup = listWrap.as(Parent.class, Node.class)
1531                         .lookup(ListCell.class, new LookupCriteria<ListCell>() {
1532                     public boolean check(ListCell cell) {
1533                         return cell.isVisible();
1534                     }
1535                 });
1536 
1537                 testedControl.keyboard().pushKey(KeyboardButtons.ESCAPE);
1538 
1539                 return lookup;
1540             }
1541 
1542             @Override
1543             protected String getTextFromCell(ListCell cell) {
1544                 return cell.getText();
1545             }
1546         };
1547 
1548         boolean result = validator.check();
1549         String msg = validator.getFailureReason();
1550         assertTrue(msg, result);
1551     }
1552 
1553     /**
1554      * When there are no items, or items list is null, placeholder about items
1555      * emptyness is shown in the popup. This test changes placeholder and
1556      * checks, that it is shown when popup is shown.
1557      */
1558     @Smoke
1559     @Test(timeout = 30000)
1560     public void emptyListDropDownPlaceholderTest() throws Throwable {
1561         placeholderTestLoop(true);
1562         placeholderTestLoop(false);
1563 
1564         selectObjectFromChoiceBox(SettingType.UNIDIRECTIONAL, Properties.placeholder, Label.class);
1565         if (!isPopupVisible(false)) {
1566             clickDropDownButton();
1567         }
1568 
1569         //wait for animation
1570         try {
1571             Thread.sleep(SLEEP);
1572         } catch (Exception ignore) {
1573         }
1574 
1575         checkScreenshot("combobox_placeholder_dimmed",
1576                 new NodeWrap(testedControl.getEnvironment(), new GetAction<Node>() {
1577             @Override
1578             public void run(Object... os) throws Exception {
1579                 setResult(((javafx.scene.Parent) getPopupWrap().getControl().getRoot().getChildrenUnmodifiable().get(0)).getChildrenUnmodifiable().get(0));
1580             }
1581         }.dispatch(Root.ROOT.getEnvironment())));
1582         throwScreenshotError();
1583     }
1584 
1585     private void placeholderTestLoop(boolean withPopupClosedState) {
1586         assertEquals("Check initial emptyness of items list.", new GetAction<Integer>() {
1587             @Override
1588             public void run(Object... os) throws Exception {
1589                 setResult(testedControl.getControl().getItems().size());
1590             }
1591         }.dispatch(testedControl.getEnvironment()), 0, 0);
1592 
1593         selectObjectFromChoiceBox(SettingType.SETTER, Properties.placeholder, Rectangle.class);
1594         checkTextFieldTextContaining(Properties.placeholder, "Rectangle");
1595         testEmptyPlaceholder(Rectangle.class, true, withPopupClosedState);
1596 
1597         addElement("0", 0);
1598         testEmptyPlaceholder(Rectangle.class, false, withPopupClosedState);
1599 
1600         removeFromPos(0);
1601         testEmptyPlaceholder(Rectangle.class, true, withPopupClosedState);
1602 
1603         selectObjectFromChoiceBox(SettingType.BIDIRECTIONAL, Properties.placeholder, Polygon.class);
1604         checkTextFieldTextContaining(Properties.placeholder, "Polygon");
1605         testEmptyPlaceholder(Polygon.class, true, withPopupClosedState);
1606 
1607         clickButtonForTestPurpose(SET_ITEMS_NULL_BUTTON_ID);
1608         testEmptyPlaceholder(Polygon.class, true, withPopupClosedState);
1609 
1610         selectObjectFromChoiceBox(SettingType.UNIDIRECTIONAL, Properties.placeholder, Rectangle.class);
1611         checkTextFieldTextContaining(Properties.placeholder, "Rectangle");
1612         testEmptyPlaceholder(Rectangle.class, true, withPopupClosedState);
1613 
1614         new GetAction() {
1615             @Override
1616             public void run(Object... os) throws Exception {
1617                 testedControl.getControl().setItems(FXCollections.<String>observableArrayList("1"));
1618             }
1619         }.dispatch(testedControl.getEnvironment());
1620         testEmptyPlaceholder(Rectangle.class, false, withPopupClosedState);
1621 
1622         removeFromPos(0);
1623     }
1624 
1625     private void testEmptyPlaceholder(final Class classOfPlaceholder, boolean expectedToBeShown, boolean closePopupAfter) {
1626         if (!isPopupVisible()) {
1627             clickDropDownButton();
1628         }
1629 
1630         testedControl.waitState(new State<Integer>() {
1631             public Integer reached() {
1632                 final Lookup<Node> lookup = getPopupWrap().as(Parent.class, Node.class).lookup(classOfPlaceholder);
1633                 final int size = lookup.size();
1634                 if (size == 0) {
1635                     return 0;
1636                 } else {
1637                     final Wrap placeholderPane = getPopupWrap().as(Parent.class, Node.class).lookup(new ByStyleClass("placeholder")).wrap(0);
1638                     final Parent<Node> parent = (Parent<Node>) placeholderPane.as(Parent.class, Node.class);
1639                     assertTrue("Double check : there still must be a placeholder.", parent.lookup(classOfPlaceholder).size() > 0);
1640                     if (!new GetAction<Boolean>() {
1641                         @Override
1642                         public void run(Object... os) throws Exception {
1643                             setResult(((Wrap<Node>) os[0]).getControl().isVisible());
1644                         }
1645                     }.dispatch(testedControl.getEnvironment(), placeholderPane)) {
1646                         return 0;
1647                     } else {
1648                         return 1;
1649                     }
1650                 }
1651             }
1652         }, expectedToBeShown ? 1 : 0);
1653 
1654         if (closePopupAfter) {
1655             clickDropDownButton();
1656         }
1657     }
1658 }