001/*
002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Sun Seng David TAN
016 *     Florent Guillaume
017 *     Antoine Taillefer
018 */
019package org.nuxeo.functionaltests.pages;
020
021import static org.junit.Assert.assertNotNull;
022
023import java.util.List;
024
025import org.nuxeo.functionaltests.AbstractTest;
026import org.nuxeo.functionaltests.Assert;
027import org.nuxeo.functionaltests.Locator;
028import org.nuxeo.functionaltests.fragment.WebFragment;
029import org.openqa.selenium.By;
030import org.openqa.selenium.NoSuchElementException;
031import org.openqa.selenium.NotFoundException;
032import org.openqa.selenium.WebDriver;
033import org.openqa.selenium.WebElement;
034import org.openqa.selenium.support.FindBy;
035import org.openqa.selenium.support.ui.ExpectedConditions;
036import org.openqa.selenium.support.ui.Select;
037import org.openqa.selenium.support.ui.WebDriverWait;
038
039/**
040 * Base functions for all pages.
041 */
042public abstract class AbstractPage {
043
044    @FindBy(xpath = "//div[@id='nxw_userMenuActions_panel']/ul/li/span")
045    public WebElement userServicesForm;
046
047    protected WebDriver driver;
048
049    public AbstractPage(WebDriver driver) {
050        this.driver = driver;
051    }
052
053    /**
054     * Returns true if corresponding element is found in the test page.
055     *
056     * @since 5.7
057     */
058    public boolean hasElement(By by) {
059        return Assert.hasElement(by);
060    }
061
062    public <T> T get(String url, Class<T> pageClassToProxy) {
063        return AbstractTest.get(url, pageClassToProxy);
064    }
065
066    public <T> T asPage(Class<T> pageClassToProxy) {
067        return AbstractTest.asPage(pageClassToProxy);
068    }
069
070    public <T extends WebFragment> T getWebFragment(By by, Class<T> webFragmentClass) {
071        return AbstractTest.getWebFragment(by, webFragmentClass);
072    }
073
074    public <T extends WebFragment> T getWebFragment(WebElement element, Class<T> webFragmentClass) {
075        return AbstractTest.getWebFragment(element, webFragmentClass);
076    }
077
078    /**
079     * Gets the info feedback message.
080     *
081     * @return the message if any or an empty string.
082     * @deprecated since 5.8
083     */
084    @Deprecated
085    public String getFeedbackMessage() {
086        String ret;
087        try {
088            ret = findElementWithTimeout(By.xpath("//li[@class=\"errorFeedback\"]")).getText();
089        } catch (NoSuchElementException e) {
090            ret = "";
091        }
092        return ret.trim();
093    }
094
095    /**
096     * Returns the error feedback message.
097     * <p>
098     * If there are more than one error message, always return the second one (not interested by 'Please correct errors'
099     * message).
100     *
101     * @since 5.8
102     */
103    public String getErrorFeedbackMessage() {
104        String ret = "";
105        try {
106            List<WebElement> elements = findElementsWithTimeout(By.xpath("//div[contains(@class, 'errorFeedback')]/div[@class='ambiance-title']"));
107            if (elements.size() == 1) {
108                ret = elements.get(0).getText();
109            } else if (elements.size() > 1) {
110                ret = elements.get(1).getText();
111            }
112        } catch (NoSuchElementException e) {
113            ret = "";
114        }
115        return ret.trim();
116    }
117
118    /**
119     * Gets the top bar navigation sub page.
120     */
121    public HeaderLinksSubPage getHeaderLinks() {
122        assertNotNull(userServicesForm);
123        return asPage(HeaderLinksSubPage.class);
124    }
125
126    /**
127     * Returns the fancy box content web element
128     *
129     * @since 5.7
130     */
131    public WebElement getFancyBoxContent() {
132        // make sure the fancybox content is loaded
133        WebElement fancyBox = findElementWithTimeout(By.id("fancybox-content"));
134        WebDriverWait wait = new WebDriverWait(driver, AbstractTest.LOAD_TIMEOUT_SECONDS);
135        wait.until(ExpectedConditions.visibilityOf(fancyBox));
136        return fancyBox;
137    }
138
139    /**
140     * Finds the first {@link WebElement} using the given method, with a timeout.
141     *
142     * @param by the locating mechanism
143     * @param timeout the timeout in milliseconds
144     * @return the first matching element on the current page, if found
145     * @throws NoSuchElementException when not found
146     */
147    public WebElement findElementWithTimeout(By by, int timeout) throws NoSuchElementException {
148        return Locator.findElementWithTimeout(by, timeout);
149    }
150
151    /**
152     * Finds the first {@link WebElement} using the given method, with a timeout.
153     *
154     * @param by the locating mechanism
155     * @param timeout the timeout in milliseconds
156     * @param parentElement find from the element
157     * @return the first matching element on the current page, if found
158     * @throws NoSuchElementException when not found
159     */
160    public WebElement findElementWithTimeout(By by, int timeout, WebElement parentElement)
161            throws NoSuchElementException {
162        return Locator.findElementWithTimeout(by, timeout, parentElement);
163    }
164
165    /**
166     * Finds the first {@link WebElement} using the given method, with a timeout.
167     *
168     * @param by the locating mechanism
169     * @param timeout the timeout in milliseconds
170     * @return the first matching element on the current page, if found
171     * @throws NoSuchElementException when not found
172     */
173    public static WebElement findElementWithTimeout(By by) throws NoSuchElementException {
174        return Locator.findElementWithTimeout(by);
175    }
176
177    /**
178     * Finds webelement list using the given method, with a timeout
179     */
180    public static List<WebElement> findElementsWithTimeout(By by) throws NoSuchElementException {
181        return Locator.findElementsWithTimeout(by);
182    }
183
184    /**
185     * Finds the first {@link WebElement} using the given method, with a timeout.
186     *
187     * @param by the locating mechanism
188     * @param parentElement find from the element
189     * @return the first matching element on the current page, if found
190     * @throws NoSuchElementException when not found
191     */
192    public static WebElement findElementWithTimeout(By by, WebElement parentElement) throws NoSuchElementException {
193        return Locator.findElementWithTimeout(by, parentElement);
194    }
195
196    /**
197     * Waits until an element is enabled, with a timeout.
198     *
199     * @param element the element
200     */
201    public static void waitUntilEnabled(WebElement element) throws NotFoundException {
202        Locator.waitUntilEnabled(element);
203    }
204
205    /**
206     * Finds the first {@link WebElement} using the given method, with a {@code findElementTimeout}. Then waits until
207     * the element is enabled, with a {@code waitUntilEnabledTimeout}.
208     *
209     * @param by the locating mechanism
210     * @param findElementTimeout the find element timeout in milliseconds
211     * @param waitUntilEnabledTimeout the wait until enabled timeout in milliseconds
212     * @return the first matching element on the current page, if found
213     * @throws NotFoundException if the element is not found or not enabled
214     */
215    public static WebElement findElementAndWaitUntilEnabled(By by, int findElementTimeout, int waitUntilEnabledTimeout)
216            throws NotFoundException {
217        return Locator.findElementAndWaitUntilEnabled(by, findElementTimeout, waitUntilEnabledTimeout);
218    }
219
220    /**
221     * Finds the first {@link WebElement} using the given method, with the default timeout. Then waits until the element
222     * is enabled, with the default timeout.
223     *
224     * @param by the locating mechanism
225     * @return the first matching element on the current page, if found
226     * @throws NotFoundException if the element is not found or not enabled
227     */
228    public static WebElement findElementAndWaitUntilEnabled(By by) throws NotFoundException {
229        return Locator.findElementAndWaitUntilEnabled(by);
230    }
231
232    /**
233     * Finds the first {@link WebElement} using the given method, with a {@code findElementTimeout}. Then waits until
234     * the element is enabled, with a {@code waitUntilEnabledTimeout}. Then clicks on the element.
235     *
236     * @param by the locating mechanism
237     * @param findElementTimeout the find element timeout in milliseconds
238     * @param waitUntilEnabledTimeout the wait until enabled timeout in milliseconds
239     * @throws NotFoundException if the element is not found or not enabled
240     */
241    public static void findElementWaitUntilEnabledAndClick(By by, int findElementTimeout, int waitUntilEnabledTimeout)
242            throws NotFoundException {
243        Locator.waitUntilElementEnabledAndClick(by, findElementTimeout, waitUntilEnabledTimeout);
244    }
245
246    /**
247     * Finds the first {@link WebElement} using the given method, with the default timeout. Then waits until the element
248     * is enabled, with the default timeout. Then clicks on the element.
249     *
250     * @param by the locating mechanism
251     * @throws NotFoundException if the element is not found or not enabled
252     */
253    public static void findElementWaitUntilEnabledAndClick(By by) throws NotFoundException {
254        Locator.findElementWaitUntilEnabledAndClick(by);
255    }
256
257    /**
258     * Waits until the URL is different from the one given in parameter, with a timeout.
259     *
260     * @param url the URL to compare to
261     */
262    public void waitUntilURLDifferentFrom(String url) {
263        Locator.waitUntilURLDifferentFrom(url);
264    }
265
266    /**
267     * Selects item in drop down menu.
268     *
269     * @since 5.7
270     */
271    public void selectItemInDropDownMenu(WebElement selector, String optionLabel) {
272        Select select = new Select(selector);
273        select.selectByVisibleText(optionLabel);
274    }
275
276    /**
277     * Switch to given frame id.
278     *
279     * @since 5.7.3
280     */
281    public WebDriver switchToFrame(String id) {
282        driver.switchTo().defaultContent();
283        // you are now outside both frames
284        return driver.switchTo().frame(id);
285    }
286}