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 * Antoine Taillefer 018 * Yannis JULIENNE 019 */ 020package org.nuxeo.functionaltests.pages.tabs; 021 022import java.util.ArrayList; 023import java.util.List; 024 025import org.apache.commons.logging.Log; 026import org.apache.commons.logging.LogFactory; 027import org.nuxeo.functionaltests.AbstractTest; 028import org.nuxeo.functionaltests.Locator; 029import org.nuxeo.functionaltests.Required; 030import org.nuxeo.functionaltests.pages.DocumentBasePage; 031import org.openqa.selenium.Alert; 032import org.openqa.selenium.By; 033import org.openqa.selenium.NoSuchElementException; 034import org.openqa.selenium.NotFoundException; 035import org.openqa.selenium.WebDriver; 036import org.openqa.selenium.WebDriverException; 037import org.openqa.selenium.WebElement; 038import org.openqa.selenium.support.FindBy; 039import org.openqa.selenium.support.ui.Clock; 040import org.openqa.selenium.support.ui.SystemClock; 041 042import static org.junit.Assert.assertEquals; 043import static org.junit.Assert.fail; 044 045/** 046 * Representation of a Archived versions sub tab page. 047 */ 048public class ArchivedVersionsSubPage extends DocumentBasePage { 049 050 private static final Log log = LogFactory.getLog(ArchivedVersionsSubPage.class); 051 052 private static final String DELETE_ACTION_ID = "CURRENT_VERSION_SELECTION_DELETE"; 053 054 private static final String VIEW_VERSION_ACTION_ID = "VIEW_VERSION"; 055 056 private static final String RESTORE_VERSION_ACTION_ID = "RESTORE_VERSION"; 057 058 @Required 059 @FindBy(id = "document_versions") 060 WebElement documentVersions; 061 062 @FindBy(id = "document_versions_form") 063 WebElement documentVersionsForm; 064 065 public ArchivedVersionsSubPage(WebDriver driver) { 066 super(driver); 067 } 068 069 /** 070 * Gets the version labels. 071 * 072 * @return the version labels 073 */ 074 public List<String> getVersionLabels() { 075 List<String> versionLabels = new ArrayList<String>(); 076 List<WebElement> trElements; 077 try { 078 trElements = documentVersionsForm.findElement(By.tagName("tbody")).findElements(By.tagName("tr")); 079 } catch (NoSuchElementException nsee) { 080 return versionLabels; 081 } 082 for (WebElement trItem : trElements) { 083 try { 084 WebElement versionLabel = trItem.findElement(By.xpath("td[2]")); 085 versionLabels.add(versionLabel.getText()); 086 } catch (NoSuchElementException e) { 087 // Go to next line 088 } 089 } 090 return versionLabels; 091 } 092 093 /** 094 * Selects a version given its label. 095 * 096 * @param versionLabel the version label 097 * @return the archived versions sub page 098 */ 099 public ArchivedVersionsSubPage selectVersion(String versionLabel) { 100 101 List<WebElement> trElements = documentVersionsForm.findElement(By.tagName("tbody")) 102 .findElements(By.tagName("tr")); 103 for (WebElement trItem : trElements) { 104 try { 105 trItem.findElement(By.xpath("td[text()=\"" + versionLabel + "\"]")); 106 WebElement checkBox = trItem.findElement(By.xpath("td/input[@type=\"checkbox\"]")); 107 Locator.waitUntilEnabledAndClick(checkBox); 108 break; 109 } catch (NoSuchElementException e) { 110 // Go to next line 111 } 112 } 113 return asPage(ArchivedVersionsSubPage.class); 114 } 115 116 /** 117 * Checks the ability to remove selected versions. 118 * 119 * @param canRemove true to check if can remove selected versions 120 */ 121 public void checkCanRemoveSelectedVersions(boolean canRemove) { 122 checkCanExecuteActionOnSelectedVersions(DELETE_ACTION_ID, canRemove); 123 } 124 125 /** 126 * Checks the ability to execute the action identified by {@code actionId} on selected versions. 127 * 128 * @param actionId the action id 129 * @param canExecute true to check if can execute action identified by {@code actionId} on selected versions 130 */ 131 public void checkCanExecuteActionOnSelectedVersions(String actionId, boolean canExecute) { 132 try { 133 findElementAndWaitUntilEnabled(By.xpath("//span[@id=\"" + actionId + "\"]/input"), 134 AbstractTest.LOAD_TIMEOUT_SECONDS * 1000, AbstractTest.AJAX_SHORT_TIMEOUT_SECONDS * 1000); 135 if (!canExecute) { 136 fail(actionId + " action should not be enabled because there is no version selected."); 137 } 138 } catch (NotFoundException nfe) { 139 if (canExecute) { 140 log.error(nfe, nfe); 141 fail(actionId + " action should be enabled because there is at least one version selected."); 142 } 143 } 144 } 145 146 /** 147 * Removes the selected versions. 148 * 149 * @return the archived versions sub page 150 */ 151 public ArchivedVersionsSubPage removeSelectedVersions() { 152 153 ArchivedVersionsSubPage archivedVersionsPage = null; 154 // As accepting the Delete confirm alert randomly fails to reload the 155 // page, we need to repeat the Delete action until it is really taken 156 // into account, ie. the "Delete" button is not displayed any more nor 157 // enabled. 158 Clock clock = new SystemClock(); 159 long end = clock.laterBy(AbstractTest.LOAD_TIMEOUT_SECONDS * 1000); 160 while (clock.isNowBefore(end)) { 161 try { 162 archivedVersionsPage = executeActionOnSelectedVersions(DELETE_ACTION_ID, true, 163 ArchivedVersionsSubPage.class, AbstractTest.LOAD_SHORT_TIMEOUT_SECONDS * 1000, 164 AbstractTest.AJAX_TIMEOUT_SECONDS * 1000); 165 } catch (NotFoundException nfe) { 166 if (archivedVersionsPage == null) { 167 break; 168 } 169 return archivedVersionsPage; 170 } 171 try { 172 Thread.sleep(100); 173 } catch (InterruptedException e) { 174 Thread.currentThread().interrupt(); 175 throw new RuntimeException(e); 176 } 177 } 178 throw new WebDriverException("Couldn't remove selected versions"); 179 } 180 181 /** 182 * Executes the action identified by {@code actionId} on selected versions. 183 * 184 * @param <T> the generic type of the page to return 185 * @param actionId the action id 186 * @param isConfirm true if the action needs a javascript confirm 187 * @param pageClass the class of the page to return 188 * @param findElementTimeout the find element timeout in milliseconds 189 * @param waitUntilEnabledTimeout the wait until enabled timeout in milliseconds 190 * @return the page displayed after the action execution 191 */ 192 public <T> T executeActionOnSelectedVersions(String actionId, boolean isConfirm, Class<T> pageClass, 193 int findElementTimeout, int waitUntilEnabledTimeout) { 194 Locator.findElementWaitUntilEnabledAndClick(null, By.xpath("//span[@id=\"" + actionId + "\"]/input"), 195 findElementTimeout, waitUntilEnabledTimeout); 196 if (isConfirm) { 197 Alert alert = driver.switchTo().alert(); 198 assertEquals("Delete selected document(s)?", alert.getText()); 199 alert.accept(); 200 } 201 return asPage(pageClass); 202 } 203 204 /** 205 * Views the version with label {@code versionLabel}. 206 * 207 * @param versionLabel the version label 208 * @return the version page 209 */ 210 public DocumentBasePage viewVersion(String versionLabel) { 211 return executeActionOnVersion(versionLabel, VIEW_VERSION_ACTION_ID); 212 } 213 214 /** 215 * Restores the version with label {@code versionLabel}. 216 * 217 * @param versionLabel the version label 218 * @return the restored version page 219 */ 220 public DocumentBasePage restoreVersion(String versionLabel) { 221 return executeActionOnVersion(versionLabel, RESTORE_VERSION_ACTION_ID); 222 } 223 224 /** 225 * Executes the action identified by {@code actionId} on the version with label {@code versionLabel}. 226 * 227 * @param versionLabel the version label 228 * @param actionId the action id 229 * @return the page displayed after the action execution 230 */ 231 public DocumentBasePage executeActionOnVersion(String versionLabel, String actionId) { 232 233 List<WebElement> trElements = documentVersionsForm.findElement(By.tagName("tbody")) 234 .findElements(By.tagName("tr")); 235 for (WebElement trItem : trElements) { 236 try { 237 trItem.findElement(By.xpath("td[text()=\"" + versionLabel + "\"]")); 238 WebElement actionButton = trItem.findElement(By.xpath("td/span[@id=\"" + actionId + "\"]/input")); 239 Locator.waitUntilEnabledAndClick(actionButton); 240 break; 241 } catch (NoSuchElementException e) { 242 // Go to next line 243 } 244 } 245 return asPage(DocumentBasePage.class); 246 } 247 248 /** 249 * @since 8.3 250 */ 251 public String getDocumentVersionsText() { 252 return documentVersions.getText(); 253 } 254}