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