com.github.loyada.dollarx.ElementProperties.scala Maven / Gradle / Ivy
package com.github.loyada.dollarx
import com.github.loyada.dollarx.ElementPropertiesHelper._
import com.github.loyada.dollarx.util.XpathUtils
object ElementProperties {
implicit def elementPropertyToPath(p: ElementProperty): Path = Path.element.that(p)
case class hasClass(cssClass: String) extends ElementProperty {
override def toXpath = XpathUtils.hasClass(cssClass)
override def toString = s"""has class "$cssClass""""
}
def not(prop: ElementProperty): ElementProperty = {
Not(prop)
}
case class isNthFromLastSibling(reverseIndex: Integer) extends ElementProperty {
def toXpath: String = {
String.format("count(following-sibling::*)=%d", reverseIndex)
}
override def toString: String = String.format("is in place %d from the last sibling", reverseIndex)
}
case class isNthSibling(index: Integer) extends ElementProperty {
def toXpath: String = String.format("count(preceding-sibling::*)=%d", index)
override def toString: String = String.format("is in place %d among its siblings", index)
}
object has {
import ElementPropertiesHelper.HasHelper._
def apply(n: NCount) = HasN(n)
def child(path: Path) = hasChild(path)
def parent(path: Path) = hasParent(path)
def sibling(path: Path) = hasSibling(path)
def descendant(path: Path*) = hasDescendant(path:_*)
def ancestor(path: Path) = hasAncesctor(path)
def children = new HasChildren
def noChildren = HasNoChildren
def id(theId: String) = hasId(theId)
def cssClass(cssClass: String) = hasClass(cssClass)
def classes(cssClasses: String*) = hasClasses(cssClasses:_*)
def oneOfClasses(cssClasses: String*) = hasOneOfClasses(cssClasses:_*)
def text(txt: String) = hasText(txt)
def textStartingWith(txt: String) = hasTextStartingWith(txt)
def textEndingWith(txt: String) = hasTextEndingWith(txt)
def textContaining(txt: String) = hasTextContaining(txt)
val someText = hasSomeText
def aggregatedTextContaining(txt: String) = withAggregatedTextContaining(txt)
def aggregatedText(txt: String) = withAggregatedTextEqualTo(txt)
def aggregatedTextStartingWith(txt: String) = withAggregatedTextStartingWith(txt)
def aggregatedTextEndingWith(txt: String) = withAggregatedTextEndingWith(txt)
def attributeWithValue(key: String, value: Any) = hasAttributeWithValue(key, value)
def attribute(name: String) = hasAttribute(name)
def name(name: String) = hasAttributeWithValue("name", name)
trait HasNotProperty {
def get: ElementProperty
}
object bar extends HasNotProperty {
override def get: ElementProperty = HasNoChildren
}
def no(p: HasNotProperty): ElementProperty = p.get
object not {
object children extends HasNotProperty {
override def get: ElementProperty = HasNoChildren
}
case class cssClass(cssClass: String*) extends HasNotProperty{
override def get: ElementProperty = withoutClasses(cssClass:_*)
}
object text extends HasNotProperty{
override def get: ElementProperty = hasNoText()
}
case class textEqualTo(txt: String) extends HasNotProperty {
override def get: ElementProperty = hasNoText(txt)
}
case class textContaining(txt: String) extends HasNotProperty {
override def get: ElementProperty = Not(hasTextContaining(txt))
}
case class aggregatedTextContaining(txt: String) extends HasNotProperty {
override def get: ElementProperty = Not(withAggregatedTextContaining(txt))
}
case class aggregatedText(txt: String) extends HasNotProperty {
override def get: ElementProperty = Not(withAggregatedTextEqualTo(txt))
}
}
}
object lastSiblingOfType extends ElementProperty{
override def toXpath = "last()"
override def toString = "is last sibling"
}
object uniqueOfType extends ElementProperty {
override def toXpath = "count(*)=1"
override def toString = "only one of its type"
}
case class hasId(id: String) extends ElementProperty {
override def toXpath = XpathUtils.hasId(id)
override def toString = s"""has Id "$id""""
}
case class hasOneOfClasses(cssClasses: String*) extends ElementProperty {
override def toXpath = XpathUtils.hasOneOfClasses(cssClasses: _*)
override def toString = s"has at least one of the classes: [${cssClasses.mkString(", ")}]"
}
case class hasClasses(cssClasses: String*) extends ElementProperty {
override def toXpath = XpathUtils.hasClasses(cssClasses: _*)
override def toString = s"has classes [${cssClasses.mkString(", ")}]"
}
case class withoutClasses(cssClasses: String*) extends ElementProperty {
override def toXpath = XpathUtils.DoesNotExist(XpathUtils.hasOneOfClasses(cssClasses: _*))
override def toString = {
if (cssClasses.size>1) {
s"has non of the classes: [${cssClasses.mkString(", ")}]"
}
else s"does not have the class ${cssClasses.mkString(", ")}"
}
}
case class raw(rawXpathProps: String, explanation: String) extends ElementProperty {
override def toXpath: String = rawXpathProps
override def toString = explanation
}
case class hasText(txt: String) extends ElementProperty {
override def toXpath = XpathUtils.textEquals(txt)
override def toString = s"""has the text "$txt""""
}
case class hasNoText(txt: String = "") extends ElementProperty {
override def toXpath = {
val hasItProperty = if (txt=="") hasSomeText else hasText(txt)
val hasNoProperty = not(hasItProperty)
hasNoProperty.toXpath
}
override def toString = if (txt=="") "has no text" else s"""has no text equal to "$txt""""
}
case class hasTextStartingWith(txt: String) extends ElementProperty {
override def toXpath = XpathUtils.textStartsWith(txt)
override def toString = s"""has text that starts with "$txt""""
}
case class hasTextEndingWith(txt: String) extends ElementProperty {
override def toXpath = XpathUtils.textEndsWith(txt)
override def toString = s"""has text that ends with "$txt""""
}
case class hasTextContaining(txt: String) extends ElementProperty {
override def toXpath = XpathUtils.textContains(txt)
override def toString = s"""has text containing "$txt""""
}
case class withAggregatedTextEqualTo(txt: String) extends ElementProperty {
override def toXpath = XpathUtils.aggregatedTextEquals(txt)
override def toString = s"""with aggregated text "$txt""""
}
case class withAggregatedTextStartingWith(txt: String) extends ElementProperty {
override def toXpath = XpathUtils.aggregatedStartsWith(txt)
override def toString = s"""with aggregated text that starts with "$txt""""
}
case class withAggregatedTextEndingWith(txt: String) extends ElementProperty {
override def toXpath = XpathUtils.aggregatedTextEndsWith(txt)
override def toString = s"""with aggregated text that ends with "$txt""""
}
case class withAggregatedTextContaining(txt: String) extends ElementProperty {
override def toXpath = XpathUtils.aggregatedTextContains(txt)
override def toString = s"""with aggregated text containing "$txt""""
}
object hasSomeText extends ElementProperty {
override def toXpath = XpathUtils.hasSomeText
override def toString = "has some text"
}
object isHidden extends ElementProperty with IsProperty{
override def toXpath = XpathUtils.isHidden
override def toString = "is hidden"
}
case class isChildOf(path: Path) extends ElementProperty with relationBetweenElement {
override def toXpath = getRelationXpath("parent")
override def toString = {
"is child of: " + path
}
}
def contains(paths: Path*) = hasDescendant(paths:_*)
case class hasDescendant(paths: Path*) extends ElementProperty with relationBetweenMultiElement {
protected val relation = "descendant"
override def toString = asString("has descendant")
}
case class hasAncesctor(path: Path) extends ElementProperty with relationBetweenElement with IsProperty{
override def toXpath = getRelationXpath("ancestor")
override def toString = {
"has ancestor: " + rValueToString(path)
}
}
case class hasParent(path: Path) extends ElementProperty with relationBetweenElement {
override def toXpath = getRelationXpath("parent")
override def toString = {
"has parent: " + rValueToString(path)
}
}
case class hasSibling(path: Path) extends ElementProperty with relationBetweenElement {
override def toXpath = (isAfterSibling(path) or isBeforeSibling(path)).toXpath
override def toString = {
"has sibling: " + rValueToString(path)
}
}
case class hasChild(paths: Path*) extends ElementProperty with relationBetweenMultiElement {
protected val relation = "child"
override def toString = asString("has " + (if (paths.size==1) "child" else "children"))
override protected def plural(relation: String) = relation
}
case class hasAttributeWithValue(attribute: String, value: Any) extends ElementProperty {
override def toXpath: String = {
XpathUtils.hasAttribute(attribute, value.toString)
}
override def toString: String = {
String.format("has attribute %s: \"%s\"", attribute, value.toString)
}
}
case class hasAttribute(attribute: String) extends ElementProperty {
override def toXpath: String = {
XpathUtils.hasAttributeName(attribute)
}
override def toString: String = {
String.format("has the attribute \"%s\"", attribute)
}
}
object is {
import ElementPropertiesHelper.IsHelpers._
def not(e: IsProperty) = Not(e)
def after(nPath: NPath) = IsAfterProperty(nPath)
def before(nPath: NPath) = IsBeforeProperty(nPath)
def siblingOf(path: Path*) = IsSiblingProperty(path: _*)
def afterSibling(path: Path*) = IsAfterSiblingProperty(path: _*)
def afterSibling(nPath: NPath) = IsAfterSiblingProperty(nPath)
def inside(path: Path) = hasAncesctor(path)
def containedIn(path: Path) = inside(path)
def childOf(path: Path) = isChildOf(path)
def descendantOf(path: Path) = inside(path)
def ancestorOf(paths: Path*) = hasDescendant(paths: _*)
def parentOf(paths: Path*) = hasChild(paths: _*)
def before(paths: Path*) = IsBeforeProperty(paths: _*)
def after(paths: Path*) = IsAfterProperty(paths: _*)
def beforeSibling(paths: Path*) = IsBeforeSiblingProperty(paths: _*)
def beforeSibling(nPath: NPath) = IsBeforeSiblingProperty(nPath)
def nthFromLastSibling(n: Int) = isNthFromLastSibling(n)
def nthSibling(n: Int) = isNthSibling(n)
val lastSibling = lastSiblingOfType
val firstSibling = withIndex(0)
def withIndex(index: Int) = IsWithIndex(index)
val hidden = isHidden
val onlyChild: ElementProperty = new ElementProperty {
override def toXpath: String = "count(preceding-sibling::*)=0 and count(following-sibling::*)=0"
override def toString: String = "is only child"
}
def withIndexInRange(first: Int, last: Int): ElementProperty = {
IsWithIndexInRange(first, last)
}
}
implicit def intToNPathBuilder(n: Int): NPathBuilder = NPathBuilder(n)
private def rValueToString(path: Path): String = if (path.toString.trim.contains(" ")) "(" + path + ")" else path.toString
case class isAfter(paths: Path*) extends ElementProperty with relationBetweenMultiElement {
protected val relation = "preceding"
override def toString = asString("is after")
override protected def plural(relation: String) = relation
}
case class isAfterSibling(paths: Path*) extends ElementProperty with relationBetweenMultiElement {
protected val relation = "preceding-sibling"
override def toString = asString("is after sibling")
}
case class isBefore(paths: Path*) extends ElementProperty with relationBetweenMultiElement {
protected val relation = "following"
override def toString = asString("is before")
}
case class isBeforeSibling(paths: Path*) extends ElementProperty with relationBetweenMultiElement {
protected val relation = "following-sibling"
override def toString = asString("is before sibling")
}
implicit def intToNCountBuilder(n: Int): NCountBuilder = NCountBuilder(n)
implicit def intToNTimes(n: Int): NCount = NCount(n)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy