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

Java tutorial

Introduction

Here is the source code for org.auraframework.integration.test.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.integration.test.components.ui.modalOverlay;

import org.auraframework.integration.test.util.WebDriverTestCase;
import org.auraframework.integration.test.util.WebDriverTestCase.ExcludeBrowsers;
import org.auraframework.test.util.WebDriverUtil.BrowserType;
import org.junit.Ignore;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;

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

@ExcludeBrowsers({ BrowserType.ANDROID_PHONE, BrowserType.ANDROID_TABLET, BrowserType.IPHONE, BrowserType.IPAD,
        BrowserType.IE7, BrowserType.IE8 })
@Ignore("W-2929107")
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 PARAM_TRAP_FOCUS = "&testTrapFocus=";
    private final String PARAM_CLOSE_ON_LOCATION_CHANGE = "&testCloseOnLocationChange";
    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 INPUT_CLOSE_ON_LOCATION_CHANGE = ".inputCloseOnLocationChange";

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

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

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

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

    /**
     * [Accessibility] panel dialog closing on Esc key. Bug: W-2643030
     */
    @Test
    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();
        }

        if (autoFocus) {
            waitTillFocusOnTopElement();
        } else {
            waitTillFocusOnParticularElement(CLOSE_BTN, "Focus should be on closeBtn");
        }

        WebElement activeElement = (WebElement) getAuraUITestingUtil().getEval(ACTIVE_ELEMENT);
        activeElement.sendKeys(Keys.ESCAPE);
        if (isPanel) {
            waitForPanelDialogClose();
        } else {
            waitForModalClose();
        }
    }

    /**
     * Wait till the focus is on the top input element for panel/modal.
     */
    private void waitTillFocusOnTopElement() {
        getAuraUITestingUtil().waitUntil(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                WebElement activeElement = (WebElement) getAuraUITestingUtil().getEval(ACTIVE_ELEMENT);
                String activeElementValue = activeElement.getAttribute("value");
                return activeElementValue.equals("modal");
            }
        }, "After opening panel/modal, focus is not on first input");
    }

    /**
     * Wait till focus is on the correct element
     *
     * @param elementClassName: Element on which you expect the focus to be on
     * @param failureMessage
     */
    private void waitTillFocusOnParticularElement(String elementClassName, String failureMessage) {
        getAuraUITestingUtil().waitUntil(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                WebElement activeElement = (WebElement) getAuraUITestingUtil().getEval(ACTIVE_ELEMENT);
                String activeElementClassName = activeElement.getAttribute("class");
                return activeElementClassName.contains(elementClassName);
            }
        }, failureMessage);
    }

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

        openPanel();
        waitForPanelDialogOpen();

        waitTillFocusOnTopElement();

        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 = getAuraUITestingUtil().getValueFromCmpExpression(panelGlobalId,
                "v.closeActionCalled");
        String expectedText = String.format("CloseActionCustomMethodCalled when %s", actionType);

        getAuraUITestingUtil().waitUntil(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                String attrValueText = (String) getAuraUITestingUtil().getEval(attrValueExp);
                return attrValueText.contains(expectedText);
            }
        }, "Custom close on Action method was not called");
    }

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

    /**
     * Test modal does have scrollbar when content is not so long Test case: W-2615146
     * <p>
     * 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 })
    @Test
    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 = getAuraUITestingUtil().hasScrollBar(bodyClassName);
        assertEquals(errorMessage, hasScrollbar, hasScroll);
    }

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

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

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

    @Test
    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");
        }

        verifyModalPanelIsActive(String.format("First %s should have class active", errorMessage), locator, true,
                0);
        openPanel(2);
        waitForNumberOfPanels(locator, 2);

        verifyModalPanelIsActive(
                String.format("First %s should not have class active after opening second modal", errorMessage),
                locator, false, 0);
        verifyModalPanelIsActive(String.format("Second %s should have class active", errorMessage), locator, true,
                1);

        waitTillFocusOnTopElement();

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

        verifyModalPanelIsActive(String.format("First %s should have class active after press ESC on 2nd %s",
                errorMessage, errorMessage), locator, true, 0);

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

    private void verifyModalPanelIsActive(String failureMessage, String locator, boolean isActive,
            int modalPanelNumber) {
        WebElement element = findDomElements(By.cssSelector(locator)).get(modalPanelNumber);
        getAuraUITestingUtil().waitUntil(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                return element.getAttribute("class").contains("active") == isActive;
            }
        }, failureMessage);
    }

    /**
     * [Accessibility] panel dialog should not close when closeOnClickOut is not set to true
     */
    @Test
    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
     */
    @Test
    public void testPanelDialogWithCloseOnClickOutSet() throws Exception {
        open(APP + "?" + PARAM_PANEL_TYPE + "panel");

        WebElement closeOutChexbox = findDomElement(By.cssSelector(CLOSE_ON_CLICKOUT));
        closeOutChexbox.click();

        openPanel();
        waitForPanelDialogOpen();
        waitTillFocusOnTopElement();

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

    /**
     * Verify custom close action Bug: W-2619406
     */
    @Test
    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();
        waitTillFocusOnTopElement();

        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
     */
    @Test
    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
     */
    @Test
    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
     */
    @Test
    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
     */
    @Test
    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.
     */
    @Test
    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();

        waitTillFocusOnParticularElement(CLOSE_BTN, "Focus should be on closeBtn");

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

        // check focus
        waitTillFocusOnParticularElement("appInput2", "Active element is not app input");
    }

    /**
     * Test tabbing goes through footer
     */
    @Test
    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
        waitTillFocusOnParticularElement("defaultCustomPanelFooterBtn", "Active element is not button in footer");
    }

    /**
     * Test panel when trapFocus is false
     */
    @Test
    public void testPanelTabingWithTrapFocusFalse() throws Exception {
        String url = APP + "?" + PARAM_TRAP_FOCUS + "false";

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

        // check focus outside of panel
        getAuraUITestingUtil().waitUntil(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                WebElement activeElement = (WebElement) getAuraUITestingUtil().getEval(ACTIVE_ELEMENT);
                String tag = activeElement.getTagName();
                return "body".equals(tag);
            }
        }, "Focus should be on element outside of panel.");
    }

    /**
     * Test back button on browser closes panel.
     */
    @Test
    public void testBrowserBackButton() throws Exception {
        String url = APP + "?" + PARAM_CLOSE_ON_LOCATION_CHANGE + "true";
        open(url);

        openPanel();
        waitForModalOpen();

        WebElement closeOnLocationChangeCheckbox = findDomElements(By.cssSelector(INPUT_CLOSE_ON_LOCATION_CHANGE))
                .get(1);
        closeOnLocationChangeCheckbox.click();
        openPanel(2);
        waitForNumberOfPanels(PANEL_MODAL, 2);

        getDriver().navigate().back();
        waitForModalClose();
    }

    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) getAuraUITestingUtil().getEval(ACTIVE_ELEMENT);
        // assertEquals("Focus should be on first element", panelType, auraUITestingUtil.getEval(ACTIVE_ELEMENT_TEXT));
        int numElements = 27;
        // cycle through input elements on panel
        for (int i = 1; i < numElements; i++) {
            WebElement prevActiveElement = activeElement;
            activeElement.sendKeys(Keys.TAB);
            activeElement = (WebElement) getAuraUITestingUtil().getEval(ACTIVE_ELEMENT);
            getAuraUITestingUtil().waitUntil(new ExpectedCondition<Boolean>() {
                @Override
                public Boolean apply(WebDriver d) {
                    WebElement activeElement = (WebElement) getAuraUITestingUtil().getEval(ACTIVE_ELEMENT);
                    return activeElement != prevActiveElement;
                }
            }, String.format("Tab event was not fired for element with className: %s",
                    prevActiveElement.getAttribute("class")));
        }

        // 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);
        if (isOpen) {
            getAuraUITestingUtil().waitUntil(new ExpectedCondition<Boolean>() {
                @Override
                public Boolean apply(WebDriver d) {
                    List<WebElement> panels = findDomElements(locator);
                    return panels != null;
                }
            }, String.format("Panel %s is not open", panelType));
        } else {
            String failureMessage = String.format("Panel Type: %s is not open", panelType);
            isPanelPresent(failureMessage, false, locator);
        }
    }

    private void waitForNumberOfPanels(String panelType, int numPanels) throws InterruptedException {
        By locator = By.cssSelector(panelType);
        if (numPanels != 0) {
            getAuraUITestingUtil().waitUntil(new ExpectedCondition<Boolean>() {
                @Override
                public Boolean apply(WebDriver d) {
                    List<WebElement> elements = findDomElements(locator);
                    return elements.size() == numPanels;
                }
            }, String.format("Number of panels open is incorrect, it should be: %s", numPanels));
        } else {
            String failureMessage = "No panels should be opened";
            isPanelPresent(failureMessage, false, locator);
        }
    }

    private void isPanelPresent(String failureMessage, boolean isElemPresent, By locator) {
        getAuraUITestingUtil().waitUntil(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                return isElementPresent(locator) == isElemPresent;
            }
        }, failureMessage);
    }
}