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( 163 // replace existing input content when typing, as the clear() method crashes on boolean elements for 164 // instance 165 Keys.chord(Keys.CONTROL, "a"), // select input content for linux 166 Keys.chord(Keys.COMMAND, "a"), // select input content for macos 167 value); // add new value 168 } 169 } 170 171 /** 172 * Retrieves sub input element with given id and sets the given value. 173 * 174 * @see #setInput(WebElement, String) 175 */ 176 public void setInput(String id, String value) { 177 WebElement elt = getSubElement(id); 178 setInput(elt, value); 179 } 180 181 /** 182 * Retrieves sub input elements with given ids and sets corresponding values. 183 * 184 * @see #setInput(String, String) 185 */ 186 public void setInput(Map<String, String> entries) { 187 if (entries == null || entries.isEmpty()) { 188 return; 189 } 190 for (Map.Entry<String, String> entry : entries.entrySet()) { 191 setInput(entry.getKey(), entry.getValue()); 192 } 193 } 194 195 /** 196 * @since 5.9.2 197 */ 198 public <T extends WebFragment> T getWebFragment(String id, Class<T> webFragmentClass) { 199 return AbstractTest.getWebFragment(By.id(getSubElementId(id)), webFragmentClass); 200 } 201 202}