org.auraframework.components.ui.modalOverlay.Panel2ModalOverlayUITest.java Source code

Java tutorial

Introduction

Here is the source code for org.auraframework.components.ui.modalOverlay.Panel2ModalOverlayUITest.java

Source

/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.auraframework.components.ui.modalOverlay;

import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.List;

import org.auraframework.test.util.*;
import org.auraframework.test.util.WebDriverTestCase.ExcludeBrowsers;
import org.auraframework.test.util.WebDriverUtil.BrowserType;
import org.openqa.selenium.*;

@ExcludeBrowsers({ BrowserType.ANDROID_PHONE, BrowserType.ANDROID_TABLET, BrowserType.IPHONE, BrowserType.IPAD,
        BrowserType.IE7, BrowserType.IE8 })
public class Panel2ModalOverlayUITest extends WebDriverTestCase {
    private final String APP = "/uitest/panel2_Test.app";
    private final String PARAM_PANEL_TYPE = "&testPanelType=";
    private final String PARAM_DIRECTION = "&testDirection=";
    private final String PARAM_USE_FOOTER = "&testUseFooter=";
    private final String FLAVOR = "&testFlavor=";
    private final String CREATE_PANEL_BUTTON = ".createPanelBtnClass";
    private final String PANEL_DIALOG = ".uiPanel";
    private final String PANEL_MODAL = ".uiModal";
    private final String CLOSE_ON_CLICKOUT = ".inputcloseOnClickOutClass";
    private final String MAKE_SCROLLABLE = ".inputMakeScrollableClass";
    private final String MAKE_NONSCROLLABLE = ".inputNonScrollableClass";
    private final String ENABLE_CUSTOM_CLOSEACTION = ".inputCustomizeCloseAction";
    private final String INPUT_PANELTYPE = ".inputPanelTypeClass";
    private final String INPUT_AUTOFOCUS = ".inputAutoFocusClass";

    private final String ACTIVE_ELEMENT = "return $A.test.getActiveElement()";
    private final String APP_INPUT = ".appInput";
    private final String APP_INPUT2 = ".appInput2";

    public Panel2ModalOverlayUITest(String name) {
        super(name);
    }

    /**
     * [Accessibility] modal closing on Esc key. Bug: W-2617212
     */
    public void testPressEscKeyOnModalWithAutoFocusSet() throws Exception {
        String panelType = "modal";
        Boolean autoFocus = true;
        verifyCloseOnEsc(panelType, autoFocus);
    }

    /**
     * [Accessibility] panel dialog closing on Esc key. Bug: W-2643030
     */
    public void testPressEscKeyOnPanelDialogWithAutoFocusSet() throws Exception {
        String panelType = "panel";
        Boolean autoFocus = true;
        verifyCloseOnEsc(panelType, autoFocus);
    }

    /**
     * [Accessibility] modal closing on Esc key. Bug: W-2617212
     */
    public void testPressEscKeyOnModalWithAutoFocusNotSet() throws Exception {
        String panelType = "modal";
        Boolean autoFocus = false;
        verifyCloseOnEsc(panelType, autoFocus);
    }

    /**
     * [Accessibility] panel dialog closing on Esc key. Bug: W-2643030
     */
    public void testPressEscKeyOnPanelDialogWithAutoFocusNotSet() throws Exception {
        String panelType = "panel";
        Boolean autoFocus = false;
        verifyCloseOnEsc(panelType, autoFocus);
    }

    private void verifyCloseOnEsc(String panelType, Boolean autoFocus)
            throws MalformedURLException, URISyntaxException, InterruptedException {
        String url = APP;
        boolean isPanel = panelType.contains("panel");
        if (isPanel) {
            url += "?" + PARAM_PANEL_TYPE + panelType;
        }
        open(url);
        if (!autoFocus) {
            // disable autoFocus
            WebElement autoFocusElement = findDomElement(By.cssSelector(INPUT_AUTOFOCUS));
            autoFocusElement.click();
        }
        openPanel();
        if (isPanel) {
            waitForPanelDialogOpen();
        } else {
            waitForModalOpen();
        }
        WebElement activeElement = (WebElement) auraUITestingUtil.getEval(ACTIVE_ELEMENT);
        activeElement.sendKeys(Keys.ESCAPE);
        if (isPanel) {
            waitForPanelDialogClose();
        } else {
            waitForModalClose();
        }
    }

