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.tabpane;
  26 
  27 import client.test.Smoke;
  28 import java.util.Comparator;
  29 import java.util.HashMap;
  30 import java.util.List;
  31 import java.util.Map;
  32 import javafx.collections.FXCollections;
  33 import javafx.collections.ObservableList;
  34 import javafx.commons.SortValidator;
  35 import javafx.geometry.Orientation;
  36 import javafx.scene.Node;
  37 import javafx.scene.control.Label;
  38 import javafx.scene.control.Tab;
  39 import static javafx.scene.control.test.tabpane.NewTabPaneApp.*;
  40 import javafx.scene.control.test.utils.ptables.AbstractPropertyController.SettingType;
  41 import javafx.util.StringConverter;
  42 import org.jemmy.action.GetAction;
  43 import org.jemmy.control.Wrap;
  44 import org.jemmy.fx.control.TabWrap;
  45 import org.jemmy.interfaces.Keyboard.KeyboardButtons;
  46 import org.jemmy.interfaces.Parent;
  47 import org.jemmy.lookup.Lookup;
  48 import org.jemmy.lookup.LookupCriteria;
  49 import org.junit.Assert;
  50 import static org.junit.Assert.*;
  51 import org.junit.Test;
  52 
  53 /**
  54  * @author Dmitry Zinkevich <dmitry.zinkevich@oracle.com>
  55  */
  56 public class NewTabPaneTest extends NewTabPaneBase {
  57 
  58     /**
  59      * Disables the tab and then tries to switch to it by mouse clicking
  60      */
  61     @Smoke
  62     @Test(timeout = 300000)
  63     public void disablePropertyBindingTest() {
  64         final int NUM_TABS = SettingType.values().length + 1; //Number of tabs
  65         final List<String> tabs = populateTabPane(NUM_TABS); //Tabs names
  66 
  67         /*
  68          * Click on the fist tab and ensure it is selected.
  69          * It must remain selectet through all the test
  70          */
  71         getPlaceholderWrap((Tab) tabPaneAsSelectable.getStates().get(0)).mouse().click();
  72 
  73         final Tab firstTab = getSelectedTab();
  74 
  75         Assert.assertSame((Tab) tabPaneAsSelectable.getStates().get(0), firstTab);
  76 
  77         int testedIndex = NUM_TABS - 1;
  78 
  79         for (SettingType settingType : SettingType.values()) {
  80             System.out.println(String.format("Tested binding: %s", settingType.name()));
  81 
  82             initChangingController(parent);
  83             defaultController.include().allTables().allProperties().allCounters().apply();
  84             defaultController.exclude().allTables().properties(TabProperties.hover, TabProperties.pressed).apply();
  85             defaultController.fixCurrentState();
  86 
  87             /*
  88              * Disable tab
  89              */
  90             switchToPropertiesTab(tabs.get(testedIndex));
  91             setPropertyByToggleClick(settingType, TabProperties.disable, Boolean.TRUE);
  92 
  93             /*
  94              * Check disableProperty and disabledProperty
  95              */
  96             checkTextFieldText(TabProperties.disable, "true");
  97             checkTextFieldText(TabProperties.disabled, "true");
  98 
  99             Tab selectedTab = getSelectedTab();
 100             Assert.assertSame("Selected tab is still the same after changing property", firstTab, selectedTab);
 101 
 102             /*
 103              * Click on the disabled tab. Previously selected tab must be the same
 104              */
 105             Wrap<? extends Node> tab = getPlaceholderWrap((Tab) tabPaneAsSelectable.getStates().get(testedIndex));
 106             tab.mouse().click();
 107 
 108             defaultController.check();
 109 
 110             selectedTab = getSelectedTab();
 111             Assert.assertSame("Selected tab is still the same after click", firstTab, selectedTab);
 112 
 113             testedIndex--;
 114         }
 115     }
 116 
 117     /**
 118      * Sets tab prop closable to 'true' and then tries to close it
 119      */
 120     @Smoke
 121     @Test(timeout = 300000)
 122     public void closablePropertyBindingTest() {
 123         final int NUM_TABS = SettingType.values().length + 1;
 124         final List<String> tabs = populateTabPane(NUM_TABS);
 125 
 126         int testedIndex = NUM_TABS - 1;
 127 
 128         for (SettingType settingType : SettingType.values()) {
 129             System.out.println(String.format("Tested binding: %s", settingType.name()));
 130 
 131             initChangingController(parent);
 132 
 133             defaultController.include().allTables().allProperties().allCounters().apply();
 134             defaultController.exclude().allTables().properties(TabProperties.hover, TabProperties.selected, TabProperties.pressed).apply();
 135             defaultController.fixCurrentState();
 136 
 137             switchToPropertiesTab(tabs.get(testedIndex));
 138             setPropertyByToggleClick(settingType, TabProperties.closable, Boolean.FALSE);
 139 
 140             checkTextFieldText(TabProperties.closable, "false");
 141 
 142             /*
 143              * Click on the disabled tab.
 144              * Previously selected tab must be the same
 145              */
 146             Wrap<? extends Node> tab = getPlaceholderWrap((Tab) tabPaneAsSelectable.getStates().get(testedIndex));
 147             tab.mouse().click();
 148 
 149             TabWrap tabWrap = getTabWrapByIndex(testedIndex);
 150             try {
 151                 tabWrap.close();
 152             } catch (Exception e) {
 153                 System.out.println(String.format("After a closing attempt when closable = 'false':\n%s", e.getMessage()));
 154             }
 155 
 156             checkTextFieldText(TabProperties.selected, "true");
 157 
 158             defaultController.check();
 159             testedIndex--;
 160         }
 161     }
 162 
 163     /**
 164      * Checks API setUserData/getUserData
 165      */
 166     @Smoke
 167     @Test(timeout = 300000)
 168     public void userDataAPITest() {
 169         final java.util.List<String> userData = new java.util.ArrayList<String>();
 170         userData.add("Tested user data");
 171 
 172         populateTabPane(1);
 173 
 174         initChangingController(parent);
 175 
 176         defaultController.include().allTables().allProperties().allCounters().apply();
 177         defaultController.fixCurrentState();
 178 
 179         setUserData(0, userData);
 180 
 181         java.util.List<String> actualData = (java.util.List<String>) getUserData(0);
 182 
 183         Assert.assertEquals("User data represents the same object", userData, actualData);
 184 
 185         defaultController.check();
 186     }
 187 
 188     /**
 189      * Checks API getProperties/hasProperties
 190      */
 191     @Smoke
 192     @Test(timeout = 300000)
 193     public void propertiesAPITest() {
 194         Map<Object, Object> testedData = new HashMap<Object, Object>();
 195         for (int i = 0; i < 5; i++) {
 196             testedData.put(String.format("_Key #%d", i), new Tab(String.format("_Tab #%d", i)));
 197         }
 198 
 199         populateTabPane(1);
 200 
 201         initChangingController(parent);
 202         defaultController.include().allTables().allProperties().allCounters().apply();
 203         defaultController.fixCurrentState();
 204 
 205         Assert.assertFalse("hasProperties() must return false", tabHasProperties(0));
 206         Assert.assertTrue("Initial properties collection is empty", getPropertiesCount(0) == 0);
 207 
 208         setProperties(0, testedData);
 209 
 210         Map<Object, Object> actualProps = getProperties(0);
 211 
 212         Assert.assertTrue("hasProperties() must return true", tabHasProperties(0));
 213         Assert.assertTrue("Properties collection remains the same", testedData.equals(actualProps));
 214 
 215         defaultController.check();
 216     }
 217 
 218     /**
 219      * Checks API hasProperties
 220      */
 221     @Smoke
 222     @Test(timeout = 300000)
 223     public void hasPropertiesMethodTest() {
 224         populateTabPane(1);
 225 
 226         initChangingController(parent);
 227         defaultController.include().allTables().allProperties().allCounters().apply();
 228         defaultController.fixCurrentState();
 229 
 230         Assert.assertFalse("hasProperties() must return false", tabHasProperties(0));
 231         Assert.assertTrue("Initial properties collection is empty", getPropertiesCount(0) == 0);
 232         Assert.assertFalse("hasProperties() must return false", tabHasProperties(0));
 233 
 234         defaultController.check();
 235     }
 236 
 237     /**
 238      * This test dynamicaly changes focused state of control with the only tab,
 239      * and checks, that there is a focus.
 240      *
 241      * Bug on test creation RT-27869.
 242      */
 243     @Test(timeout = 300000)
 244     @Smoke
 245     public void visualFocusScreenshotTest() throws Throwable {
 246         final String NOT_FOCUSED_TAB_SCREENSHOT_NAME = "TabPane-not_focused_tab";
 247         final String FOCUSED_TAB_SCREENSHOT_NAME = "TabPane-focused_tab";
 248 
 249         addTab("FIRST", 0);
 250 
 251         //Time of adding animation.
 252         Thread.sleep(500);
 253 
 254         moveFocusFromTestedControl();
 255 
 256         checkScreenshot(NOT_FOCUSED_TAB_SCREENSHOT_NAME, testedControl);
 257 
 258         tabPaneAsSelectable.selector().select(tabPaneAsSelectable.getStates().get(0));
 259         moveMouseFromTestedControl();
 260 
 261         checkScreenshot(FOCUSED_TAB_SCREENSHOT_NAME, testedControl);
 262 
 263         testedControl.keyboard().pushKey(KeyboardButtons.TAB);
 264 
 265         checkScreenshot(NOT_FOCUSED_TAB_SCREENSHOT_NAME, testedControl);
 266 
 267         requestFocusOnControl(testedControl);
 268         moveMouseFromTestedControl();
 269 
 270         checkScreenshot(FOCUSED_TAB_SCREENSHOT_NAME, testedControl);
 271 
 272         moveFocusFromTestedControl();
 273 
 274         checkScreenshot(NOT_FOCUSED_TAB_SCREENSHOT_NAME, testedControl);
 275 
 276         throwScreenshotError();
 277     }
 278 
 279     /**
 280      * Test checks possibility of content to veto tab closing. A label with such
 281      * possibility is added as content of tab, and it will veto the tab closing.
 282      *
 283      * Bug on test creation RT-27823.
 284      */
 285     @Test(timeout = 300000)
 286     @Smoke
 287     public void contentVetoTest() {
 288         final String vetoTabName = "vetoTab";
 289         final String nonVetoTabName = "nonVetoTab";
 290 
 291         addTab(vetoTabName, 0, true, true);
 292 
 293         addTab(nonVetoTabName, 1, true, false);
 294 
 295         checkTabsCount(2);
 296 
 297         switchToPropertiesTab(vetoTabName);
 298         checkCounterValue(TAB_CLOSE_REQUEST_EVENT, 0);
 299         switchToPropertiesTab(nonVetoTabName);
 300         checkCounterValue(TAB_CLOSE_REQUEST_EVENT, 0);
 301 
 302         tryToCloseTabByIndex(0);
 303 
 304         checkTabsCount(2);
 305 
 306         switchToPropertiesTab(vetoTabName);
 307         checkCounterValue(TAB_CLOSE_REQUEST_EVENT, 1);
 308         switchToPropertiesTab(nonVetoTabName);
 309         checkCounterValue(TAB_CLOSE_REQUEST_EVENT, 0);
 310 
 311         tryToCloseTabByIndex(1);
 312 
 313         checkTabsCount(1);
 314 
 315         switchToPropertiesTab(vetoTabName);
 316         checkCounterValue(TAB_CLOSE_REQUEST_EVENT, 1);
 317         switchToPropertiesTab(nonVetoTabName);
 318         checkCounterValue(TAB_CLOSE_REQUEST_EVENT, 1);
 319     }
 320 
 321     /**
 322      * Checks that when the sorting is applied
 323      * to the underlying data collection
 324      * the tabs are rendered in the right order.
 325      */
 326     @Smoke
 327     @Test(timeout=30000)
 328     public void renderingAfterSortingTest() {
 329         final int ITEMS_COUNT = 3;
 330 
 331         StringConverter<Tab> conv = new StringConverter<Tab>() {
 332             @Override public String toString(Tab t) { return t.getText(); }
 333 
 334             @Override public Tab fromString(String s) {
 335                 Tab t = new Tab(s);
 336                 t.setContent(new Label("CONTENT!"));
 337                 return t;
 338             }
 339         };
 340 
 341         SortValidator<Tab, Label> validator = new SortValidator<Tab, Label>(ITEMS_COUNT, conv) {
 342 
 343             @Override
 344             protected void setControlData(final ObservableList<Tab> ls) {
 345                 new GetAction<Object>() {
 346                     @Override
 347                     public void run(Object... parameters) throws Exception {
 348                         testedControl.getControl().getTabs().setAll(ls);
 349                     }
 350                 }.dispatch(testedControl.getEnvironment());
 351             }
 352 
 353             @Override
 354             protected Lookup<? extends Label> getCellsLookup() {
 355                 return testedControl.as(Parent.class, Label.class)
 356                               .lookup(Label.class, new LookupCriteria<Label>() {
 357 
 358                     public boolean check(Label lbl) {
 359                         return lbl.getStyleClass().contains("tab-label")
 360                                 && lbl.isVisible();
 361                     }
 362                 });
 363             }
 364 
 365             @Override
 366             protected String getTextFromCell(Label cell) {
 367                 return cell.getText();
 368             }
 369 
 370             @Override
 371             protected void sort() {
 372                 new GetAction<Object>() {
 373                     @Override
 374                     public void run(Object... os) throws Exception {
 375                         FXCollections.sort(testedControl.getControl().getTabs(), new Comparator<Tab>() {
 376                             @Override
 377                             public int compare(Tab o1, Tab o2) {
 378                                 return o1.getText().compareTo(o2.getText());
 379                             }
 380                         });
 381                     }
 382                 }.dispatch(testedControl.getEnvironment());
 383             }
 384         };
 385         validator.setOrientation(Orientation.HORIZONTAL);
 386         boolean result = validator.check();
 387         String msg = validator.getFailureReason();
 388         assertTrue(msg, result);
 389     }
 390 }