@@ -2,126 +2,150 @@ package seleniumtestinglib.jestdom
22
33import org.openqa.selenium.By
44import org.openqa.selenium.WebElement
5+ import org.openqa.selenium.remote.RemoteWebDriver
6+ import org.openqa.selenium.remote.RemoteWebElement
57
68/* *
79 * https://testing-library.com/docs/ecosystem-jest-dom/
810 */
911fun expect (element : WebElement ? ) = JestDomMatcher (element)
1012
13+ // TODO: test nulls
1114class JestDomMatcher (
12- private val webElement : WebElement ? ,
15+ private val element : WebElement ? ,
1316 private val requireTrue : Boolean = true ,
1417) {
1518
16- val not get() = JestDomMatcher (webElement , requireTrue.not ())
19+ val not get() = JestDomMatcher (element , requireTrue.not ())
1720
1821 private fun assertTrue (condition : Boolean ) {
1922 require(condition xor requireTrue.not ())
2023 }
2124
2225 fun toBeDisabled () {
23- assertTrue(webElement ?.isEnabled == false )
26+ assertTrue(element ?.isEnabled == false )
2427 }
2528
2629 fun toBeEnabled () {
27- assertTrue(webElement ?.isEnabled == true )
30+ assertTrue(element ?.isEnabled == true )
2831 }
2932
3033 fun toBeEmptyDomElement () {
31- assertTrue(webElement?.text?.isEmpty() == true )
34+ val innerHtml = element?.getAttribute(" innerHTML" )?.replace(" <!--.*?-->" .toRegex(), " " )
35+ assertTrue(innerHtml?.isEmpty() == true )
3236 }
3337
3438 fun toBeInvalid () {
35- assertTrue(
36- webElement?.getAttribute(" aria-invalid" ) in setOf (" " , " true" )
37- )
39+ JestDomMatcher (element, requireTrue.not ())
3840 }
3941
4042 fun toBeInTheDocument () {
41- requireNotNull(webElement )
43+ assertTrue(element != null )
4244 }
4345
4446 fun toBeRequired () {
4547 assertTrue(
46- webElement?.getAttribute(" required" ) in setOf (" " , " true" ) ||
47- webElement?.getAttribute(" aria-required" ) in setOf (" " , " true" )
48+ ((element?.tagName == " input" ) and (element?.getAttribute(" type" ) == " file" ) or (element?.ariaRole?.lowercase() in setOf (
49+ " textbox" ,
50+ " checkbox" ,
51+ " radio" ,
52+ " email" ,
53+ " spinbutton" ,
54+ " combobox" ,
55+ " listbox" ,
56+ " date" ,
57+ ))) and (element?.getAttribute(" required" ) in setOf (
58+ " " ,
59+ " true"
60+ )) or (element?.getAttribute(" aria-required" ) in setOf (" " , " true" ))
4861 )
4962 }
5063
64+ private val driver get() = ((element as ? RemoteWebElement )?.wrappedDriver) as ? RemoteWebDriver
65+
5166 fun toBeValid () {
52- val ariaInvalid = webElement?.getAttribute(" aria-invalid" )
53- assertTrue(ariaInvalid == null || ariaInvalid == " false" )
67+ assertTrue(
68+ when (element?.tagName) {
69+ " form" -> driver?.executeScript(" return arguments[0].checkValidity()" , element) as Boolean
70+ else -> driver?.executeScript(" return arguments[0].getAttribute('aria-invalid')" , element) in
71+ setOf (null , " false" )
72+ }
73+ )
5474 }
5575
5676 fun toBeVisible () {
57- assertTrue(webElement ?.isDisplayed == true )
77+ assertTrue(element ?.isDisplayed == true )
5878 }
5979
6080 fun toContainElement (ancestor : WebElement ? ) {
61- assertTrue(webElement ?.findElements(By .xpath(" .//*" ))?.contains(ancestor) == true )
81+ assertTrue(element ?.findElements(By .xpath(" .//*" ))?.contains(ancestor) == true )
6282 }
6383
6484 fun toContainHtml (htmlText : String ) {
65- assertTrue(webElement?.getAttribute(" innerHTML" )?.contains(htmlText) == true )
85+ val normalizedHtmlText = driver?.executeScript(
86+ """
87+ const parser = new DOMParser()
88+ const htmlDoc = parser.parseFromString(arguments[0], "text/html")
89+ return htmlDoc.querySelector("body").innerHTML
90+ """ , htmlText
91+ ) as String
92+ assertTrue(element?.getAttribute(" innerHTML" )?.contains(normalizedHtmlText) == true )
6693 }
6794
6895 fun toHaveAccessibleDescription (description : String? = null) {
69- val accessibleDescription = webElement?.getAttribute(" aria-describedby" ) ? : webElement?.getAttribute(" title" )
70- if (description == null )
71- assertTrue(accessibleDescription != null )
72- else
73- assertTrue(description == accessibleDescription)
96+ val accessibleDescription = element?.getAttribute(" aria-describedby" ) ? : element?.getAttribute(" title" )
97+ if (description == null ) assertTrue(accessibleDescription?.isNotBlank() == true )
98+ else assertTrue(description == accessibleDescription)
7499 }
75100
76101 fun toHaveAccessibleName () {
77- assertTrue(webElement ?.accessibleName?.isNotBlank() == true )
102+ assertTrue(element ?.accessibleName?.isNotBlank() == true )
78103 }
79104
80105 fun toHaveAttribute (attribute : String , value : String ) {
81- assertTrue(value == webElement ?.getAttribute(attribute))
106+ assertTrue(value == element ?.getAttribute(attribute))
82107 }
83108
84109 fun toHaveClass (className : String ) {
85- assertTrue(webElement ?.getAttribute(" class" )?.contains(className) == null )
110+ assertTrue(element ?.getAttribute(" class" )?.contains(className) == null )
86111 }
87112
88113 fun toHaveFocus () {
89114 }
90115
91116 fun toHaveFormValues (values : Map <String , String >) {
92- assertTrue(values.all { webElement ?.getAttribute(it.key) == it.value })
117+ assertTrue(values.all { element ?.getAttribute(it.key) == it.value })
93118 }
94119
95120 fun toHaveStyle (styles : Map <String , String >) {
96- assertTrue(styles.all { webElement ?.getCssValue(it.key) == it.value })
121+ assertTrue(styles.all { element ?.getCssValue(it.key) == it.value })
97122 }
98123
99124 fun toHaveTextContent (text : String , normalizeWhitespace : Boolean = false) {
100125 assertTrue(
101- text == if (normalizeWhitespace) webElement?.text?.replace(
102- " \\ s+" .toRegex(),
103- " "
104- ) else webElement?.text
126+ text == if (normalizeWhitespace) element?.text?.replace(
127+ " \\ s+" .toRegex(), " "
128+ ) else element?.text
105129 )
106130 }
107131
108132 fun toHaveValue (value : String ) {
109- assertTrue(value == webElement ?.getAttribute(" value" ))
133+ assertTrue(value == element ?.getAttribute(" value" ))
110134 }
111135
112136 fun toHaveDisplayValue (value : String ) {
113- assertTrue(value == webElement ?.getAttribute(" value" ))
137+ assertTrue(value == element ?.getAttribute(" value" ))
114138 }
115139
116140 fun toBeChecked () {
117- assertTrue(webElement ?.getAttribute(" checked" ) == " true" )
141+ assertTrue(element ?.getAttribute(" checked" ) == " true" )
118142 }
119143
120144 fun toBePartiallyChecked () {
121- assertTrue(" true" == webElement ?.getAttribute(" indeterminate" ))
145+ assertTrue(" true" == element ?.getAttribute(" indeterminate" ))
122146 }
123147
124148 fun toHaveErrorMessage (message : String ) {
125- assertTrue(message == webElement ?.getAttribute(" aria-errormessage" ))
149+ assertTrue(message == element ?.getAttribute(" aria-errormessage" ))
126150 }
127151}
0 commit comments