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
016 *     Florent Guillaume
017 *     Antoine Taillefer
018 */
019package org.nuxeo.functionaltests.pages.tabs;
020
021import java.util.ArrayList;
022import java.util.Arrays;
023import java.util.List;
024
025import org.nuxeo.functionaltests.AjaxRequestManager;
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.WebDriver;
033import org.openqa.selenium.WebElement;
034import org.openqa.selenium.support.FindBy;
035
036import com.google.common.base.Function;
037
038import static org.junit.Assert.assertEquals;
039import static org.junit.Assert.assertNotNull;
040
041/**
042 * The content tab sub page. Most of the time available for folderish documents and displaying the current document's
043 * children.
044 */
045public class ContentTabSubPage extends DocumentBasePage {
046
047    private static final String COPY_BUTTON_XPATH = "//input[@value=\"Copy\"]";
048
049    private static final String PASTE_BUTTON_XPATH = "//input[@value=\"Paste\"]";
050
051    private static final String DELETE_BUTTON_XPATH = "//input[@value=\"Delete\"]";
052
053    private static final String ADD_TO_WORKLIST_BUTTON_XPATH = "//input[@value=\"Add to Worklist\"]";
054
055    private static final String SELECT_ALL_BUTTON_XPATH = "//input[@type=\"checkbox\" and @title=\"Select all / deselect all\"]";
056
057    private static final String CHECK_BOX_XPATH = "td/input[@type=\"checkbox\"]";
058
059    private static final String DOCUMENT_TITLE_XPATH = "td//span[@id[starts-with(.,'title_')]]";
060
061    @Required
062    @FindBy(id = "document_content")
063    WebElement documentContentForm;
064
065    @FindBy(linkText = "New")
066    WebElement newButton;
067
068    @FindBy(id = "cv_document_content_0_quickFilterForm:nxl_document_content_filter:nxw_search_title")
069    WebElement filterInput;
070
071    @FindBy(id = "cv_document_content_0_quickFilterForm:submitFilter")
072    WebElement filterButton;
073
074    @FindBy(id = "cv_document_content_0_resetFilterForm:resetFilter")
075    WebElement clearFilterButton;
076
077    @FindBy(xpath = "//form[@id=\"document_content\"]//tbody//tr")
078    List<WebElement> childDocumentRows;
079
080    public List<WebElement> getChildDocumentRows() {
081        return childDocumentRows;
082    }
083
084    public ContentTabSubPage(WebDriver driver) {
085        super(driver);
086    }
087
088    /**
089     * Clicking on one of the child with the title.
090     *
091     * @param documentTitle
092     */
093    public DocumentBasePage goToDocument(String documentTitle) {
094        documentContentForm.findElement(By.linkText(documentTitle)).click();
095        return asPage(DocumentBasePage.class);
096    }
097
098    /**
099     * Clicks on the new button and select the type of document to create
100     *
101     * @param docType the document type to create
102     * @param pageClassToProxy The page object type to return
103     * @return The create form page object
104     */
105    public <T> T getDocumentCreatePage(String docType, Class<T> pageClassToProxy) {
106        newButton.click();
107        WebElement fancyBox = getFancyBoxContent();
108        // find the link to doc type that needs to be created
109        WebElement link = fancyBox.findElement(By.linkText(docType));
110        assertNotNull(link);
111        link.click();
112        return asPage(pageClassToProxy);
113    }
114
115    public DocumentBasePage removeDocument(String documentTitle) {
116        // get all table item and if the link has the documents title, click
117        // (enable) checkbox
118
119        List<WebElement> trelements = documentContentForm.findElement(By.tagName("tbody")).findElements(
120                By.tagName("tr"));
121        for (WebElement trItem : trelements) {
122            try {
123                trItem.findElement(By.linkText(documentTitle));
124                WebElement checkBox = trItem.findElement(By.xpath("td/input[@type=\"checkbox\"]"));
125                checkBox.click();
126                break;
127            } catch (NoSuchElementException e) {
128                // next
129            }
130        }
131        deleteSelectedDocuments();
132
133        return asPage(DocumentBasePage.class);
134    }
135
136    protected void deleteSelectedDocuments() {
137        findElementWaitUntilEnabledAndClick(By.xpath(DELETE_BUTTON_XPATH));
138        Alert alert = driver.switchTo().alert();
139        assertEquals("Delete selected document(s)?", alert.getText());
140        alert.accept();
141    }
142
143    public DocumentBasePage addToWorkList(String documentTitle) {
144        // get all table item and if the link has the documents title, click
145        // (enable) checkbox
146
147        selectDocumentByTitles(documentTitle);
148        findElementWaitUntilEnabledAndClick(By.xpath(ADD_TO_WORKLIST_BUTTON_XPATH));
149
150        return asPage(DocumentBasePage.class);
151    }
152
153    public ContentTabSubPage removeAllDocuments() {
154        ContentTabSubPage page = asPage(ContentTabSubPage.class);
155        By locator = By.xpath(SELECT_ALL_BUTTON_XPATH);
156        if (!hasElement(locator)) {
157            // no document to remove
158            return page;
159        }
160        findElementWaitUntilEnabledAndClick(By.xpath(SELECT_ALL_BUTTON_XPATH));
161        deleteSelectedDocuments();
162
163        try {
164            documentContentForm.findElement(By.tagName("tbody"));
165        } catch (NoSuchElementException e) {
166            // no more document to remove
167            return page;
168        }
169        return removeAllDocuments();
170    }
171
172    /**
173     * Perform filter on the given string.
174     *
175     * @param filter the string to filter
176     * @param expectedDisplayedElt
177     * @param timeout
178     * @since 5.7.2
179     */
180    public void filterDocument(final String filter, final int expectedNbOfDisplayedResult, final int timeout) {
181        filterInput.clear();
182        filterInput.sendKeys(filter);
183        filterButton.click();
184        Locator.waitUntilGivenFunction(new Function<WebDriver, Boolean>() {
185            @Override
186            public Boolean apply(WebDriver driver) {
187                try {
188                    return getChildDocumentRows().size() == expectedNbOfDisplayedResult;
189                } catch (NoSuchElementException e) {
190                    return false;
191                }
192            }
193        });
194    }
195
196    /**
197     * Reset the filter.
198     *
199     * @param expectedNbOfDisplayedResult
200     * @param timeout
201     * @since 5.7.2
202     */
203    public void clearFilter(final int expectedNbOfDisplayedResult, final int timeout) {
204        clearFilterButton.click();
205        Locator.waitUntilGivenFunction(new Function<WebDriver, Boolean>() {
206            @Override
207            public Boolean apply(WebDriver driver) {
208                try {
209                    return getChildDocumentRows().size() == expectedNbOfDisplayedResult;
210                } catch (NoSuchElementException e) {
211                    return false;
212                }
213            }
214        });
215    }
216
217    /**
218     * Select the document by their index in the content view.
219     *
220     * @param indexes
221     * @since 5.7.8
222     */
223    public void selectDocumentByIndex(int... indexes) {
224        AjaxRequestManager a = new AjaxRequestManager(driver);
225        for (int i : indexes) {
226            a.watchAjaxRequests();
227            getChildDocumentRows().get(i).findElement(By.xpath(CHECK_BOX_XPATH)).click();
228            a.waitForAjaxRequests();
229        }
230    }
231
232    /**
233     * Select the document by their title in the content view.
234     *
235     * @param indexes
236     * @since 5.7.8
237     */
238    public void selectDocumentByTitles(String... titles) {
239        selectDocumentByIndex(convertToIndexes(titles));
240    }
241
242    protected int[] convertToIndexes(String... titles) {
243        List<String> titleList = Arrays.asList(titles);
244        List<Integer> temp = new ArrayList<Integer>();
245        int index = 0;
246        for (WebElement row : childDocumentRows) {
247            String docTitle = row.findElement(By.xpath(DOCUMENT_TITLE_XPATH)).getText();
248            if (docTitle != null && titleList.contains(docTitle)) {
249                temp.add(index);
250            }
251            index++;
252        }
253        int[] result = new int[temp.size()];
254        for (int i = 0; i < temp.size(); i++) {
255            result[i] = temp.get(i);
256        }
257        return result;
258    }
259
260    /**
261     * Select the document by their index in the content view and copy them in the clipboard.
262     *
263     * @param indexes
264     * @since 5.7.8
265     */
266    public void copyByIndex(int... indexes) {
267        selectDocumentByIndex(indexes);
268        findElementWaitUntilEnabledAndClick(By.xpath(COPY_BUTTON_XPATH));
269    }
270
271    /**
272     * Select the document by their title in the content view and copy them in the clipboard.
273     *
274     * @param indexes
275     * @since 5.7.8
276     */
277    public void copyByTitle(String... titles) {
278        copyByIndex(convertToIndexes(titles));
279    }
280
281    /**
282     * Past the content of the clip board.
283     *
284     * @param indexes
285     * @since 5.7.8
286     */
287    public ContentTabSubPage paste() {
288        findElementWaitUntilEnabledAndClick(By.xpath(PASTE_BUTTON_XPATH));
289        return asPage(ContentTabSubPage.class);
290    }
291
292    /**
293     * @since 5.9.3
294     */
295    public DocumentBasePage goToDocument(final int index) {
296        getChildDocumentRows().get(index).findElement(By.xpath("td[3]/div/a[1]")).click();
297        return asPage(DocumentBasePage.class);
298    }
299}