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