001/*
002 * (C) Copyright 2012 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 *     Anahide Tchertchian
018 */
019package org.nuxeo.functionaltests.forms;
020
021import java.lang.reflect.Constructor;
022import java.util.Map;
023
024import org.nuxeo.functionaltests.AbstractTest;
025import org.nuxeo.functionaltests.Assert;
026import org.nuxeo.functionaltests.Locator;
027import org.nuxeo.functionaltests.fragment.WebFragment;
028import org.openqa.selenium.By;
029import org.openqa.selenium.Keys;
030import org.openqa.selenium.WebDriver;
031import org.openqa.selenium.WebElement;
032
033/**
034 * Represents a layout on the page, with helper methods to retrieve its widgets.
035 *
036 * @since 5.7
037 */
038public class LayoutElement implements LayoutFragment {
039
040    protected final WebDriver driver;
041
042    protected String id;
043
044    public String getId() {
045        return id;
046    }
047
048    public void setId(String id) {
049        this.id = id;
050    }
051
052    /**
053     * @param driver
054     * @param id
055     */
056    public LayoutElement(WebDriver driver, String id) {
057        this.driver = driver;
058        this.id = id;
059    }
060
061    /**
062     * Returns a sub element, concatenating the layout id with the sub element id (and using the standard character ':'
063     * as JSF UINamingContainer separator).
064     */
065    @Override
066    public String getSubElementId(String id) {
067        String finalId = id;
068        if (this.id != null) {
069            if (this.id.endsWith(":")) {
070                finalId = this.id + id;
071            } else {
072                finalId = this.id + ":" + id;
073            }
074        }
075        return finalId;
076    }
077
078    protected <T> T instantiateWidget(String id, Class<T> pageClassToProxy) {
079        try {
080            try {
081                Constructor<T> constructor = pageClassToProxy.getConstructor(WebDriver.class, String.class);
082                return constructor.newInstance(driver, getSubElementId(id));
083            } catch (NoSuchMethodException e) {
084                return pageClassToProxy.newInstance();
085            }
086        } catch (RuntimeException e) {
087            throw e;
088        } catch (Exception e) {
089            throw new RuntimeException(e);
090        }
091    }
092
093    /**
094     * Returns a {@link WidgetElement} with given id, after having injected its fields.
095     */
096    @Override
097    public WidgetElement getWidget(String id) {
098        return getWidget(id, WidgetElement.class);
099    }
100
101    /**
102     * Returns a widget with given id , after having injected its fields.
103     */
104    @Override
105    public <T> T getWidget(String id, Class<T> widgetClassToProxy) {
106        T res = instantiateWidget(id, widgetClassToProxy);
107        res = AbstractTest.fillElement(widgetClassToProxy, res);
108        return res;
109    }
110
111    /**
112     * Returns true if sub element is found in the page.
113     */
114    protected boolean hasSubElement(String id) {
115        return Assert.hasElement(By.id(getSubElementId(id)));
116    }
117
118    /**
119     * Returns the element with given id in the page.
120     */
121    public WebElement getElement(String id) {
122        return Locator.findElement(By.id(id));
123    }
124
125    /**
126     * Returns the element with given id in the page.
127     *
128     * @param wait if true, waits for a default timeout (useful when element is added to the page after an ajax call).
129     */
130    public WebElement getElement(String id, boolean wait) {
131        return Locator.findElementWithTimeout(By.id(id));
132    }
133
134    /**
135     * Returns the element with given sub id on the page.
136     * <p>
137     * The layout id is concatenated to the sub element id for retrieval.
138     */
139    @Override
140    public WebElement getSubElement(String id) {
141        return getElement(getSubElementId(id));
142    }
143
144    /**
145     * Returns the element with given sub id on the page.
146     * <p>
147     * The layout id is concatenated to the sub element id for retrieval.
148     *
149     * @param wait if true, waits for a default timeout (useful when element is added to the page after an ajax call).
150     */
151    @Override
152    public WebElement getSubElement(String id, boolean wait) {
153        return getElement(getSubElementId(id), wait);
154    }
155
156    /**
157     * Clears the given input element and sets the given value if not null.
158     */
159    public void setInput(WebElement elt, String value) {
160        Locator.waitUntilEnabledAndClick(elt);
161        if (value != null) {
162            elt.sendKeys(Keys.chord(Keys.CONTROL, "a"), value);
163        }
164    }
165
166    /**
167     * Retrieves sub input element with given id and sets the given value.
168     *
169     * @see #setInput(WebElement, String)
170     */
171    public void setInput(String id, String value) {
172        WebElement elt = getSubElement(id);
173        setInput(elt, value);
174    }
175
176    /**
177     * Retrieves sub input elements with given ids and sets corresponding values.
178     *
179     * @see #setInput(String, String)
180     */
181    public void setInput(Map<String, String> entries) {
182        if (entries == null || entries.isEmpty()) {
183            return;
184        }
185        for (Map.Entry<String, String> entry : entries.entrySet()) {
186            setInput(entry.getKey(), entry.getValue());
187        }
188    }
189
190    /**
191     * @since 5.9.2
192     */
193    public <T extends WebFragment> T getWebFragment(String id, Class<T> webFragmentClass) {
194        return AbstractTest.getWebFragment(By.id(getSubElementId(id)), webFragmentClass);
195    }
196
197}