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.pagination;
  26 
  27 import com.sun.javafx.scene.control.skin.LabeledText;
  28 import java.util.ArrayList;
  29 import java.util.Arrays;
  30 import java.util.Comparator;
  31 import javafx.geometry.Orientation;
  32 import javafx.scene.Node;
  33 import javafx.scene.Scene;
  34 import javafx.scene.control.Label;
  35 import javafx.scene.control.Pagination;
  36 import javafx.scene.control.ScrollBar;
  37 import javafx.scene.control.TextArea;
  38 import static javafx.scene.control.test.pagination.PaginationApp.*;
  39 import javafx.scene.control.test.util.UtilTestFunctions;
  40 import static javafx.scene.control.test.utils.ComponentsFactory.*;
  41 import javafx.scene.control.test.utils.ptables.AbstractPropertyController.SettingType;
  42 import javafx.scene.layout.StackPane;
  43 import org.jemmy.Point;
  44 import org.jemmy.action.GetAction;
  45 import org.jemmy.control.Wrap;
  46 import org.jemmy.env.Environment;
  47 import org.jemmy.fx.ByID;
  48 import org.jemmy.fx.Root;
  49 import org.jemmy.input.AbstractScroll;
  50 import org.jemmy.interfaces.Keyboard.KeyboardButtons;
  51 import org.jemmy.interfaces.Parent;
  52 import org.jemmy.interfaces.Text;
  53 import org.jemmy.lookup.Lookup;
  54 import org.jemmy.lookup.LookupCriteria;
  55 import org.jemmy.timing.State;
  56 import org.junit.After;
  57 import static org.junit.Assert.*;
  58 import org.junit.Before;
  59 import org.junit.BeforeClass;
  60 import static test.javaclient.shared.TestUtil.isEmbedded;
  61 
  62 /**
  63  * @author Alexander Kirov
  64  */
  65 public class TestBase extends UtilTestFunctions {
  66 
  67     static Wrap<? extends Pagination> testedControl;
  68     static Wrap<? extends Scene> scene;
  69     static Wrap<? extends Scene> popupScene;
  70     protected boolean resetHardByDefault = true;//switcher of hard and soft reset mode.
  71     protected boolean doNextResetHard = resetHardByDefault;
  72     private final static String leftArrowButtonStyleClass = "left-arrow";
  73     private final static String rightArrowButtonStyleClass = "right-arrow";
  74 
  75     @Before
  76     public void setUp() {
  77         initWrappers();
  78         Environment.getEnvironment().setTimeout("wait.state", isEmbedded() ? 60000 : 2000);
  79         Environment.getEnvironment().setTimeout("wait.control", isEmbedded() ? 60000 : 1000);
  80         scene.mouse().move(new Point(0, 0));
  81     }
  82 
  83     @BeforeClass
  84     public static void setUpClass() throws Exception {
  85         PaginationApp.main(null);
  86         currentSettingOption = SettingOption.PROGRAM;
  87     }
  88 
  89     @After
  90     public void tearDown() {
  91         if (doNextResetHard) {
  92             resetSceneHard();
  93         } else {
  94             resetSceneSoft();
  95         }
  96 
  97         doNextResetHard = resetHardByDefault;
  98     }
  99 
 100     protected void initWrappers() {
 101         scene = Root.ROOT.lookup().wrap();
 102         parent = scene.as(Parent.class, Node.class);
 103 
 104         testedControl = (Wrap<? extends Pagination>) parent.lookup(Pagination.class, new ByID<Pagination>(TESTED_PAGINATION_ID)).wrap();
 105     }
 106 
 107     //                   ACTIONS
 108     protected void resetSceneSoft() {
 109         clickButtonForTestPurpose(SOFT_RESET_BUTTON_ID);
 110     }
 111 
 112     protected void resetSceneHard() {
 113         clickButtonForTestPurpose(HARD_RESET_BUTTON_ID);
 114     }
 115 
 116     protected void doNextResetHard() {
 117         doNextResetHard = true;
 118     }
 119 
 120     protected void doNextResetSoft() {
 121         doNextResetHard = false;
 122     }
 123 
 124     protected void setNewFactory() {
 125         clickButtonForTestPurpose(SET_NEW_PAGE_FACTORY_BUTTON_ID);
 126     }
 127 
 128     protected void setOldFactory() {
 129         clickButtonForTestPurpose(SET_OLD_PAGE_FACTORY_BUTTON_ID);
 130     }
 131 
 132     protected void setBulletStyleOfPageIndicators() {
 133         clickButtonForTestPurpose(SET_BULLET_PAGE_INDICATOR_BUTTON_ID);
 134     }
 135 
 136     protected void setIndeterminatePageCount() {
 137         clickButtonForTestPurpose(SET_PAGE_COUNT_TO_INDETERMINATE_BUTTON_ID);
 138     }
 139 
 140     protected void checkFormComponentButton() {
 141         clickButtonByID(FORM_BUTTON_ID);
 142         testedControl.waitState(new State<Integer>() {
 143             public Integer reached() {
 144                 return Integer.parseInt(findTextField(FORM_CLICK_TEXT_FIELD_ID).getControl().getText());
 145             }
 146         }, 1);
 147     }
 148 
 149     protected void checkScrollingOfFormComponentScrollBar() {
 150         Wrap<? extends ScrollBar> scrollBar = findScrollBar(testedControl.as(Parent.class, Node.class), Orientation.HORIZONTAL, true);
 151         scrollBar.mouse().turnWheel(-1);
 152         testedControl.waitState(new State<Integer>() {
 153             public Integer reached() {
 154                 return Integer.parseInt(findTextField(FORM_SCROLL_TEXT_FIELD_ID).getControl().getText());
 155             }
 156         }, 1);
 157 
 158         AbstractScroll c = scrollBar.as(AbstractScroll.class);
 159         c.allowError(0.01);
 160         double meanValue = getScrollBarCenter(scrollBar);
 161         c.caret().to(meanValue);
 162         assertTrue(Math.abs(meanValue - getScrollBarValue(scrollBar)) <= 1);
 163     }
 164 
 165     protected double getScrollBarValue(final Wrap<? extends ScrollBar> scrollBar) {
 166         return new GetAction<Double>() {
 167             @Override
 168             public void run(Object... os) throws Exception {
 169                 setResult(scrollBar.getControl().getValue());
 170             }
 171         }.dispatch(scrollBar.getEnvironment());
 172     }
 173 
 174     protected double getScrollBarCenter(final Wrap<? extends ScrollBar> scrollBar) {
 175         return new GetAction<Double>() {
 176             @Override
 177             public void run(Object... os) throws Exception {
 178                 setResult((scrollBar.getControl().getMax() - scrollBar.getControl().getMin()) / 2);
 179             }
 180         }.dispatch(scrollBar.getEnvironment());
 181     }
 182 
 183     protected void checkPrintingInInnerTextField() {
 184         final Wrap<? extends TextArea> editWrap = parent.lookup(TextArea.class, new ByID<TextArea>(FORM_TEXT_AREA_ID)).wrap();
 185         editWrap.as(Text.class).clear();
 186         editWrap.as(Text.class).type("New string");
 187         editWrap.waitState(new State<String>() {
 188             public String reached() {
 189                 return editWrap.getControl().getText();
 190             }
 191         }, "New string");
 192     }
 193 
 194     protected void navigateToPage(int pageIndex, NavigationWay nav) {
 195         int direction;
 196         while ((direction = checkDirectionForSearch(pageIndex)) != 0) {
 197             if (direction == 1) {
 198                 navigateToRight(nav);
 199             }
 200             if (direction == -1) {
 201                 navigateToLeft(nav);
 202             }
 203         }
 204         Wrap<? extends LabeledText>[] array = getSortedPageIndeces();
 205         for (int i = 0; i < array.length; i++) {
 206             if (Integer.parseInt(array[i].getControl().getText()) == pageIndex) {
 207                 array[i].mouse().click();
 208                 return;
 209             }
 210         }
 211     }
 212 
 213     private void navigateToRight(NavigationWay nav) {
 214         switch (nav) {
 215             case KEYBOARD:
 216                 testedControl.mouse().click(1, new Point(10, 10));
 217                 testedControl.keyboard().pushKey(KeyboardButtons.RIGHT);
 218                 break;
 219             case MOUSE:
 220                 clickArrowByStyleClass(rightArrowButtonStyleClass);
 221                 break;
 222         }
 223     }
 224 
 225     private void navigateToLeft(NavigationWay nav) {
 226         switch (nav) {
 227             case KEYBOARD:
 228                 testedControl.mouse().click(1, new Point(10, 10));
 229                 testedControl.keyboard().pushKey(KeyboardButtons.LEFT);
 230                 break;
 231             case MOUSE:
 232                 clickArrowByStyleClass(leftArrowButtonStyleClass);
 233                 break;
 234         }
 235     }
 236 
 237     /**
 238      * Checks, that shown content is respect to according page.
 239      *
 240      * @param isNewFactory : true - new; false - old.
 241      * @param pageIndex
 242      */
 243     protected void checkCorrectPageContentShowing(final boolean isNewFactory, final int pageIndex) {
 244         assertEquals(testedControl.as(Parent.class, Node.class).lookup(Label.class, new LookupCriteria<Label>() {
 245             public boolean check(Label cntrl) {
 246                 return (cntrl.getText().contains(PAGE_INDEX_PREFIX + pageIndex))
 247                         && (cntrl.getText().contains(isNewFactory ? NEW_FACTORY_MARKER : OLD_FACTORY_MARKER));
 248             }
 249         }).size(), LABELS_PER_PAGE, 0);
 250     }
 251 
 252     protected void setSize(double width, double height) throws InterruptedException {
 253         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.minWidth, width);
 254         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.minHeight, height);
 255 
 256         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.prefWidth, width);
 257         setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.prefHeight, height);
 258     }
 259 
 260     /**
 261      * 0 - begin, 1 - end.
 262      *
 263      * @param pos
 264      */
 265     protected void checkScrollBarPosition(final int pos) {
 266         ScrollBar sb = getScrollbarWrap(true).getControl();
 267         if (pos == 1) {
 268             assertTrue(sb.getMax() == sb.getValue());
 269         }
 270         if (pos == 0) {
 271             assertTrue(sb.getMin() == sb.getValue());
 272         }
 273     }
 274 
 275     protected Wrap<? extends ScrollBar> getScrollbarWrap(boolean visible) {
 276         return findScrollBar(testedControl.as(Parent.class, Node.class), Orientation.VERTICAL, visible);
 277     }
 278 
 279     protected void checkNumberOfVisiblePageIndeces(int expectedIndeces) {
 280         checkRightPageIndecesOrderAndContinuousOrder();
 281         Wrap<? extends LabeledText>[] array = getSortedPageIndeces();
 282         int len = array.length;
 283         assertEquals(len, expectedIndeces, 0);
 284     }
 285 
 286     protected void checkRangeOfPageIndecesVisibility(int expectedStart, int expectedEnd) {
 287         checkNumberOfVisiblePageIndeces(expectedEnd - expectedStart + 1);
 288         Wrap<? extends LabeledText>[] array = getSortedPageIndeces();
 289         int len = array.length;
 290 
 291         assertEquals(Integer.parseInt(array[0].getControl().getText()), expectedStart, 0);
 292         assertEquals(Integer.parseInt(array[len - 1].getControl().getText()), expectedEnd, 0);
 293     }
 294 
 295     protected void checkRightPageIndecesOrderAndContinuousOrder() {
 296         testedControl.waitState(new State() {
 297             public Object reached() {
 298                 Wrap<? extends LabeledText>[] array = getSortedPageIndeces();
 299                 return array.length > 0 ? true : null;
 300             }
 301         });
 302 
 303         Wrap<? extends LabeledText>[] array = getSortedPageIndeces();
 304 
 305         double initialY = array[0].getScreenBounds().y;
 306         for (int i = 1; i < array.length; i++) {
 307             assertTrue(Math.abs(initialY - array[i].getScreenBounds().y) <= yDeltaInPageIndeces);
 308             assertTrue(array[i - 1].getScreenBounds().x < array[i].getScreenBounds().x);
 309             assertTrue(Integer.parseInt(array[i - 1].getControl().getText()) + 1 == Integer.parseInt(array[i].getControl().getText()));
 310         }
 311     }
 312 
 313     private void clickArrowByStyleClass(final String name) {
 314         Lookup res = findArrow(name);
 315 
 316         if (res.size() == 0) {
 317             throw new IllegalStateException("Cannot find arrow : " + name);
 318         }
 319 
 320         if (((Node) ((Wrap) res.wrap()).getControl()).isVisible()) {
 321             ((Wrap) res.wrap()).mouse().click();
 322         } else {
 323             throw new IllegalStateException("Want to press an invisible control.");
 324         }
 325     }
 326 
 327     private Lookup findArrow(final String name) {
 328         return testedControl.as(Parent.class, Node.class).lookup(StackPane.class, new LookupCriteria<StackPane>() {
 329             public boolean check(StackPane cntrl) {
 330                 if ((cntrl.getStyleClass().size() == 1) && (cntrl.getStyleClass().get(0).equals(name))) {
 331                     return true;
 332                 } else {
 333                     return false;
 334                 }
 335             }
 336         });
 337     }
 338 
 339     protected void checkTwoArrowsVisibility(boolean leftVisiblity, boolean rightVisibility) {
 340         checkArrowNonDisabledState(true, leftVisiblity);
 341         checkArrowNonDisabledState(false, rightVisibility);
 342     }
 343 
 344     protected int adjustNumber(int min, int max, int value) {
 345         assertTrue(min < max);
 346         if (value < min) {
 347             return min;
 348         }
 349         if (value > max) {
 350             return max;
 351         }
 352         return value;
 353     }
 354 
 355     /**
 356      *
 357      * @param left - true - left, false - right.
 358      */
 359     protected void checkArrowNonDisabledState(boolean left, boolean nonDisabled) {
 360         final String name = left ? leftArrowButtonStyleClass : rightArrowButtonStyleClass;
 361         Lookup res = findArrow(name);
 362 
 363         if (res.size() == 0) {
 364             throw new IllegalStateException("Cannot find arrow : " + name);
 365         }
 366 
 367         assertEquals(((Node) ((Wrap) res.wrap()).getControl()).isDisabled(), !nonDisabled);
 368     }
 369 
 370     /**
 371      * @param itemToFind - page index.
 372      * @return +1 to press right; -1 to press left; 0, if we can click item and
 373      * it is visible. can throw exception.
 374      */
 375     private int checkDirectionForSearch(int itemToFind) {
 376         checkRightPageIndecesOrderAndContinuousOrder();
 377         Wrap<? extends LabeledText>[] array = getSortedPageIndeces();
 378         int len = array.length;
 379 
 380         for (int i = 0; i < len; i++) {
 381             if (Integer.parseInt(array[i].getControl().getText()) == itemToFind) {
 382                 return 0;
 383             }
 384         }
 385 
 386         if (Integer.parseInt(array[0].getControl().getText()) > itemToFind) {
 387             return -1;
 388         }
 389         if (Integer.parseInt(array[len - 1].getControl().getText()) < itemToFind) {
 390             return +1;
 391         }
 392 
 393         throw new IllegalStateException("Can't find direction for search because of unknown issue. " + array.toString());
 394     }
 395 
 396     private Lookup<LabeledText> findVisiblePageIndeces() {
 397         final Parent<Node> testedControlAsParent = testedControl.as(Parent.class, Node.class);
 398         Parent<Node> foundStackPaneInControlAsParent = testedControlAsParent.lookup(StackPane.class, new LookupCriteria<StackPane>() {
 399             public boolean check(StackPane cntrl) {
 400                 if (cntrl.getStyleClass().contains("pagination-control")) {
 401                     return true;
 402                 } else {
 403                     return false;
 404                 }
 405             }
 406         }).wrap().as(Parent.class, Node.class);
 407         return foundStackPaneInControlAsParent.lookup(LabeledText.class, new LookupCriteria<LabeledText>() {
 408             public boolean check(LabeledText cntrl) {
 409                 try {
 410                     Integer.parseInt(cntrl.getText());
 411                 } catch (Throwable ex) {
 412                     return false;
 413                 }
 414                 //return !cntrl.getText().contains("/");
 415                 return true;
 416             }
 417         });
 418     }
 419 
 420     private Wrap<? extends LabeledText>[] getSortedPageIndeces() {
 421         Lookup<LabeledText> visiblePageIndeces = findVisiblePageIndeces();
 422 
 423         ArrayList<Wrap<? extends LabeledText>> list = new ArrayList<Wrap<? extends LabeledText>>();
 424         for (int i = 0; i < visiblePageIndeces.size(); i++) {
 425             list.add(visiblePageIndeces.wrap(i));
 426         }
 427         Wrap<? extends LabeledText>[] array = list.toArray(new Wrap[0]);
 428 
 429         Arrays.sort(array, new Comparator<Wrap<? extends LabeledText>>() {
 430             public int compare(Wrap<? extends LabeledText> t, Wrap<? extends LabeledText> t1) {
 431                 String s1 = t.getControl().getText();
 432                 String s2 = t1.getControl().getText();
 433                 int int1 = Integer.parseInt("".equals(s1) ? "-1" : s1);
 434                 int int2 = Integer.parseInt("".equals(s2) ? "-1" : s2);
 435 
 436                 return int1 - int2;
 437             }
 438         });
 439 
 440         return array;
 441     }
 442     private double yDeltaInPageIndeces = 0;
 443 
 444     static protected enum NavigationWay {
 445 
 446         MOUSE, KEYBOARD
 447     };
 448 
 449     static protected enum Properties {
 450 
 451         minWidth, minHeight, prefWidth, prefHeight, maxHeight, maxWidth, currentPageIndex, pageCount, maxPageIndicatorCount
 452     };
 453 }