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 <stan@nuxeo.com> 016 * Antoine Taillefer 017 */ 018package org.nuxeo.functionaltests.pages; 019 020import java.util.ArrayList; 021import java.util.List; 022 023import org.apache.commons.lang.StringUtils; 024import org.nuxeo.functionaltests.Locator; 025import org.nuxeo.functionaltests.Required; 026import org.nuxeo.functionaltests.fragment.AddToCollectionForm; 027import org.nuxeo.functionaltests.pages.actions.ContextualActions; 028import org.nuxeo.functionaltests.pages.admincenter.AdminCenterBasePage; 029import org.nuxeo.functionaltests.pages.search.SearchPage; 030import org.nuxeo.functionaltests.pages.tabs.CollectionContentTabSubPage; 031import org.nuxeo.functionaltests.pages.tabs.ContentTabSubPage; 032import org.nuxeo.functionaltests.pages.tabs.EditTabSubPage; 033import org.nuxeo.functionaltests.pages.tabs.HistoryTabSubPage; 034import org.nuxeo.functionaltests.pages.tabs.ManageTabSubPage; 035import org.nuxeo.functionaltests.pages.tabs.RelationTabSubPage; 036import org.nuxeo.functionaltests.pages.tabs.SummaryTabSubPage; 037import org.nuxeo.functionaltests.pages.tabs.WorkflowTabSubPage; 038import org.nuxeo.functionaltests.pages.tabs.WorkspacesContentTabSubPage; 039import org.openqa.selenium.By; 040import org.openqa.selenium.NoSuchElementException; 041import org.openqa.selenium.StaleElementReferenceException; 042import org.openqa.selenium.WebDriver; 043import org.openqa.selenium.WebElement; 044import org.openqa.selenium.support.FindBy; 045 046import com.google.common.base.Function; 047 048import static org.junit.Assert.assertEquals; 049 050/** 051 * The nuxeo main document base page 052 * 053 * @author Sun Seng David TAN <stan@nuxeo.com> 054 */ 055public class DocumentBasePage extends AbstractPage { 056 057 /** 058 * Exception occurred a user is expected to be connected but it isn't. 059 */ 060 public class UserNotConnectedException extends Exception { 061 /** 062 * 063 */ 064 private static final long serialVersionUID = 1L; 065 066 public UserNotConnectedException(String username) { 067 super("The user " + username + " is expected to be connected but isn't"); 068 } 069 } 070 071 @FindBy(xpath = "//form[@id='breadcrumbForm']") 072 public WebElement breadcrumbForm; 073 074 @FindBy(xpath = "//div[@id='nxw_documentTabs_panel']//a/span[text()='Content']") 075 public WebElement contentTabLink; 076 077 public ContextualActions contextualActions; 078 079 @FindBy(className = "creator") 080 public WebElement currentDocumentContributor; 081 082 @FindBy(className = "documentDescription") 083 public WebElement currentDocumentDescription; 084 085 @FindBy(xpath = "//form[@id='document_header_layout_form']//h1") 086 public WebElement currentDocumentTitle; 087 088 @FindBy(className = "currentDocumentDescription") 089 public WebElement currentFolderishDescription; 090 091 @FindBy(linkText = "WORKSPACE") 092 public WebElement documentManagementLink; 093 094 @FindBy(xpath = "//div[@id='nxw_documentTabs_panel']//a/span[text()='Edit']") 095 public WebElement editTabLink; 096 097 @FindBy(xpath = "//div[@id='nxw_documentTabs_panel']//a/span[text()='History']") 098 public WebElement historyTabLink; 099 100 @FindBy(xpath = "//div[@id='nxw_documentTabs_panel']//a/span[text()='Manage']") 101 public WebElement manageTabLink; 102 103 @FindBy(xpath = "//div[@id='nxw_documentTabs_panel']//a/span[text()='Relations']") 104 public WebElement relationTabLink; 105 106 @FindBy(xpath = "//div[@id='nxw_documentTabs_panel']//a/span[text()='Summary']") 107 public WebElement summaryTabLink; 108 109 @Required 110 @FindBy(xpath = "//div[@id='nxw_documentTabs_panel']") 111 public WebElement tabsBar; 112 113 @FindBy(linkText = "Workflow") 114 public WebElement workflowLink; 115 116 @Required 117 @FindBy(id = "nxw_userMenuActions_panel") 118 public WebElement userMenuActions; 119 120 @Required 121 @FindBy(linkText = "HOME") 122 public WebElement homePageLink; 123 124 @Required 125 @FindBy(linkText = "SEARCH") 126 public WebElement searchPageLink; 127 128 public DocumentBasePage(WebDriver driver) { 129 super(driver); 130 } 131 132 /** 133 * Check if the title of the current document page is equal to the {@code expectedTitle}. 134 * 135 * @param expectedTitle the expected title 136 */ 137 public void checkDocTitle(String expectedTitle) { 138 assertEquals(expectedTitle, getCurrentDocumentTitle()); 139 } 140 141 /** 142 * Check if the user is connected by looking for the text: You are logged as Username 143 * 144 * @param username 145 * @throws UserNotConnectedException 146 */ 147 public void checkUserConnected(String username) throws UserNotConnectedException { 148 if (!(getHeaderLinks().getText().contains(username))) { 149 throw new UserNotConnectedException(username); 150 } 151 } 152 153 protected void clickOnLinkIfNotSelected(WebElement tabLink) { 154 WebElement selectedTab = findElementWithTimeout(By.xpath("//div[@id='nxw_documentTabs_panel']//li[@class='selected']/a/span")); 155 if (!selectedTab.equals(tabLink)) { 156 tabLink.click(); 157 } 158 } 159 160 public AdminCenterBasePage getAdminCenter() { 161 findElementWithTimeout(By.linkText("ADMIN")).click(); 162 return asPage(AdminCenterBasePage.class); 163 } 164 165 /** 166 * Click on the content tab and return the subpage of this page. 167 */ 168 public ContentTabSubPage getContentTab() { 169 return getContentTab(ContentTabSubPage.class); 170 } 171 172 public <T extends ContentTabSubPage> T getContentTab(Class<T> tabClass) { 173 clickOnLinkIfNotSelected(contentTabLink); 174 return asPage(tabClass); 175 } 176 177 public CollectionContentTabSubPage getCollectionContentTab() { 178 return getContentTab(CollectionContentTabSubPage.class); 179 } 180 181 public ContextualActions getContextualActions() { 182 return asPage(ContextualActions.class); 183 } 184 185 /** 186 * @since 7.3 187 */ 188 public List<WebElement> getBlobActions(int index) { 189 return findElementsWithTimeout(By.xpath("(//div[@class='actionsColumn'])[" + (index + 1) + "]//a")); 190 } 191 192 public String getCurrentContributors() { 193 return currentDocumentContributor.getText(); 194 } 195 196 public String getCurrentDocumentDescription() { 197 return currentDocumentDescription.getText(); 198 } 199 200 public String getCurrentDocumentTitle() { 201 return currentDocumentTitle.getText(); 202 } 203 204 public String getCurrentFolderishDescription() { 205 return currentFolderishDescription.getText(); 206 } 207 208 public List<String> getCurrentStates() { 209 List<WebElement> states = findElementsWithTimeout(By.className("sticker")); 210 List<String> stateLabels = new ArrayList<String>(); 211 for (WebElement state : states) { 212 stateLabels.add(state.getText()); 213 } 214 return stateLabels; 215 } 216 217 /** 218 * @deprecated since 7.3: use {@link #goToWorkspaces()} instead 219 */ 220 public DocumentBasePage getDocumentManagement() { 221 return goToWorkspaces(); 222 } 223 224 public EditTabSubPage getEditTab() { 225 clickOnLinkIfNotSelected(editTabLink); 226 return asPage(EditTabSubPage.class); 227 } 228 229 public HistoryTabSubPage getHistoryTab() { 230 clickOnLinkIfNotSelected(historyTabLink); 231 return asPage(HistoryTabSubPage.class); 232 } 233 234 public ManageTabSubPage getManageTab() { 235 clickOnLinkIfNotSelected(manageTabLink); 236 return asPage(ManageTabSubPage.class); 237 } 238 239 public NavigationSubPage getNavigationSubPage() { 240 return asPage(NavigationSubPage.class); 241 } 242 243 public RelationTabSubPage getRelationTab() { 244 clickOnLinkIfNotSelected(relationTabLink); 245 return asPage(RelationTabSubPage.class); 246 } 247 248 public SummaryTabSubPage getSummaryTab() { 249 clickOnLinkIfNotSelected(summaryTabLink); 250 return asPage(SummaryTabSubPage.class); 251 } 252 253 /** 254 * @since 5.7 255 */ 256 public UserHomePage getUserHome() { 257 findElementWithTimeout(By.linkText("HOME")).click(); 258 UserHomePage page = asPage(UserHomePage.class); 259 // make sure we're back on the dashboard tab 260 return page.goToDashboard(); 261 } 262 263 public WorkflowTabSubPage getWorkflow() { 264 workflowLink.click(); 265 return asPage(WorkflowTabSubPage.class); 266 } 267 268 /** 269 * For workspace type, the content tab is a bit different. 270 */ 271 public WorkspacesContentTabSubPage getWorkspacesContentTab() { 272 clickOnLinkIfNotSelected(contentTabLink); 273 return asPage(WorkspacesContentTabSubPage.class); 274 } 275 276 public DocumentBasePage goToDocumentByBreadcrumb(String documentTitle) { 277 breadcrumbForm.findElement(By.linkText(documentTitle)).click(); 278 return asPage(DocumentBasePage.class); 279 } 280 281 private static final String ADD_TO_COLLECTION_UPPER_ACTION_ID = "nxw_addToCollectionAction_form:nxw_documentActionsUpperButtons_addToCollectionAction_subview:nxw_documentActionsUpperButtons_addToCollectionAction_link"; 282 283 private static final String ADD_ALL_TO_COLLECTION_ACTION_ID = "document_content_buttons:nxw_addSelectedToCollectionAction_form:nxw_cvButton_addSelectedToCollectionAction_subview:nxw_cvButton_addSelectedToCollectionAction_link"; 284 285 @FindBy(id = ADD_TO_COLLECTION_UPPER_ACTION_ID) 286 private WebElement addToCollectionUpperAction; 287 288 @FindBy(id = ADD_ALL_TO_COLLECTION_ACTION_ID) 289 private WebElement addAllToCollectionAction; 290 291 /** 292 * @since 5.9.3 293 */ 294 public AddToCollectionForm getAddToCollectionPopup() { 295 addToCollectionUpperAction.click(); 296 Locator.waitUntilElementPresent(By.id("fancybox-content")); 297 return getWebFragment(By.id("fancybox-content"), AddToCollectionForm.class); 298 } 299 300 /** 301 * @since 5.9.3 302 */ 303 public AddToCollectionForm getAddAllToCollectionPopup() { 304 Locator.waitUntilGivenFunctionIgnoring(new Function<WebDriver, Boolean>() { 305 @Override 306 public Boolean apply(WebDriver driver) { 307 return StringUtils.isBlank(driver.findElement(By.id(ADD_ALL_TO_COLLECTION_ACTION_ID)).getAttribute( 308 "disabled")); 309 } 310 }, StaleElementReferenceException.class); 311 driver.findElement(By.id(ADD_ALL_TO_COLLECTION_ACTION_ID)).click(); 312 Locator.waitUntilElementPresent(By.id("fancybox-content")); 313 return getWebFragment(By.id("fancybox-content"), AddToCollectionForm.class); 314 } 315 316 public boolean isAddToCollectionUpperActionAvailable() { 317 try { 318 driver.findElement(By.id(ADD_TO_COLLECTION_UPPER_ACTION_ID)); 319 return true; 320 } catch (final NoSuchElementException e) { 321 return false; 322 } 323 } 324 325 /** 326 * @since 5.9.3 327 */ 328 public void popupUserMenuActions() { 329 userMenuActions.findElement(By.id("nxw_userMenuActions_dropDownMenu")).click(); 330 Locator.waitUntilGivenFunctionIgnoring(new Function<WebDriver, Boolean>() { 331 @Override 332 public Boolean apply(WebDriver driver) { 333 return !userMenuActions.findElement(By.xpath("//ul[@class='actionSubList']")).getAttribute("style").equals( 334 "display: none;"); 335 } 336 }, StaleElementReferenceException.class); 337 } 338 339 /** 340 * @since 5.9.3 341 */ 342 public DocumentBasePage switchToPersonalWorkspace() { 343 popupUserMenuActions(); 344 driver.findElement(By.linkText("Personal Workspace")).click(); 345 return asPage(DocumentBasePage.class); 346 } 347 348 /** 349 * @since 5.9.3 350 */ 351 public DocumentBasePage switchToDocumentBase() { 352 popupUserMenuActions(); 353 driver.findElement(By.linkText("Back to Document Base")).click(); 354 return asPage(DocumentBasePage.class); 355 } 356 357 /** 358 * @since 5.9.3 359 */ 360 public HomePage goToHomePage() { 361 homePageLink.click(); 362 return asPage(HomePage.class); 363 } 364 365 /** 366 * @since 6.0 367 */ 368 public SearchPage goToSearchPage() { 369 searchPageLink.click(); 370 return asPage(SearchPage.class); 371 } 372 373 /** 374 * @since 7.3 375 */ 376 public DocumentBasePage goToWorkspaces() { 377 documentManagementLink.click(); 378 return asPage(DocumentBasePage.class); 379 } 380 381 /** 382 * Returns true if given element representing a main tab is selected in UI. 383 * 384 * @since 7.3 385 */ 386 public boolean isMainTabSelected(WebElement tab) { 387 WebElement elt = Locator.findParentTag(tab, "li"); 388 String css = elt.getAttribute("class"); 389 if (css != null && css.contains("selected")) { 390 return true; 391 } 392 return false; 393 } 394 395}