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