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 public static void waitUntilEnabledAndClick(WebElement element, int waitUntilEnabledTimeout) 280 throws NotFoundException { 281 Locator.waitUntilEnabledAndClick(element, waitUntilEnabledTimeout); 282 } 283 284 /** 285 * Finds the first {@link WebElement} using the given method, with a {@code findElementTimeout}. Then waits until 286 * the element is enabled, with a {@code waitUntilEnabledTimeout}. 287 * 288 * @param by the locating mechanism 289 * @param findElementTimeout the find element timeout in milliseconds 290 * @param waitUntilEnabledTimeout the wait until enabled timeout in milliseconds 291 * @return the first matching element on the current page, if found 292 * @throws NotFoundException if the element is not found or not enabled 293 */ 294 public static WebElement findElementAndWaitUntilEnabled(By by, int findElementTimeout, int waitUntilEnabledTimeout) 295 throws NotFoundException { 296 return Locator.findElementAndWaitUntilEnabled(by, findElementTimeout, waitUntilEnabledTimeout); 297 } 298 299 /** 300 * Finds the first {@link WebElement} using the given method, with the default timeout. Then waits until the element 301 * is enabled, with the default timeout. 302 * 303 * @param by the locating mechanism 304 * @return the first matching element on the current page, if found 305 * @throws NotFoundException if the element is not found or not enabled 306 */ 307 public static WebElement findElementAndWaitUntilEnabled(By by) throws NotFoundException { 308 return Locator.findElementAndWaitUntilEnabled(by); 309 } 310 311 /** 312 * Finds the first {@link WebElement} using the given method, with a {@code findElementTimeout}. Then waits until 313 * the element is enabled, with a {@code waitUntilEnabledTimeout}. Then clicks on the element. 314 * 315 * @param by the locating mechanism 316 * @param findElementTimeout the find element timeout in milliseconds 317 * @param waitUntilEnabledTimeout the wait until enabled timeout in milliseconds 318 * @throws NotFoundException if the element is not found or not enabled 319 * @deprecated since 8.3, use {@link Locator#findElementWaitUntilEnabledAndClick(WebElement, By, int, int)} 320 */ 321 @Deprecated 322 public static void findElementWaitUntilEnabledAndClick(By by, int findElementTimeout, int waitUntilEnabledTimeout) 323 throws NotFoundException { 324 Locator.findElementWaitUntilEnabledAndClick(by, findElementTimeout, waitUntilEnabledTimeout); 325 } 326 327 /** 328 * Finds the first {@link WebElement} using the given method, with the default timeout. Then waits until the element 329 * is enabled, with the default timeout. Then clicks on the element. 330 * 331 * @param by the locating mechanism 332 * @throws NotFoundException if the element is not found or not enabled 333 */ 334 public static void findElementWaitUntilEnabledAndClick(By by) throws NotFoundException { 335 Locator.findElementWaitUntilEnabledAndClick(by); 336 } 337 338 /** 339 * Waits until the URL is different from the one given in parameter, with a timeout. 340 * 341 * @param url the URL to compare to 342 */ 343 public void waitUntilURLDifferentFrom(String url) { 344 Locator.waitUntilURLDifferentFrom(url); 345 } 346 347 /** 348 * Selects item in drop down menu. 349 * 350 * @since 5.7 351 */ 352 public void selectItemInDropDownMenu(WebElement selector, String optionLabel) { 353 Select select = new Select(selector); 354 select.selectByVisibleText(optionLabel); 355 } 356 357 /** 358 * Switch to given frame id. 359 * 360 * @since 5.7.3 361 */ 362 public WebDriver switchToFrame(String id) { 363 driver.switchTo().defaultContent(); 364 // you are now outside both frames 365 return driver.switchTo().frame(id); 366 } 367 368 /** 369 * Helper method to adapt tests behaviour when ajaxifying tabs. 370 * 371 * @since 7.10 372 */ 373 public boolean useAjaxTabs() { 374 return true; 375 } 376 377 protected void clickOnTabIfNotSelected(String tabPanelId, WebElement tabElement) { 378 clickOnTabIfNotSelected(tabPanelId, tabElement, useAjaxTabs()); 379 } 380 381 protected void clickOnTabIfNotSelected(String tabPanelId, WebElement tabElement, boolean useAjax) { 382 WebElement selectedTab = findElementWithTimeout( 383 By.xpath("//div[@id='" + tabPanelId + "']//li[@class='selected']//a/span")); 384 if (!selectedTab.equals(tabElement)) { 385 if (useAjax) { 386 AjaxRequestManager arm = new AjaxRequestManager(driver); 387 arm.begin(); 388 waitUntilEnabledAndClick(tabElement); 389 arm.end(); 390 } else { 391 waitUntilEnabledAndClick(tabElement); 392 } 393 } 394 } 395 396 protected void clickOnTabIfNotSelected(String tabPanelId, String tabElementId) { 397 WebElement tabElement = findElementWithTimeout( 398 By.xpath("//div[@id='" + tabPanelId + "']//a[contains(@id,'" + tabElementId + "')]/span")); 399 clickOnTabIfNotSelected(tabPanelId, tabElement); 400 } 401 402}