    /**
     * Verify custom close action Bug: W-2619406
     */
    public void testPressEscKeyOnPanelDialogWhenCloseActionSet() throws Exception {
        open(APP + "?" + PARAM_PANEL_TYPE + "panel");
        WebElement enableCustomCloseAction = findDomElement(By.cssSelector(ENABLE_CUSTOM_CLOSEACTION));
        enableCustomCloseAction.click();

        openPanel();
        waitForPanelDialogOpen();

        WebElement fistInputElement = findDomElements(By.cssSelector(INPUT_PANELTYPE)).get(1);
        fistInputElement.click();

        fistInputElement.sendKeys(Keys.ESCAPE);
        // ESC does not close the panel
        waitForPanelDialogOpen();
        String actionType = "closeOnEsc";
        verifyCustomCloseActionMethodCalled(actionType);
    }

    private void verifyCustomCloseActionMethodCalled(String actionType) {
        String panelGlobalId = findDomElements(By.cssSelector(".info .idCurrent")).get(0).getText();
        String attrValueExp = auraUITestingUtil.getValueFromCmpExpression(panelGlobalId, "v.closeActionCalled");

        String attrValueText = (String) auraUITestingUtil.getEval(attrValueExp);
        String expectedText = String.format("CloseActionCustomMethodCalled when %s", actionType);
        assertEquals("Custom close on Action method was not called", expectedText, attrValueText);
    }

    /**
     * Test modal does have scrollbar when content is not so long Test case: W-2615146
     */
    public void testModalWithScrollBar() throws Exception {
        verifyScrollbarPresent(true, MAKE_SCROLLABLE);
    }

    /**
     * Test modal does have scrollbar when content is not so long Test case: W-2615146
     * 
     * Excluding in IE11 for now because added extra padding to modal-body causing scroller to appear because font is
     * bigger than body and the body has overflow-y:auto. Tried css changes to outputText but it did not work.
     */
    @ExcludeBrowsers({ BrowserType.IE11 })
    public void testModalWithoutScrollBar() throws Exception {
        verifyScrollbarPresent(false, MAKE_NONSCROLLABLE);
    }

    private void verifyScrollbarPresent(boolean hasScrollbar, String locator)
            throws MalformedURLException, URISyntaxException, InterruptedException {
        open(APP);
        String errorMessage = "Scroller should not be present for Modal body";
        WebElement makeScrollable = findDomElement(By.cssSelector(locator));
        makeScrollable.click();

        if (hasScrollbar) {
            errorMessage = "Scroller should be present for Modal body";
        }
        openPanel();
        waitForModalOpen();
        String bodyClassName = "modal-body";
        boolean hasScroll = auraUITestingUtil.hasScrollBar(bodyClassName);
        assertEquals(errorMessage, hasScrollbar, hasScroll);
    }

    /**
     * Test multiple modal one above another, should close top panel when we press ESC on the newest panel
     */
    public void testMultipleModalPressEscKeyWithAutoFocusSet() throws Exception {
        verifyPressingEscOnMultipleModalDestorysModal(PANEL_MODAL, true);
    }

    public void testMultipleModalPressEscKeyWithAutoFocusNotSet() throws Exception {
        verifyPressingEscOnMultipleModalDestorysModal(PANEL_MODAL, false);
    }

    public void testMultiplePanelPressEscKeyWithAutoFocusSet() throws Exception {
        verifyPressingEscOnMultipleModalDestorysModal(PANEL_DIALOG, true);
    }

    public void testMultiplePanelPressEscKeyWithAutoFocusNotSet() throws Exception {
        verifyPressingEscOnMultipleModalDestorysModal(PANEL_DIALOG, false);
    }

    private void verifyPressingEscOnMultipleModalDestorysModal(String locator, boolean autoFocus)
            throws MalformedURLException, URISyntaxException, InterruptedException {
        String url = APP;
        boolean isPanel = locator.contains(PANEL_DIALOG);
        String errorMessage = "modal";
        if (isPanel) {
            url += "?" + PARAM_PANEL_TYPE + "panel";
            errorMessage = "panel";
        }

        open(url);

        // disable autoFocus for modal 1
        if (!autoFocus) {
            WebElement autoFocusElement = findDomElement(By.cssSelector(INPUT_AUTOFOCUS));
            autoFocusElement.click();
        }

        openPanel();
        if (locator.contains(PANEL_MODAL)) {
            waitForModalOpen();
        } else {
            waitForPanelDialogOpen();
            WebElement fistInputElement = findDomElements(By.cssSelector(INPUT_PANELTYPE)).get(1);
            fistInputElement.clear();
            fistInputElement.click();
            fistInputElement.sendKeys("panel");
        }

        WebElement firstModalPanel = findDomElements(By.cssSelector(locator)).get(0);
        assertTrue(String.format("First %s should have class active", errorMessage),
                firstModalPanel.getAttribute("class").contains("active"));
        // open second modal
        openPanel(2);
        waitForNumberOfPanels(locator, 2);

        WebElement secondModalPanel = findDomElements(By.cssSelector(locator)).get(1);
        assertFalse(String.format("First %s should have not have class active", errorMessage),
                firstModalPanel.getAttribute("class").contains("active"));
        assertTrue(String.format("Second %s should have class active", errorMessage),
                secondModalPanel.getAttribute("class").contains("active"));

        WebElement activeElement = (WebElement) auraUITestingUtil.getEval(ACTIVE_ELEMENT);
        activeElement.sendKeys(Keys.ESCAPE);
        waitForNumberOfPanels(locator, 1);

        assertTrue(String.format("First %s should have class active after press ESC on 2nd %s", errorMessage,
                errorMessage), firstModalPanel.getAttribute("class").contains("active"));

        activeElement = (WebElement) auraUITestingUtil.getEval(ACTIVE_ELEMENT);
        activeElement.sendKeys(Keys.ESCAPE);
        waitForNumberOfPanels(locator, 0);
    }

