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.choicebox;
  26 
  27 import client.test.ScreenshotCheck;
  28 import client.test.Smoke;
  29 import com.sun.javafx.scene.control.LabeledText;
  30 import javafx.collections.ObservableList;
  31 import javafx.commons.SortValidator;
  32 import javafx.scene.Node;
  33 import javafx.scene.Scene;
  34 import javafx.scene.control.Button;
  35 import javafx.scene.control.CheckBox;
  36 import javafx.scene.control.ChoiceBox;
  37 import javafx.scene.control.Label;
  38 import javafx.scene.control.ListView;
  39 import javafx.scene.control.TextField;
  40 import javafx.scene.control.test.ControlsTestBase;
  41 import javafx.scene.layout.Pane;
  42 import javafx.stage.PopupWindow;
  43 import javafx.stage.Window;
  44 import javafx.util.StringConverter;
  45 import org.jemmy.action.GetAction;
  46 import org.jemmy.control.Wrap;
  47 import org.jemmy.fx.ByID;
  48 import org.jemmy.fx.ByText;
  49 import org.jemmy.fx.ByWindowType;
  50 import org.jemmy.fx.Root;
  51 import org.jemmy.fx.control.CheckBoxWrap;
  52 import org.jemmy.fx.control.TextControlWrap;
  53 import org.jemmy.interfaces.Keyboard.KeyboardButtons;
  54 import org.jemmy.interfaces.Parent;
  55 import org.jemmy.interfaces.Selectable;
  56 import org.jemmy.interfaces.Selector;
  57 import org.jemmy.interfaces.Text;
  58 import org.jemmy.lookup.Lookup;
  59 import org.jemmy.lookup.LookupCriteria;
  60 import org.jemmy.resources.StringComparePolicy;
  61 import org.jemmy.timing.State;
  62 import static org.junit.Assert.*;
  63 import org.junit.Before;
  64 import org.junit.BeforeClass;
  65 import org.junit.Test;
  66 import org.junit.runner.RunWith;
  67 import test.javaclient.shared.FilteredTestRunner;
  68 import test.javaclient.shared.screenshots.ScreenshotUtils;
  69 
  70 /**
  71  *
  72  * @author shura
  73  */
  74 @RunWith(FilteredTestRunner.class)
  75 public class ChoiceTest extends ControlsTestBase {
  76 
  77     static Wrap<? extends ChoiceBox> choice;
  78     static Parent<Node> scene;
  79     static Wrap<? extends Scene> sceneWrap;
  80     static Wrap<? extends Label> selection;
  81     static Wrap<? extends ListView> list;
  82     static Wrap add;
  83     static Text textField;
  84     static Wrap getField;
  85     static Wrap show;
  86     static Wrap hide;
  87     static Wrap get;
  88     static Wrap converter;
  89     static Wrap removeConverter;
  90     static Wrap clear;
  91     static Wrap reset;
  92     static Wrap isShowing;
  93     static Wrap propVal;
  94     static Wrap propArg1;
  95     static Wrap propArg2;
  96     static Wrap testPane;
  97 
  98     public ChoiceTest() {
  99     }
 100 
 101     @BeforeClass
 102     public static void setUpClass() throws Exception {
 103         ChoiceBoxApp.main(new String[0]);
 104 
 105         sceneWrap = Root.ROOT.lookup(new ByWindowType(Window.class)).lookup(Scene.class).wrap();
 106 
 107         scene = sceneWrap.as(Parent.class, Node.class);
 108         choice = scene.lookup(ChoiceBox.class).wrap();
 109         list = scene.lookup(ListView.class).wrap();
 110         selection = scene.lookup(Label.class, new ByID<Label>(ChoiceBoxApp.SELECTION_LABEL)).wrap();
 111 
 112         get = scene.lookup(Button.class, new ByID<Button>(ChoiceBoxApp.GET_BUTTON_ID)).wrap();
 113         getField = scene.lookup(TextField.class, new ByID<TextField>(ChoiceBoxApp.GET_FIELD_ID)).wrap();
 114 
 115         converter = scene.lookup(Button.class, new ByID<Button>(ChoiceBoxApp.CONVERTER_BUTTON_ID)).wrap();
 116         removeConverter = scene.lookup(Button.class, new ByID<Button>(ChoiceBoxApp.REMOVE_CONVERTER_BUTTON_ID)).wrap();
 117 
 118         add = scene.lookup(Button.class, new ByID<Button>(ChoiceBoxApp.ADD_BUTTON_ID)).wrap();
 119         textField = scene.lookup(TextField.class, new ByID<TextField>(ChoiceBoxApp.ADD_FIELD)).wrap().as(Text.class);
 120 
 121         show = scene.lookup(Button.class, new ByID<Button>(ChoiceBoxApp.SHOW_BUTTON_ID)).wrap();
 122         hide = scene.lookup(Button.class, new ByID<Button>(ChoiceBoxApp.HIDE_BUTTON_ID)).wrap();
 123 
 124         clear = scene.lookup(Button.class, new ByID<Button>(ChoiceBoxApp.CLEAR_BUTTON_ID)).wrap();
 125         reset = scene.lookup(Button.class, new ByID<Button>(ChoiceBoxApp.RESET_BUTTON_ID)).wrap();
 126 
 127         isShowing = scene.lookup(CheckBox.class, new ByID<CheckBox>(ChoiceBoxApp.IS_SHOWING_CHECK_ID)).wrap();
 128         propVal = scene.lookup(CheckBox.class, new ByID<CheckBox>(ChoiceBoxApp.SHOWING_PROPERTY_VAL_CHECK_ID)).wrap();
 129         propArg1 = scene.lookup(CheckBox.class, new ByID<CheckBox>(ChoiceBoxApp.SHOWING_PROPERTY_ARG1_CHECK_ID)).wrap();
 130         propArg2 = scene.lookup(CheckBox.class, new ByID<CheckBox>(ChoiceBoxApp.SHOWING_PROPERTY_ARG2_CHECK_ID)).wrap();
 131 
 132         testPane = scene.lookup(Pane.class, new ByID<Pane>(ChoiceBoxApp.TEST_PANE_ID)).wrap();
 133     }
 134 
 135     @Before
 136     public void setUp() {
 137         reset.mouse().click();
 138     }
 139 
 140     @ScreenshotCheck
 141     @Smoke
 142     @Test(timeout = 300000)
 143     public void initialState() throws InterruptedException {
 144         ScreenshotUtils.checkScreenshot("ChoiceBox-initialState", testPane);
 145     }
 146 
 147     @ScreenshotCheck
 148     @Test(timeout = 300000)
 149     public void selection() throws Throwable {
 150         checkSelection(choice.as(Selectable.class).selector(), false);
 151         checkSelection(list.as(Selectable.class).selector(), false);
 152         throwScreenshotError();
 153     }
 154 
 155     @ScreenshotCheck
 156     @Test(timeout = 300000)
 157     public void showAPI() throws InterruptedException {
 158         for (int i = 0; i < 5; i++) { // cycle is reassonable due to previously observed bugs
 159             hide.mouse().click();
 160             show.mouse().click();
 161             checkState(true);
 162             ScreenshotUtils.checkScreenshot("ChoiceBox-showAPI", testPane);
 163         }
 164     }
 165 
 166     @ScreenshotCheck
 167     @Test(timeout = 300000)
 168     public void show() throws InterruptedException {
 169         for (int i = 0; i < 5; i++) { // cycle is reassonable due to previously observed bugs
 170             testPane.mouse().click();
 171             choice.mouse().click();
 172             checkState(true);
 173             ScreenshotUtils.checkScreenshot("ChoiceBox-show", testPane);
 174         }
 175     }
 176 
 177     @ScreenshotCheck
 178     @Test(timeout = 300000)
 179     public void hideAPI() throws InterruptedException {
 180         show.mouse().click();
 181         hide.mouse().click();
 182         checkState(false);
 183         ScreenshotUtils.checkScreenshot("ChoiceBox-hideAPI", testPane);
 184     }
 185 
 186     @ScreenshotCheck
 187     @Test(timeout = 300000)
 188     public void hide() throws InterruptedException {
 189         choice.mouse().click();
 190         testPane.mouse().click();
 191         checkState(false);
 192         ScreenshotUtils.checkScreenshot("ChoiceBox-hide-outside", testPane);
 193         hide.mouse().click();
 194         hide.mouse().click();
 195         checkState(false);
 196         ScreenshotUtils.checkScreenshot("ChoiceBox-hide", testPane);
 197     }
 198 
 199     @ScreenshotCheck
 200     @Test(timeout = 300000)
 201     public void add() throws InterruptedException {
 202         clear.mouse().click();
 203         reset.mouse().click();
 204         textField.clear();
 205         textField.type("New item");
 206         add.mouse().click();
 207         choice.mouse().click();
 208         ScreenshotUtils.checkScreenshot("ChoiceBox-add", testPane);
 209     }
 210 
 211     @Smoke
 212     @Test(timeout = 300000)
 213     public void keyboardCapture() throws InterruptedException { //RT-12597
 214         choice.mouse().click();
 215         Wrap<? extends Scene> popupScene = Root.ROOT.lookup(new ByWindowType(PopupWindow.class)).lookup(Scene.class).wrap(0);
 216         Node focused = getFocused();
 217         popupScene.keyboard().pushKey(KeyboardButtons.UP);
 218         assertEquals(focused, getFocused());
 219     }
 220 
 221     @ScreenshotCheck
 222     @Test(timeout = 300000)
 223     public void clear() throws InterruptedException {
 224         choice.as(Selectable.class).selector().select("1");
 225         selection.waitProperty(Wrap.TEXT_PROP_NAME, "1");
 226         clear.mouse().click();
 227         choice.mouse().click();
 228         ScreenshotUtils.checkScreenshot("ChoiceBox-clear", testPane);
 229     }
 230 
 231     @Smoke
 232     @Test(timeout = 300000)
 233     public void converter() throws InterruptedException {
 234         choice.as(Selectable.class).selector().select("1");
 235         converter.mouse().click();
 236         final LookupCriteria marker = new ByText("Converted", StringComparePolicy.SUBSTRING);
 237         final Parent choiceAsParent = choice.as(Parent.class, Node.class);
 238         choiceAsParent.lookup(marker).wait(1);
 239         choice.mouse().click();
 240         final Lookup<? extends Scene> popupLookup = Root.ROOT.lookup(new ByWindowType(PopupWindow.class)).lookup(Scene.class);
 241         popupLookup.wrap().as(Parent.class, Node.class).lookup(marker).wait(3);
 242         removeConverter.mouse().click();
 243         choice.waitState(new State<Integer>() {
 244             public Integer reached() {
 245                 return choiceAsParent.lookup(marker).size();
 246             }
 247         }, 0);
 248         choice.mouse().click();
 249         choice.waitState(new State<Integer>() {
 250             public Integer reached() {
 251                 return popupLookup.wrap().as(Parent.class, Node.class).lookup(marker).size();
 252             }
 253         }, 0);
 254     }
 255 
 256     /**
 257      * Checks that when the sorting is applied
 258      * to the underlying data collection
 259      * the cells are rendered in the right order.
 260      */
 261     @Smoke
 262     @Test(timeout=30000)
 263     public void renderingAfterSortingTest() {
 264         final int ITEMS_COUNT = 10;
 265 
 266         StringConverter<String> conv = new StringConverter<String>() {
 267             @Override public String toString(String s) { return s; }
 268 
 269             @Override public String fromString(String s) { return s; }
 270         };
 271 
 272         SortValidator<String, LabeledText> validator
 273                 = new SortValidator<String, LabeledText>(ITEMS_COUNT, conv) {
 274 
 275             @Override
 276             protected void setControlData(final ObservableList<String> ls) {
 277                 new GetAction<Object>() {
 278                     @Override
 279                     public void run(Object... parameters) throws Exception {
 280                         choice.getControl().setItems(ls);
 281                     }
 282                 }.dispatch(choice.getEnvironment());
 283             }
 284 
 285             @Override
 286             protected Lookup<? extends LabeledText> getCellsLookup() {
 287                 choice.mouse().click();
 288 
 289                 final Lookup<? extends Scene> popup =
 290                         Root.ROOT.lookup(new ByWindowType(PopupWindow.class))
 291                         .lookup(Scene.class);
 292 
 293                 choice.waitState(new State() {
 294                     public Boolean reached() {
 295                         if (popup.size() == 1) {
 296                             return Boolean.valueOf(true);
 297                         } else {
 298                             return null;
 299                         }
 300                     }
 301                 });
 302 
 303                 Lookup result = popup.as(Parent.class, Node.class)
 304                                        .lookup(LabeledText.class);
 305 
 306                 choice.keyboard().pushKey(KeyboardButtons.ESCAPE);
 307 
 308                 return result;
 309             }
 310 
 311             @Override
 312             protected String getTextFromCell(LabeledText cell) {
 313                 return cell.getText();
 314             }
 315         };
 316 
 317         boolean result = validator.check();
 318         String msg = validator.getFailureReason();
 319         assertTrue(msg, result);
 320     }
 321 
 322     protected void checkState(boolean check) {
 323         isShowing.waitProperty(TextControlWrap.SELECTED_PROP_NAME, check ? CheckBoxWrap.State.CHECKED : CheckBoxWrap.State.UNCHECKED);
 324         propVal.waitProperty(TextControlWrap.SELECTED_PROP_NAME, check ? CheckBoxWrap.State.CHECKED : CheckBoxWrap.State.UNCHECKED);
 325         propArg1.waitProperty(TextControlWrap.SELECTED_PROP_NAME, check ? CheckBoxWrap.State.UNCHECKED : CheckBoxWrap.State.CHECKED);
 326         propArg2.waitProperty(TextControlWrap.SELECTED_PROP_NAME, check ? CheckBoxWrap.State.CHECKED : CheckBoxWrap.State.UNCHECKED);
 327     }
 328 
 329     protected Node getFocused() {
 330         return new GetAction<Node>() {
 331             @Override
 332             public void run(Object... parameters) {
 333                 setResult(sceneWrap.getControl().getFocusOwner());
 334             }
 335         }.dispatch(Root.ROOT.getEnvironment());
 336     }
 337 
 338     protected void checkSelection(Selector selector, boolean requestFocus) {
 339         Object[] objects = new Object[]{"1", 3, false};
 340         for (int i = 0; i < objects.length; i++) {
 341             selector.select(objects[i]);
 342             get.mouse().click();
 343             getField.waitProperty(Wrap.TEXT_PROP_NAME, objects[i].toString());
 344             selection.waitProperty(Wrap.TEXT_PROP_NAME, objects[i].toString());
 345             list.waitState(new State() {
 346                 public Object reached() {
 347                     return list.as(Selectable.class).getState();
 348                 }
 349             }, objects[i]);
 350             if (requestFocus) {
 351                 new GetAction() {
 352                     @Override
 353                     public void run(Object... os) throws Exception {
 354                         choice.getControl().requestFocus();
 355                     }
 356                 }.dispatch(Root.ROOT.getEnvironment());
 357             }
 358             checkScreenshot("ChoiceBox-selection" + (i + 1), testPane);
 359         }
 360     }
 361 }