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 java.util.List; 025import java.util.concurrent.TimeUnit; 026 027import org.nuxeo.functionaltests.AbstractTest; 028import org.nuxeo.functionaltests.AjaxRequestManager; 029import org.nuxeo.functionaltests.Assert; 030import org.nuxeo.functionaltests.Locator; 031import org.nuxeo.functionaltests.fragment.WebFragment; 032import org.openqa.selenium.By; 033import org.openqa.selenium.NoSuchElementException; 034import org.openqa.selenium.NotFoundException; 035import org.openqa.selenium.WebDriver; 036import org.openqa.selenium.WebElement; 037import org.openqa.selenium.support.FindBy; 038import org.openqa.selenium.support.ui.ExpectedConditions; 039import org.openqa.selenium.support.ui.FluentWait; 040import org.openqa.selenium.support.ui.Select; 041 042import static org.junit.Assert.assertNotNull; 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 * Gets the info feedback message. 085 * 086 * @return the message if any or an empty string. 087 * @deprecated since 5.8 088 */ 089 @Deprecated 090 public String getFeedbackMessage() { 091 String ret; 092 try { 093 ret = findElementWithTimeout(By.xpath("//li[@class=\"errorFeedback\"]")).getText(); 094 } catch (NoSuchElementException e) { 095 ret = ""; 096 } 097 return ret.trim(); 098 } 099 100 /** 101 * Returns the error feedback message. 102 * <p> 103 * If there are more than one error message, always return the last one (not interested by 'Please correct errors' 104 * message). 105 * 106 * @since 5.8 107 */ 108 public String getErrorFeedbackMessage() { 109 return getFeedbackMessage("errorFeedback"); 110 } 111 112 /** 113 * Returns the info feedback message. 114 * <p> 115 * If there are more than one info message, always return the last one. 116 * 117 * @since 8.3 118 */ 119 public String getInfoFeedbackMessage() { 120 return getFeedbackMessage("infoFeedback"); 121 } 122 123 protected String getFeedbackMessage(String styleClass) { 124 String ret = ""; 125 try { 126 List<WebElement> elements = findElementsWithTimeout( 127 By.xpath("//div[contains(@class, '" + styleClass + "')]/div[@class='ambiance-title']")); 128 if (elements.size() == 1) { 129 ret = elements.get(0).getText(); 130 } else if (elements.size() > 1) { 131 ret = elements.get(elements.size() - 1).getText(); 132 } 133 } catch (NoSuchElementException e) { 134 ret = ""; 135 } 136 return ret.trim(); 137 } 138 139 /** 140 * Gets the top bar navigation sub page. 141 */ 142 public HeaderLinksSubPage getHeaderLinks() { 143 assertNotNull(userServicesForm); 144 return asPage(HeaderLinksSubPage.class); 145 } 146 147 /** 148 * Returns the fancy box content web element. 149 * 150 * @since 5.7 151 */ 152 public static WebElement getFancyBoxContent() { 153 // make sure the fancybox content is loaded 154 WebElement fancyBox = findElementWithTimeout(By.id("fancybox-content")); 155 FluentWait<WebDriver> wait = Locator.getFluentWait(); 156 wait.until(ExpectedConditions.visibilityOf(fancyBox)); 157 return fancyBox; 158 } 159 160 /** 161 * Closes current fancy box. 162 * 163 * @since 8.3 164 */ 165 public static void closeFancyBox() { 166 AjaxRequestManager arm = new AjaxRequestManager(AbstractTest.driver); 167 arm.begin(); 168 findElementWaitUntilEnabledAndClick(By.id("fancybox-close")); 169 arm.end(); 170 waitForFancyBoxClosed(); 171 } 172 173 /** 174 * Waits for the fancybox to be fully closed. 175 * 176 * @since 8.3 177 */ 178 public static void waitForFancyBoxClosed() { 179 // make sure the fancybox content is not loaded anymore 180 FluentWait<WebDriver> wait = Locator.getFluentWait(); 181 wait.withTimeout(AbstractTest.AJAX_TIMEOUT_SECONDS, TimeUnit.SECONDS); 182 wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("fancybox-overlay"))); 183 } 184 185 /** 186 * Finds the first {@link WebElement} using the given method, with a timeout. 187 * 188 * @param by the locating mechanism 189 * @param timeout the timeout in milliseconds 190 * @return the first matching element on the current page, if found 191 * @throws NoSuchElementException when not found 192 */ 193 public WebElement findElementWithTimeout(By by, int timeout) throws NoSuchElementException { 194 return Locator.findElementWithTimeout(by, timeout); 195 } 196 197 /** 198 * Finds the first {@link WebElement} using the given method, with a timeout. 199 * 200 * @param by the locating mechanism 201 * @param timeout the timeout in milliseconds 202 * @param parentElement find from the element 203 * @return the first matching element on the current page, if found 204 * @throws NoSuchElementException when not found 205 */ 206 public WebElement findElementWithTimeout(By by, int timeout, WebElement parentElement) 207 throws NoSuchElementException { 208 return Locator.findElementWithTimeout(by, timeout, parentElement); 209 } 210 211 /** 212 * Finds the first {@link WebElement} using the given method, with a timeout. 213 * 214 * @param by the locating mechanism 215 * @param timeout the timeout in milliseconds 216 * @return the first matching element on the current page, if found 217 * @throws NoSuchElementException when not found 218 */ 219 public static WebElement findElementWithTimeout(By by) throws NoSuchElementException { 220 return Locator.findElementWithTimeout(by); 221 } 222 223 /** 224 * Finds webelement list using the given method, with a timeout 225 */ 226 public static List<WebElement> findElementsWithTimeout(By by) throws NoSuchElementException { 227 return Locator.findElementsWithTimeout(by); 228 } 229 230 /** 231 * Finds the first {@link WebElement} using the given method, with a timeout. 232 * 233 * @param by the locating mechanism 234 * @param parentElement find from the element 235 * @return the first matching element on the current page, if found 236 * @throws NoSuchElementException when not found 237 */ 238 public static WebElement findElementWithTimeout(By by, WebElement parentElement) throws NoSuchElementException { 239 return Locator.findElementWithTimeout(by, parentElement); 240 } 241 242 /** 243 * Waits until an element is enabled, with a default timeout. 244 * 245 * @param element the element 246 */ 247 public static void waitUntilEnabled(WebElement element) throws NotFoundException { 248 Locator.waitUntilEnabled(element); 249 } 250 251 /** 252 * Waits until an element is enabled, with a timeout. 253 * 254 * @param element the element 255 * @param timeout the timeout in milliseconds 256 * @since 8.3 257 */ 258 public static void waitUntilEnabled(WebElement element, int waitUntilEnabledTimeout) throws NotFoundException { 259 Locator.waitUntilEnabled(element, waitUntilEnabledTimeout); 260 } 261 262 /** 263 * Waits until an element is enabled, with a default timeout. Then clicks on the element. 264 * 265 * @param element the element 266 * @since 8.3 267 */ 268 public static void waitUntilEnabledAndClick(WebElement element) throws NotFoundException { 269 Locator.waitUntilEnabledAndClick(element); 270 } 271 272 /** 273 * Waits until an element is enabled, with a timeout. Then clicks on the element. 274 * 275 * @param element the element 276 * @param timeout the timeout in milliseconds 277 * @since 8.3 278 */ 279 280 public static void waitUntilEnabledAndClick(WebElement element, int waitUntilEnabledTimeout) 281 throws NotFoundException { 282 Locator.waitUntilEnabledAndClick(element, waitUntilEnabledTimeout); 283 } 284 285 /** 286 * Finds the first {@link WebElement} using the given method, with a {@code findElementTimeout}. Then waits until 287 * the element is enabled, with a {@code waitUntilEnabledTimeout}. 288 * 289 * @param by the locating mechanism 290 * @param findElementTimeout the find element timeout in milliseconds 291 * @param waitUntilEnabledTimeout the wait until enabled timeout in milliseconds 292 * @return the first matching element on the current page, if found 293 * @throws NotFoundException if the element is not found or not enabled 294 */ 295 public static WebElement findElementAndWaitUntilEnabled(By by, int findElementTimeout, int waitUntilEnabledTimeout) 296 throws NotFoundException { 297 return Locator.findElementAndWaitUntilEnabled(by, findElementTimeout, waitUntilEnabledTimeout); 298 } 299 300 /** 301 * Finds the first {@link WebElement} using the given method, with the default timeout. Then waits until the element 302 * is enabled, with the default timeout. 303 * 304 * @param by the locating mechanism 305 * @return the first matching element on the current page, if found 306 * @throws NotFoundException if the element is not found or not enabled 307 */ 308 public static WebElement findElementAndWaitUntilEnabled(By by) throws NotFoundException { 309 return Locator.findElementAndWaitUntilEnabled(by); 310 } 311 312 /** 313 * Finds the first {@link WebElement} using the given method, with a {@code findElementTimeout}. Then waits until 314 * the element is enabled, with a {@code waitUntilEnabledTimeout}. Then clicks on the element. 315 * 316 * @param by the locating mechanism 317 * @param findElementTimeout the find element timeout in milliseconds 318 * @param waitUntilEnabledTimeout the wait until enabled timeout in milliseconds 319 * @throws NotFoundException if the element is not found or not enabled 320 * @deprecated since 8.3, use {@link Locator#findElementWaitUntilEnabledAndClick(WebElement, By, int, int)} 321 */ 322 @Deprecated 323 public static void findElementWaitUntilEnabledAndClick(By by, int findElementTimeout, int waitUntilEnabledTimeout) 324 throws NotFoundException { 325 Locator.findElementWaitUntilEnabledAndClick(by, findElementTimeout, waitUntilEnabledTimeout); 326 } 327 328 /** 329 * Finds the first {@link WebElement} using the given method, with the default timeout. Then waits until the element 330 * is enabled, with the default timeout. Then clicks on the element. 331 * 332 * @param by the locating mechanism 333 * @throws NotFoundException if the element is not found or not enabled 334 */ 335 public static void findElementWaitUntilEnabledAndClick(By by) throws NotFoundException { 336 Locator.findElementWaitUntilEnabledAndClick(by); 337 } 338 339 /** 340 * Waits until the URL is different from the one given in parameter, with a timeout. 341 * 342 * @param url the URL to compare to 343 */ 344 public void waitUntilURLDifferentFrom(String url) { 345 Locator.waitUntilURLDifferentFrom(url); 346 } 347 348 /** 349 * Selects item in drop down menu. 350 * 351 * @since 5.7 352 */ 353 public void selectItemInDropDownMenu(WebElement selector, String optionLabel) { 354 Select select = new Select(selector); 355 select.selectByVisibleText(optionLabel); 356 } 357 358 /** 359 * Switch to given frame id. 360 * 361 * @since 5.7.3 362 */ 363 public WebDriver switchToFrame(String id) { 364 driver.switchTo().defaultContent(); 365 // you are now outside both frames 366 return driver.switchTo().frame(id); 367 } 368 369 /** 370 * Helper method to adapt tests behaviour when ajaxifying tabs. 371 * 372 * @since 7.10 373 */ 374 public boolean useAjaxTabs() { 375 return true; 376 } 377 378 protected void clickOnTabIfNotSelected(String tabPanelId, WebElement tabElement) { 379 clickOnTabIfNotSelected(tabPanelId, tabElement, useAjaxTabs()); 380 } 381 382 protected void clickOnTabIfNotSelected(String tabPanelId, WebElement tabElement, boolean useAjax) { 383 WebElement selectedTab = findElementWithTimeout( 384 By.xpath("//div[@id='" + tabPanelId + "']//li[@class='selected']//a/span")); 385 if (!selectedTab.equals(tabElement)) { 386 if (useAjax) { 387 AjaxRequestManager arm = new AjaxRequestManager(driver); 388 arm.begin(); 389 waitUntilEnabledAndClick(tabElement); 390 arm.end(); 391 } else { 392 waitUntilEnabledAndClick(tabElement); 393 } 394 } 395 } 396 397 protected void clickOnTabIfNotSelected(String tabPanelId, String tabElementId) { 398 WebElement tabElement = findElementWithTimeout( 399 By.xpath("//div[@id='" + tabPanelId + "']//a[contains(@id,'" + tabElementId + "')]/span")); 400 clickOnTabIfNotSelected(tabPanelId, tabElement); 401 } 402 403}