    /**
     * [Accessibility] panel dialog should not close when closeOnClickOut is not set to true
     */
    public void testPanelDialogWithCloseOnClickOutNotSet() throws Exception {
        open(APP + "?" + PARAM_PANEL_TYPE + "panel");
        openPanel();
        waitForPanelDialogOpen();

        WebElement inputText = findDomElement(By.cssSelector(APP_INPUT));
        inputText.click();
        waitForNumberOfPanels(PANEL_DIALOG, 1);
    }

    /**
     * [Accessibility] panel dialog should close when closeOnClickOut is set to true
     */
    public void testPanelDialogWithCloseOnClickOutSet() throws Exception {
        open(APP + "?" + PARAM_PANEL_TYPE + "panel");
        WebElement closeOutChexbox = findDomElement(By.cssSelector(CLOSE_ON_CLICKOUT));
        closeOutChexbox.click();
        openPanel();
        waitForPanelDialogOpen();

        WebElement inputText = findDomElement(By.cssSelector(APP_INPUT));
        inputText.click();
        waitForNumberOfPanels(PANEL_DIALOG, 0);
    }

    /**
     * Verify custom close action Bug: W-2619406
     */
    public void testPanelDialogWithCloseOnClickOutSetAndCustomCloseActionSet() throws Exception {
        open(APP + "?" + PARAM_PANEL_TYPE + "panel");
        WebElement closeOutChexbox = findDomElement(By.cssSelector(CLOSE_ON_CLICKOUT));
        closeOutChexbox.click();
        WebElement enableCustomCloseAction = findDomElement(By.cssSelector(ENABLE_CUSTOM_CLOSEACTION));
        enableCustomCloseAction.click();
        openPanel();
        waitForPanelDialogOpen();

        WebElement inputText = findDomElement(By.cssSelector(APP_INPUT));
        inputText.click();
        // Click outside should not close the panel
        waitForPanelDialogOpen();

        String actionType = "closeOnClickOut";
        verifyCustomCloseActionMethodCalled(actionType);
    }

    /**
     * Tabs on Modal overlay should do focus trapping and not close the overlay
     */
    public void testModalFocusTrapping() throws Exception {
        String panelType = "modal";
        String url = APP + "?" + PARAM_PANEL_TYPE + panelType;
        open(url);
        cycleThroughPanelInputElements(url, "modal", false);
    }

    /**
     * Tabs on panel dialog should close the panel and not trap the focus within the panel
     */
    public void testPanelDoesNotDoFocusTrapping() throws Exception {
        String panelType = "panel";
        String url = APP + "?" + PARAM_PANEL_TYPE + panelType;
        open(url);
        cycleThroughPanelInputElements(url, "panel", true);
    }

    /**
     * Verify custom close action Bug: W-2619406
     */
    public void testPanelTabOutCallsCustomCloseActionWhenSet() throws Exception {
        String panelType = "panel";
        String url = APP + "?" + PARAM_PANEL_TYPE + panelType;
        open(url);
        WebElement enableCustomCloseAction = findDomElement(By.cssSelector(ENABLE_CUSTOM_CLOSEACTION));
        enableCustomCloseAction.click();
        cycleThroughPanelInputElements(url, "panel", false);
        String actionType = "closeOnTabOut";
        verifyCustomCloseActionMethodCalled(actionType);
    }

    /**
     * Tabs on panel with full-screen should close the panel and not trap the focus within the panel
     */
    public void testPanelWithFullScreenDoesNotDoFocusTrapping() throws Exception {
        String panelType = "panel";
        String flavor = "full-screen";
        String url = APP + "?" + PARAM_PANEL_TYPE + panelType + FLAVOR + flavor;
        open(url);
        cycleThroughPanelInputElements(url, "panel", true);
    }

