/**
*
*/
package com.thoughtworks.calabash.android;
import org.joda.time.DateTime;
import org.jruby.RubyArray;
import org.jruby.RubyHash;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.thoughtworks.calabash.android.CalabashLogger.error;
import static java.lang.Double.parseDouble;
/**
* Represents an UI element.
*/
public class UIElement implements AndroidElementAction {
private final Map<Object, Object> data;
private final String query;
private final CalabashWrapper calabashWrapper;
public UIElement(RubyHash data, String query, CalabashWrapper calabashWrapper) {
this.data = (Map<Object, Object>) Utils.toJavaHash(data);
this.query = query;
this.calabashWrapper = calabashWrapper;
}
public UIElement(HashMap<Object, Object> data, String query, CalabashWrapper calabashWrapper) {
this.data = data;
this.query = query;
this.calabashWrapper = calabashWrapper;
}
/**
* Get element's class
*
* @return the class property
*/
public String getElementClass() {
return Utils.toString(data.get("class"));
}
/**
* Gets the element id
*
* @return the id property
*/
public String getId() {
return Utils.toString(data.get("id"));
}
/**
* Gets the value
*
* @return the text property
*/
public String getValue() {
return Utils.toString(data.get("value"));
}
/**
* Gets the text content
*
* @return the text property
*/
public String getTextContent() {
return Utils.toString(data.get("textContent"));
}
/**
* Gets the label
*
* @return the text property
*/
public String getText() {
return Utils.toString(data.get("text"));
}
/**
* Set the text property of the element
*
* @param text
* @throws CalabashException
*/
public void setText(String text) throws CalabashException {
calabashWrapper.enterText(text, this.getQuery());
}
/**
* Get description about this element
*
* @return the description property
*/
public String getDescription() throws CalabashException {
return getElementProperty("description");
}
/**
* is the element enabled
*
* @return the isEnabled property
*/
public boolean isEnabled() {
return Boolean.parseBoolean(Utils.toString(data.get("enabled")));
}
/**
* Get the content description of this element
*
* @return the contentDescription property
*/
public String getContentDescription() throws CalabashException {
return getElementProperty("contentDescription");
}
private String getElementProperty(String property) throws CalabashException {
Object description = data.get(property);
if (description == null) {
description = getProperty(property);
}
return Utils.toString(description);
}
/**
* Gets the underlying query used to locate this element
*
* @return query
*/
public String getQuery() {
return this.query;
}
/**
* Gets the rectangle
*
* @return the rectangle
*/
public Rect getRect() {
Map<String, String> rect;
try {
rect = (Map<String, String>) data.get("rect");
if (rect == null)
return null;
} catch (Exception e) {
return null;
}
return new Rect(parseDouble(rect.get("x")),
parseDouble(rect.get("y")),
parseDouble(rect.get("width")),
parseDouble(rect.get("height")),
parseDouble(rect.get("center_x")),
parseDouble(rect.get("center_y")));
}
/**
* Gets all the child elements for this element
*
* @return List of UIElement
* @throws CalabashException
*/
public UIElements children() throws CalabashException {
String q = query + " child *";
RubyArray result = calabashWrapper.query(q);
return new UIElements(result, q, calabashWrapper);
}
/**
* Inspects the current element and it's child elements and call callback
* for each element
*
* @param callback Callback to be invoked
* @throws CalabashException
*/
public void inspect(InspectCallback callback) throws CalabashException {
TreeBuilder treeBuilder = new TreeBuilder(calabashWrapper);
TreeNode tree = treeBuilder.createTreeFrom(this);
Utils.inspectElement(tree, 0, callback);
}
/**
* set the checked property of the element. It is advisable to do it only on a check box
*
* @param checked
* @throws CalabashException
*/
public void setChecked(boolean checked) throws CalabashException {
calabashWrapper.setChecked(this.getQuery(), checked);
}
/**
* get the <code>selector</code> property of the element
*
* @param selector the property of the element
* @return the getValue of the selector property
* @throws CalabashException
*/
public Object getProperty(String selector) throws CalabashException {
RubyArray rubyArray = calabashWrapper.query(this.getQuery(), selector);
Object value = Utils.toJavaObject(rubyArray.get(0));
if (value != null && value.toString().toLowerCase().contains("no accessor")) {
return null;
}
return value;
}
public void touch() throws CalabashException {
calabashWrapper.touch(query);
}
public void longPress() throws CalabashException {
calabashWrapper.longPress(query);
}
/**
* @return the date value represented by the UI element if it is a date picker
* @throws CalabashException
*/
public DateTime getDate() throws CalabashException {
return calabashWrapper.getDate(getQuery());
}
/**
* @return the time value represented by the UI element if it is a time picker in HH:mm (24 hour) format
* @throws CalabashException
*/
public String getTime() throws CalabashException {
return calabashWrapper.getTime(getQuery());
}
/**
* set the date if it is a date picker
*
* @param date date to be set
* @throws CalabashException
*/
public void setDate(DateTime date) throws CalabashException {
calabashWrapper.setDate(getQuery(), date.getYear(), date.getMonthOfYear(), date.getDayOfMonth());
}
public void setTime(int hour, int minute) throws CalabashException {
calabashWrapper.setTime(getQuery(), hour, minute);
}
/**
* get the tree with the current element as the root
*
* @return treeNode
* @throws CalabashException
*/
public TreeNode getTree() throws CalabashException {
return new TreeBuilder(calabashWrapper).createTreeFrom(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UIElement uiElement = (UIElement) o;
if (getId() != null ? !getId().equals(uiElement.getId()) : uiElement.getId() != null) return false;
if (getElementClass() != null ? !getElementClass().equals(uiElement.getElementClass()) : uiElement.getElementClass() != null)
return false;
if (getRect() != null ? !getRect().equals(uiElement.getRect()) : uiElement.getRect() != null) return false;
if (getText() != null ? !getText().equals(uiElement.getText()) : uiElement.getText() != null) return false;
return true;
}
@Override
public int hashCode() {
List<Object> objects = new ArrayList<Object>();
objects.add(getId());
objects.add(getElementClass());
objects.add(getRect());
objects.add(getText());
int result = 0;
for (Object object : objects) {
result = 31 * result + (object != null ? object.hashCode() : 0);
}
return result;
}
public String toString() {
try {
return String.format("id: %s, class: %s, text: %s, description: %s, content description: %s, enabled: %s, rect: %s",
getId(), getElementClass(), getText(), getDescription(), getContentDescription(), isEnabled(), getRect());
} catch (CalabashException e) {
error("Unable to get string value of element", e);
}
return "";
}
}