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