    /**
     * Tab out closes panel and sets focus back on element that called it. Test panel focuses on reference element after
     * its been closed.
     */
    public void testPanelTabOutFocus() throws Exception {
        String url = APP + "?" + PARAM_PANEL_TYPE + "panel" + PARAM_DIRECTION + "south";

        open(url);

        // open panel
        WebElement input = findDomElement(By.cssSelector(APP_INPUT2));
        input.click();
        waitForPanelDialogOpen();

        // tab out to close
        WebElement activeElement = (WebElement) auraUITestingUtil.getEval(ACTIVE_ELEMENT);
        activeElement.sendKeys(Keys.TAB);
        waitForPanelDialogClose();

        // check focus
        activeElement = (WebElement) auraUITestingUtil.getEval(ACTIVE_ELEMENT);
        assertTrue("Active element is not app input", activeElement.getAttribute("class").contains("appInput2"));
    }

    /**
     * Test tabbing goes through footer
     */
    public void testPanelTabWithFooter() throws Exception {
        String url = APP + "?" + PARAM_PANEL_TYPE + "modal" + PARAM_USE_FOOTER + "true";

        open(url);
        cycleThroughPanelInputElements(url, "modal", false);

        // check focus on footer's button
        WebElement activeElement = (WebElement) auraUITestingUtil.getEval(ACTIVE_ELEMENT);
        assertTrue("Active element is not button in footer",
                activeElement.getAttribute("class").contains("defaultCustomPanelFooterBtn"));
    }

    private void cycleThroughPanelInputElements(String url, String panelType, boolean doesPanelClose)
            throws Exception {
        openPanel();
        if (panelType.equals("modal")) {
            waitForModalOpen();
        } else {
            waitForPanelDialogOpen();
        }
        List<WebElement> firstInput = findDomElements(By.cssSelector(INPUT_PANELTYPE));
        firstInput.get(1).click();
        WebElement activeElement = (WebElement) auraUITestingUtil.getEval(ACTIVE_ELEMENT);
        // assertEquals("Focus should be on first element", panelType, auraUITestingUtil.getEval(ACTIVE_ELEMENT_TEXT));
        int numElements = 24;
        // cycle through input elements on panel
        for (int i = 1; i < numElements; i++) {
            activeElement.sendKeys(Keys.TAB);
            activeElement = (WebElement) auraUITestingUtil.getEval(ACTIVE_ELEMENT);
        }

        // on close button
        activeElement.sendKeys(Keys.TAB);

        if (doesPanelClose) {
            if (panelType.equals("modal")) {
                waitForModalClose();
            } else {
                waitForPanelDialogClose();
            }
        } else {
            /*
             * activeElement = (WebElement) auraUITestingUtil.getEval(ACTIVE_ELEMENT);
             * assertEquals("Panel should not be close and focus should be on first element", panelType,
             * auraUITestingUtil.getEval(ACTIVE_ELEMENT_TEXT));
             */
            if (panelType.equals("modal")) {
                waitForModalOpen();
            } else {
                waitForPanelDialogOpen();
            }
        }
    }

    private void openPanel() {
        openPanel(1);
    }

    private void openPanel(int panelNumber) {
        List<WebElement> createPanelBtn = findDomElements(By.cssSelector(CREATE_PANEL_BUTTON));
        createPanelBtn.get(panelNumber - 1).click();
    }

    private void waitForModalOpen() throws InterruptedException {
        waitForPanel(PANEL_MODAL, true);
    }

    private void waitForModalClose() throws InterruptedException {
        waitForPanel(PANEL_MODAL, false);
    }

    private void waitForPanelDialogOpen() throws InterruptedException {
        waitForPanel(PANEL_DIALOG, true);
    }

    private void waitForPanelDialogClose() throws InterruptedException {
        waitForPanel(PANEL_DIALOG, false);
    }

    private void waitForPanel(final String panelType, final boolean isOpen) throws InterruptedException {
        By locator = By.cssSelector(panelType);
        waitFor(3);
        if (isOpen) {
            List<WebElement> panels = findDomElements(locator);
            assertNotNull(String.format("Panel %s is not open", panelType), panels);
        } else {
            assertFalse("Panel " + panelType + " is not open", isElementPresent(locator));
        }
    }

    private void waitForNumberOfPanels(String panelType, int numPanels) throws InterruptedException {
        waitFor(3);
        By locator = By.cssSelector(panelType);
        if (numPanels != 0) {
            List<WebElement> elements = findDomElements(locator);
            assertEquals("Number of panels open is incorrect", numPanels, elements.size());
        } else {
            assertFalse("No panels should be opened", isElementPresent(locator));
        }
    }
}