001/* 002 * (C) Copyright 2016 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Sun Seng David TAN 018 * Florent Guillaume 019 * Antoine Taillefer 020 * Yannis JULIENNE 021 */ 022package org.nuxeo.functionaltests.pages; 023 024import static org.junit.Assert.assertNotNull; 025 026import java.util.List; 027import java.util.concurrent.TimeUnit; 028 029import org.nuxeo.functionaltests.AbstractTest; 030import org.nuxeo.functionaltests.AjaxRequestManager; 031import org.nuxeo.functionaltests.Assert; 032import org.nuxeo.functionaltests.Locator; 033import org.nuxeo.functionaltests.fragment.WebFragment; 034import org.openqa.selenium.By; 035import org.openqa.selenium.NoSuchElementException; 036import org.openqa.selenium.NotFoundException; 037import org.openqa.selenium.WebDriver; 038import org.openqa.selenium.WebElement; 039import org.openqa.selenium.support.FindBy; 040import org.openqa.selenium.support.ui.ExpectedConditions; 041import org.openqa.selenium.support.ui.FluentWait; 042import org.openqa.selenium.support.ui.Select; 043 044/** 045 * Base functions for all pages. 046 */ 047public abstract class AbstractPage { 048 049 @FindBy(xpath = "//div[@id='nxw_userMenuActions_panel']/ul/li/span") 050 public WebElement userServicesForm; 051 052 protected WebDriver driver; 053 054 public AbstractPage(WebDriver driver) { 055 this.driver = driver; 056 } 057 058 /** 059 * Returns true if corresponding element is found in the test page. 060 * 061 * @since 5.7 062 */ 063 public boolean hasElement(By by) { 064 return Assert.hasElement(by); 065 } 066 067 public <T> T get(String url, Class<T> pageClassToProxy) { 068 return AbstractTest.get(url, pageClassToProxy); 069 } 070 071 public <T> T asPage(Class<T> pageClassToProxy) { 072 return AbstractTest.asPage(pageClassToProxy); 073 } 074 075 public <T extends WebFragment> T getWebFragment(By by, Class<T> webFragmentClass) { 076 return AbstractTest.getWebFragment(by, webFragmentClass); 077 } 078 079 public <T extends WebFragment> T getWebFragment(WebElement element, Class<T> webFragmentClass) { 080 return AbstractTest.getWebFragment(element, webFragmentClass); 081 } 082 083 /** 084 * Returns the error feedback message. 085 * <p> 086 * If there are more than one error message, always return the last one (not interested by 'Please correct errors' 087 * message). 088 * 089 * @since 5.8 090 */ 091 public String getErrorFeedbackMessage() { 092 return getFeedbackMessage("errorFeedback"); 093 } 094 095 /** 096 * Returns the info feedback message. 097 * <p> 098 * If there are more than one info message, always return the last one. 099 * 100 * @since 8.3 101 */ 102 public String getInfoFeedbackMessage() { 103 return getFeedbackMessage("infoFeedback"); 104 } 105 106 protected String getFeedbackMessage(String styleClass) { 107 String ret = ""; 108 try { 109 List<WebElement> elements = findElementsWithTimeout( 110 By.xpath("//div[contains(@class, '" + styleClass + "')]/div[@class='ambiance-title']")); 111 if (elements.size() == 1) { 112 ret = elements.get(0).getText(); 113 } else if (elements.size() > 1) { 114 ret = elements.get(elements.size() - 1).getText(); 115 } 116 } catch (NoSuchElementException e) { 117 ret = ""; 118 } 119 return ret.trim(); 120 } 121 122 /** 123 * Gets the top bar navigation sub page. 124 */ 125 public HeaderLinksSubPage getHeaderLinks() { 126 assertNotNull(userServicesForm); 127 return asPage(HeaderLinksSubPage.class); 128 } 129 130 /** 131 * Returns the fancy box content web element. 132 * 133 * @since 5.7 134 */ 135 public static WebElement getFancyBoxContent() { 136 // make sure the fancybox content is loaded 137 WebElement fancyBox = findElementWithTimeout(By.id("fancybox-content")); 138 FluentWait<WebDriver> wait = Locator.getFluentWait(); 139 wait.until(ExpectedConditions.visibilityOf(fancyBox)); 140 return fancyBox; 141 } 142 143 /** 144 * Closes current fancy box. 145 * 146 * @since 8.3 147 */ 148 public static void closeFancyBox() { 149 AjaxRequestManager arm = new AjaxRequestManager(AbstractTest.driver); 150 arm.begin(); 151 findElementWaitUntilEnabledAndClick(By.id("fancybox-close")); 152 arm.end(); 153 waitForFancyBoxClosed(); 154 } 155 156 /** 157 * Waits for the fancybox to be fully closed. 158 * 159 * @since 8.3 160 */ 161 public static void waitForFancyBoxClosed() { 162 // make sure the fancybox content is not loaded anymore 163 FluentWait<WebDriver> wait = Locator.getFluentWait(); 164 wait.withTimeout(AbstractTest.AJAX_TIMEOUT_SECONDS, TimeUnit.SECONDS); 165 wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("fancybox-overlay"))); 166 } 167 168 /** 169 * Finds the first {@link WebElement} using the given method, with a timeout. 170 * 171 * @param by the locating mechanism 172 * @param timeout the timeout in milliseconds 173 * @return the first matching element on the current page, if found 174 * @throws NoSuchElementException when not found 175 */ 176 public WebElement findElementWithTimeout(By by, int timeout) throws NoSuchElementException { 177 return Locator.findElementWithTimeout(by, timeout); 178 } 179 180 /** 181 * Finds the first {@link WebElement} using the given method, with a timeout. 182 * 183 * @param by the locating mechanism 184 * @param timeout the timeout in milliseconds 185 * @param parentElement find from the element 186 * @return the first matching element on the current page, if found 187 * @throws NoSuchElementException when not found 188 */ 189 public WebElement findElementWithTimeout(By by, int timeout, WebElement parentElement) 190 throws NoSuchElementException { 191 return Locator.findElementWithTimeout(by, timeout, parentElement); 192 } 193 194 /** 195 * Finds the first {@link WebElement} using the given method, with a timeout. 196 * 197 * @param by the locating mechanism 198 * @return the first matching element on the current page, if found 199 * @throws NoSuchElementException when not found 200 */ 201 public static WebElement findElementWithTimeout(By by) throws NoSuchElementException { 202 return Locator.findElementWithTimeout(by); 203 } 204 205 /** 206 * Finds webelement list using the given method, with a timeout 207 */ 208 public static List<WebElement> findElementsWithTimeout(By by) throws NoSuchElementException { 209 return Locator.findElementsWithTimeout(by); 210 } 211 212 /** 213 * Finds the first {@link WebElement} using the given method, with a timeout. 214 * 215 * @param by the locating mechanism 216 * @param parentElement find from the element 217 * @return the first matching element on the current page, if found 218 * @throws NoSuchElementException when not found 219 */ 220 public static WebElement findElementWithTimeout(By by, WebElement parentElement) throws NoSuchElementException { 221 return Locator.findElementWithTimeout(by, parentElement); 222 } 223 224 /** 225 * Waits until an element is enabled, with a default timeout. 226 * 227 * @param element the element 228 */ 229 public static void waitUntilEnabled(WebElement element) throws NotFoundException { 230 Locator.waitUntilEnabled(element); 231 } 232 233 /** 234 * Waits until an element is enabled, with a timeout. 235 * 236 * @param element the element 237 * @param waitUntilEnabledTimeout the timeout in milliseconds 238 * @since 8.3 239 */ 240 public static void waitUntilEnabled(WebElement element, int waitUntilEnabledTimeout) throws NotFoundException { 241 Locator.waitUntilEnabled(element, waitUntilEnabledTimeout); 242 } 243 244 /** 245 * Waits until an element is enabled, with a default timeout. Then clicks on the element. 246 * 247 * @param element the element 248 * @since 8.3 249 */ 250 public static void waitUntilEnabledAndClick(WebElement element) throws NotFoundException { 251 Locator.waitUntilEnabledAndClick(element); 252 } 253 254 /** 255 * Waits until an element is enabled, with a timeout. Then clicks on the element. 256 * 257 * @param element the element 258 * @param waitUntilEnabledTimeout the timeout in milliseconds 259 * @since 8.3 260 */ 261 262 public static void waitUntilEnabledAndClick(WebElement element, int waitUntilEnabledTimeout) 263 throws NotFoundException { 264 Locator.waitUntilEnabledAndClick(element, waitUntilEnabledTimeout); 265 } 266 267 /** 268 * Finds the first {@link WebElement} using the given method, with a {@code findElementTimeout}. Then waits until 269 * the element is enabled, with a {@code waitUntilEnabledTimeout}. 270 * 271 * @param by the locating mechanism 272 * @param findElementTimeout the find element timeout in milliseconds 273 * @param waitUntilEnabledTimeout the wait until enabled timeout in milliseconds 274 * @return the first matching element on the current page, if found 275 * @throws NotFoundException if the element is not found or not enabled 276 */ 277 public static WebElement findElementAndWaitUntilEnabled(By by, int findElementTimeout, int waitUntilEnabledTimeout) 278 throws NotFoundException { 279 return Locator.findElementAndWaitUntilEnabled(by, findElementTimeout, waitUntilEnabledTimeout); 280 } 281 282 /** 283 * Finds the first {@link WebElement} using the given method, with the default timeout. Then waits until the element 284 * is enabled, with the default timeout. 285 * 286 * @param by the locating mechanism 287 * @return the first matching element on the current page, if found 288 * @throws NotFoundException if the element is not found or not enabled 289 */ 290 public static WebElement findElementAndWaitUntilEnabled(By by) throws NotFoundException { 291 return Locator.findElementAndWaitUntilEnabled(by); 292 } 293 294 /** 295 * Finds the first {@link WebElement} using the given method, with a {@code findElementTimeout}. Then waits until 296 * the element is enabled, with a {@code waitUntilEnabledTimeout}. Then clicks on the element. 297 * 298 * @param by the locating mechanism 299 * @param findElementTimeout the find element timeout in milliseconds 300 * @param waitUntilEnabledTimeout the wait until enabled timeout in milliseconds 301 * @throws NotFoundException if the element is not found or not enabled 302 * @deprecated since 8.3, use {@link Locator#findElementWaitUntilEnabledAndClick(WebElement, By, int, int)} 303 */ 304 @Deprecated 305 public static void findElementWaitUntilEnabledAndClick(By by, int findElementTimeout, int waitUntilEnabledTimeout) 306 throws NotFoundException { 307 Locator.findElementWaitUntilEnabledAndClick(by, findElementTimeout, waitUntilEnabledTimeout); 308 } 309 310 /** 311 * Finds the first {@link WebElement} using the given method, with the default timeout. Then waits until the element 312 * is enabled, with the default timeout. Then clicks on the element. 313 * 314 * @param by the locating mechanism 315 * @throws NotFoundException if the element is not found or not enabled 316 */ 317 public static void findElementWaitUntilEnabledAndClick(By by) throws NotFoundException { 318 Locator.findElementWaitUntilEnabledAndClick(by); 319 } 320 321 /** 322 * Finds the first {@link WebElement} using the given method, with the default timeout, inside an optional 323 * {@code parentElement}. Then waits until the element is enabled, with the default timeout. Then clicks on the 324 * element. 325 * 326 * @param parentElement the parent element (can be null) 327 * @param by the locating mechanism 328 * @throws NotFoundException if the element is not found or not enabled 329 * @since 9.1 330 */ 331 public static void findElementWaitUntilEnabledAndClick(WebElement parentElement, By by) throws NotFoundException { 332 Locator.findElementWaitUntilEnabledAndClick(parentElement, by); 333 } 334 335 /** 336 * Waits until the URL is different from the one given in parameter, with a timeout. 337 * 338 * @param url the URL to compare to 339 */ 340 public void waitUntilURLDifferentFrom(String url) { 341 Locator.waitUntilURLDifferentFrom(url); 342 } 343 344 /** 345 * Selects item in drop down menu. 346 * 347 * @since 5.7 348 */ 349 public void selectItemInDropDownMenu(WebElement selector, String optionLabel) { 350 Select select = new Select(selector); 351 select.selectByVisibleText(optionLabel); 352 } 353 354 /** 355 * Switch to given frame id. 356 * 357 * @since 5.7.3 358 */ 359 public WebDriver switchToFrame(String id) { 360 driver.switchTo().defaultContent(); 361 // you are now outside both frames 362 return driver.switchTo().frame(id); 363 } 364 365 /** 366 * Helper method to adapt tests behaviour when ajaxifying tabs. 367 * 368 * @since 7.10 369 */ 370 public boolean useAjaxTabs() { 371 return true; 372 } 373 374 protected void clickOnTabIfNotSelected(String tabPanelId, WebElement tabElement) { 375 clickOnTabIfNotSelected(tabPanelId, tabElement, useAjaxTabs()); 376 } 377 378 protected void clickOnTabIfNotSelected(String tabPanelId, WebElement tabElement, boolean useAjax) { 379 WebElement selectedTab = findElementWithTimeout( 380 By.xpath("//div[@id='" + tabPanelId + "']//li[@class='selected']//a/span")); 381 if (!selectedTab.equals(tabElement)) { 382 if (useAjax) { 383 AjaxRequestManager arm = new AjaxRequestManager(driver); 384 arm.begin(); 385 waitUntilEnabledAndClick(tabElement); 386 arm.end(); 387 } else { 388 waitUntilEnabledAndClick(tabElement); 389 } 390 } 391 } 392 393 protected void clickOnTabIfNotSelected(String tabPanelId, String tabElementId) { 394 WebElement tabElement = findElementWithTimeout( 395 By.xpath("//div[@id='" + tabPanelId + "']//a[contains(@id,'" + tabElementId + "')]/span")); 396 clickOnTabIfNotSelected(tabPanelId, tabElement); 397 } 398 399}