001/*
002 * (C) Copyright 2013 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-2.1.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 *      <a href="mailto:grenard@nuxeo.com">Guillaume</a>
016 */
017package org.nuxeo.functionaltests.pages.tabs;
018
019import java.util.List;
020import java.util.concurrent.TimeUnit;
021
022import org.apache.commons.lang.StringUtils;
023import org.apache.commons.logging.Log;
024import org.apache.commons.logging.LogFactory;
025import org.nuxeo.functionaltests.Required;
026import org.nuxeo.functionaltests.forms.Select2WidgetElement;
027import org.nuxeo.functionaltests.pages.DocumentBasePage;
028import org.openqa.selenium.By;
029import org.openqa.selenium.NoSuchElementException;
030import org.openqa.selenium.StaleElementReferenceException;
031import org.openqa.selenium.WebDriver;
032import org.openqa.selenium.WebElement;
033import org.openqa.selenium.support.FindBy;
034import org.openqa.selenium.support.ui.FluentWait;
035import org.openqa.selenium.support.ui.Select;
036import org.openqa.selenium.support.ui.Wait;
037
038import com.google.common.base.Function;
039
040/**
041 * Representation of a Relations tab page.
042 *
043 * @since 5.9.1
044 */
045public class RelationTabSubPage extends DocumentBasePage {
046
047    private static final Log log = LogFactory.getLog(RelationTabSubPage.class);
048
049    private static final int CREATE_FORM_LOADING_TIMEOUT = 20;
050
051    private static final int SELECT2_CHANGE_TIMEOUT = 4;
052
053    private static final String OBJECT_DOCUMENT_UID_ID = "createForm:objectDocumentUid";
054
055    private static final String SELECT2_DOCUMENT_XPATH = "//*[@id='s2id_createForm:nxw_singleDocumentSuggestion_2_select2']";
056
057    @Required
058    @FindBy(linkText = "Add a New Relation")
059    WebElement addANewRelationLink;
060
061    @FindBy(id = "createForm")
062    WebElement createRelationForm;
063
064    @FindBy(xpath = "//*[@id='createForm']/table/tbody/tr[4]/td[2]/input")
065    WebElement addButton;
066
067    @FindBy(id = "createForm:predicateUri")
068    WebElement predicate;
069
070    @FindBy(name = "createForm:objectType")
071    List<WebElement> objectCheckBoxList;
072
073    @FindBy(xpath = "//*[@id='document_relations']/table/tbody/tr")
074    List<WebElement> existingRelations;
075
076    /**
077     * @param driver
078     */
079    public RelationTabSubPage(WebDriver driver) {
080        super(driver);
081    }
082
083    public RelationTabSubPage deleteRelation(int index) {
084        getExistingRelations().get(index).findElement(By.linkText("Delete")).click();
085        return asPage(RelationTabSubPage.class);
086    }
087
088    public List<WebElement> getExistingRelations() {
089        return existingRelations;
090    }
091
092    public RelationTabSubPage initRelationSetUp() {
093        addANewRelationLink.click();
094
095        Function<WebDriver, Boolean> createRelationFormVisible = new Function<WebDriver, Boolean>() {
096            @Override
097            public Boolean apply(WebDriver driver) {
098                return createRelationForm != null;
099            }
100        };
101
102        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(CREATE_FORM_LOADING_TIMEOUT,
103                TimeUnit.SECONDS).pollingEvery(100, TimeUnit.MILLISECONDS).ignoring(NoSuchElementException.class);
104
105        wait.until(createRelationFormVisible);
106
107        return asPage(RelationTabSubPage.class);
108    }
109
110    private boolean isObjectChecked(int index) {
111        assert (index < 3 && index >= 0);
112        org.junit.Assert.assertNotNull(objectCheckBoxList);
113        org.junit.Assert.assertEquals(3, objectCheckBoxList.size());
114
115        return objectCheckBoxList.get(index).isSelected();
116    }
117
118    public boolean isObjectDocumentChecked() {
119        return isObjectChecked(2);
120    }
121
122    public RelationTabSubPage setRelationWithDocument(String documentName, String predicateUri) {
123
124        org.junit.Assert.assertFalse(isObjectDocumentChecked());
125
126        Select predicateSelect = new Select(predicate);
127        predicateSelect.selectByValue(predicateUri);
128
129        Select2WidgetElement documentSuggestionWidget = new Select2WidgetElement(driver,
130                driver.findElement(By.xpath(SELECT2_DOCUMENT_XPATH)));
131
132        documentSuggestionWidget.selectValue(documentName);
133
134        Function<WebDriver, Boolean> isDocumentSelected = new Function<WebDriver, Boolean>() {
135            @Override
136            public Boolean apply(WebDriver driver) {
137                WebElement selectedDocument = driver.findElement(By.id(OBJECT_DOCUMENT_UID_ID));
138                String value = selectedDocument.getAttribute("value");
139                boolean result = StringUtils.isNotBlank(value);
140                if (!result) {
141                    log.debug("Waiting for select2 ajaxReRender");
142                }
143                return result;
144            }
145        };
146
147        org.junit.Assert.assertTrue(isObjectDocumentChecked());
148
149        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(SELECT2_CHANGE_TIMEOUT, TimeUnit.SECONDS).pollingEvery(
150                100, TimeUnit.MILLISECONDS).ignoring(StaleElementReferenceException.class);
151
152        wait.until(isDocumentSelected);
153
154        if (log.isDebugEnabled()) {
155            WebElement selectedDocument = driver.findElement(By.id(OBJECT_DOCUMENT_UID_ID));
156            log.debug("Submitting relation on document: " + selectedDocument.getAttribute("value"));
157        }
158
159        addButton.click();
160
161        return asPage(RelationTabSubPage.class);
162    }
163
164}