package bvira.test.abstraction; import org.antlr.stringtemplate.StringTemplate; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.Text; import org.jdom.xpath.XPath; import org.openqa.selenium.By; import org.openqa.selenium.SearchContext; import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.FindsById; import org.openqa.selenium.internal.FindsByLinkText; import org.openqa.selenium.internal.FindsByName; import org.openqa.selenium.internal.FindsByTagName; import org.openqa.selenium.internal.FindsByXPath; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class HtmlElement implements WebElement, SearchContext, FindsById, FindsByXPath, FindsByTagName, FindsByLinkText, FindsByName { private final Element element; private static final String NOT_SUPPORTED = "Not supported"; private static final String NOT_YET_IMPLEMENTED = "Not yet implemented."; private static final String CHECKED = "checked"; public HtmlElement(Element element) { this.element = element; } public WebElement findElementByTagName(String tagName) { return getElementOfType(tagName); } public List<WebElement> findElementsByTagName(String s) { return getElementsOfType(s); } public void click() { throw new UnsupportedOperationException(NOT_SUPPORTED); } public void submit() { throw new UnsupportedOperationException(NOT_SUPPORTED); } public void sendKeys(CharSequence... charSequences) { StringBuilder keys = new StringBuilder(); for (CharSequence charSequence : charSequences) { keys.append(charSequence.toString()); } element.setAttribute("value", keys.toString()); } public void clear() { throw new UnsupportedOperationException(NOT_SUPPORTED); } public String getTagName() { throw new UnsupportedOperationException(NOT_SUPPORTED); } public String getElementName() { return element.getName(); } public WebElement findElementByLinkText(String linkText) { List<WebElement> anchors = this.findElements(By.tagName("a")); for (WebElement anchor : anchors) { if (anchor.getText().equals(linkText)) { return anchor; } } throw new ElementNotFoundException("Unable to find anchor with link text: " + linkText); } public List<WebElement> findElementsByLinkText(String s) { throw new UnsupportedOperationException(NOT_YET_IMPLEMENTED); } public WebElement findElementByPartialLinkText(String s) { throw new UnsupportedOperationException(NOT_YET_IMPLEMENTED); } public List<WebElement> findElementsByPartialLinkText(String s) { throw new UnsupportedOperationException(NOT_YET_IMPLEMENTED); } public WebElement findElementByName(String s) { return getElementWithAttribute("name", s); } public List<WebElement> findElementsByName(String s) { throw new UnsupportedOperationException(NOT_YET_IMPLEMENTED); } public String getAttribute(String attributeName) { return element.getAttributeValue(attributeName); } public boolean toggle() { if (isSelected()) { element.removeAttribute(CHECKED); return false; } else { element.setAttribute(CHECKED, CHECKED); return true; } } public boolean isSelected() { return element.getAttributeValue(CHECKED) != null; } public void setSelected() { String name = element.getName(); String selector; String attributeName; if ("option".equals(name)) { selector = name; attributeName = "selected"; } else if ("input".equals(name) && "radio".equals(element.getAttribute("type").getValue())) { selector = "input[@type='radio']"; attributeName = CHECKED; } else { throw new UnsupportedOperationException("Unsupported for " + name); } try { Element oldSelectedElement = (Element) XPath.selectSingleNode(this.element, String.format("./../%s[@%s='%s']", selector, attributeName, attributeName)); if (oldSelectedElement != null) { oldSelectedElement.removeAttribute(attributeName); } } catch (JDOMException e) { throw new TestFrameworkException(e); } element.setAttribute(attributeName, attributeName); } public boolean isEnabled() { return element.getAttributeValue("disabled") == null; } public List<WebElement> findElements(By by) { return by.findElements(this); } public WebElement findElement(By by) { return by.findElement(this); } public HtmlElement getElementWithAttribute(String name, String value) { return selectSingleNode(String.format(".//*[@%s='%s']", name, value)); } public HtmlElement getElementOfType(String type) { return selectSingleNode(".//" + type); } public List<WebElement> getElementsOfType(String type) { return selectMultiHtmlElements(".//" + type); } public boolean hasElementWithName(String name) { try { selectSingleNode(String.format(".//*[@name='%s']", name)); return true; } catch (ElementNotFoundException e) { return false; } } public String getText() { return element.getTextTrim(); } public String getValue() { return element.getValue(); } public List<WebElement> getChildElements() { return toHtmlElements(element.getChildren()); } private HtmlElement selectSingleNode(String xpath) { try { Object node = XPath.selectSingleNode(this.element, xpath); if (node == null) { throw new ElementNotFoundException("Unable to find element matching xpath: " + xpath); } else if (node instanceof Element) { return new HtmlElement((Element) node); } else if (node instanceof Text) { return new TextNode((Text) node); } throw new ElementNotFoundException("Unable to find element matching xpath: " + xpath); } catch (JDOMException e) { throw new TestFrameworkException(e); } } @SuppressWarnings("unchecked") private List<WebElement> selectMultiHtmlElements(String xpath) { try { return toHtmlElements(XPath.selectNodes(element, xpath)); } catch (JDOMException e) { throw new TestFrameworkException(e); } } private List<WebElement> toHtmlElements(List<Element> elements) { List<WebElement> htmlElements = new ArrayList<WebElement>(); for (Element element : elements) { htmlElements.add(new HtmlElement(element)); } return htmlElements; } private String containingWord(String attribute, String word) { return "contains(concat(' ',normalize-space(@" + attribute + "),' '),' " + word + " ')"; } public WebElement findElementById(String id) { return selectSingleNode(findByIdXPath(id)); } private String findByIdXPath(String id) { return ".//*[" + containingWord("id", id) + "]"; } public List<WebElement> findElementsById(String id) { return Arrays.asList(findElementById(id)); } public WebElement findElementByXPath(String xpath) { return selectSingleNode(xpath); } public List<WebElement> findElementsByXPath(String xpath) { return selectMultiHtmlElements(xpath); } @Override public String toString() { StringTemplate st = new StringTemplate("<$element.name$ $element.attributes:{attr|$attr.name$=\"$attr.value$\" }$/>"); st.setAttribute("element", element); return st.toString(); } }