test_findelement.py (19745B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 from urllib.parse import quote 6 7 from marionette_driver.by import By 8 from marionette_driver.errors import NoSuchElementException, InvalidSelectorException 9 from marionette_driver.marionette import WebElement 10 11 from marionette_harness import MarionetteTestCase, skip 12 13 14 def inline(doc, doctype="html"): 15 if doctype == "html": 16 return "data:text/html;charset=utf-8,{}".format(quote(doc)) 17 elif doctype == "xhtml": 18 return "data:application/xhtml+xml,{}".format( 19 quote( 20 r"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 21 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 22 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 23 <head> 24 <title>XHTML might be the future</title> 25 </head> 26 27 <body> 28 {} 29 </body> 30 </html>""".format( 31 doc 32 ) 33 ) 34 ) 35 36 37 id_html = inline("<p id=foo></p>", doctype="html") 38 id_xhtml = inline('<p id="foo"></p>', doctype="xhtml") 39 parent_child_html = inline("<div id=parent><p id=child></p></div>", doctype="html") 40 parent_child_xhtml = inline( 41 '<div id="parent"><p id="child"></p></div>', doctype="xhtml" 42 ) 43 children_html = inline("<div><p>foo <p>bar</div>", doctype="html") 44 children_xhtml = inline("<div><p>foo</p> <p>bar</p></div>", doctype="xhtml") 45 class_html = inline("<p class='foo bar'>", doctype="html") 46 class_xhtml = inline('<p class="foo bar"></p>', doctype="xhtml") 47 name_html = inline("<p name=foo>", doctype="html") 48 name_xhtml = inline('<p name="foo"></p>', doctype="xhtml") 49 50 51 class TestFindElementHTML(MarionetteTestCase): 52 def setUp(self): 53 MarionetteTestCase.setUp(self) 54 self.marionette.timeout.implicit = 0 55 56 def test_id(self): 57 self.marionette.navigate(id_html) 58 expected = self.marionette.execute_script("return document.querySelector('p')") 59 found = self.marionette.find_element(By.ID, "foo") 60 self.assertIsInstance(found, WebElement) 61 self.assertEqual(found, expected) 62 63 def test_child_element(self): 64 self.marionette.navigate(parent_child_html) 65 parent = self.marionette.find_element(By.ID, "parent") 66 child = self.marionette.find_element(By.ID, "child") 67 found = parent.find_element(By.TAG_NAME, "p") 68 self.assertEqual(found.tag_name, "p") 69 self.assertIsInstance(found, WebElement) 70 self.assertEqual(child, found) 71 72 def test_tag_name(self): 73 self.marionette.navigate(children_html) 74 el = self.marionette.execute_script("return document.querySelector('p')") 75 found = self.marionette.find_element(By.TAG_NAME, "p") 76 self.assertIsInstance(found, WebElement) 77 self.assertEqual(el, found) 78 79 def test_class_name(self): 80 self.marionette.navigate(class_html) 81 el = self.marionette.execute_script("return document.querySelector('.foo')") 82 found = self.marionette.find_element(By.CLASS_NAME, "foo") 83 self.assertIsInstance(found, WebElement) 84 self.assertEqual(el, found) 85 86 def test_by_name(self): 87 self.marionette.navigate(name_html) 88 el = self.marionette.execute_script( 89 "return document.querySelector('[name=foo]')" 90 ) 91 found = self.marionette.find_element(By.NAME, "foo") 92 self.assertIsInstance(found, WebElement) 93 self.assertEqual(el, found) 94 95 def test_css_selector(self): 96 self.marionette.navigate(children_html) 97 el = self.marionette.execute_script("return document.querySelector('p')") 98 found = self.marionette.find_element(By.CSS_SELECTOR, "p") 99 self.assertIsInstance(found, WebElement) 100 self.assertEqual(el, found) 101 102 def test_invalid_css_selector_should_throw(self): 103 with self.assertRaises(InvalidSelectorException): 104 self.marionette.find_element(By.CSS_SELECTOR, "#") 105 106 def test_xpath(self): 107 self.marionette.navigate(id_html) 108 el = self.marionette.execute_script("return document.querySelector('#foo')") 109 found = self.marionette.find_element(By.XPATH, "id('foo')") 110 self.assertIsInstance(found, WebElement) 111 self.assertEqual(el, found) 112 113 def test_not_found(self): 114 self.marionette.timeout.implicit = 0 115 self.assertRaises( 116 NoSuchElementException, 117 self.marionette.find_element, 118 By.CLASS_NAME, 119 "cheese", 120 ) 121 self.assertRaises( 122 NoSuchElementException, 123 self.marionette.find_element, 124 By.CSS_SELECTOR, 125 "cheese", 126 ) 127 self.assertRaises( 128 NoSuchElementException, self.marionette.find_element, By.ID, "cheese" 129 ) 130 self.assertRaises( 131 NoSuchElementException, self.marionette.find_element, By.LINK_TEXT, "cheese" 132 ) 133 self.assertRaises( 134 NoSuchElementException, self.marionette.find_element, By.NAME, "cheese" 135 ) 136 self.assertRaises( 137 NoSuchElementException, 138 self.marionette.find_element, 139 By.PARTIAL_LINK_TEXT, 140 "cheese", 141 ) 142 self.assertRaises( 143 NoSuchElementException, self.marionette.find_element, By.TAG_NAME, "cheese" 144 ) 145 self.assertRaises( 146 NoSuchElementException, self.marionette.find_element, By.XPATH, "cheese" 147 ) 148 149 def test_not_found_implicit_wait(self): 150 self.marionette.timeout.implicit = 0.5 151 self.assertRaises( 152 NoSuchElementException, 153 self.marionette.find_element, 154 By.CLASS_NAME, 155 "cheese", 156 ) 157 self.assertRaises( 158 NoSuchElementException, 159 self.marionette.find_element, 160 By.CSS_SELECTOR, 161 "cheese", 162 ) 163 self.assertRaises( 164 NoSuchElementException, self.marionette.find_element, By.ID, "cheese" 165 ) 166 self.assertRaises( 167 NoSuchElementException, self.marionette.find_element, By.LINK_TEXT, "cheese" 168 ) 169 self.assertRaises( 170 NoSuchElementException, self.marionette.find_element, By.NAME, "cheese" 171 ) 172 self.assertRaises( 173 NoSuchElementException, 174 self.marionette.find_element, 175 By.PARTIAL_LINK_TEXT, 176 "cheese", 177 ) 178 self.assertRaises( 179 NoSuchElementException, self.marionette.find_element, By.TAG_NAME, "cheese" 180 ) 181 self.assertRaises( 182 NoSuchElementException, self.marionette.find_element, By.XPATH, "cheese" 183 ) 184 185 def test_not_found_from_element(self): 186 self.marionette.timeout.implicit = 0 187 self.marionette.navigate(id_html) 188 el = self.marionette.find_element(By.ID, "foo") 189 self.assertRaises( 190 NoSuchElementException, el.find_element, By.CLASS_NAME, "cheese" 191 ) 192 self.assertRaises( 193 NoSuchElementException, el.find_element, By.CSS_SELECTOR, "cheese" 194 ) 195 self.assertRaises(NoSuchElementException, el.find_element, By.ID, "cheese") 196 self.assertRaises( 197 NoSuchElementException, el.find_element, By.LINK_TEXT, "cheese" 198 ) 199 self.assertRaises(NoSuchElementException, el.find_element, By.NAME, "cheese") 200 self.assertRaises( 201 NoSuchElementException, el.find_element, By.PARTIAL_LINK_TEXT, "cheese" 202 ) 203 self.assertRaises( 204 NoSuchElementException, el.find_element, By.TAG_NAME, "cheese" 205 ) 206 self.assertRaises(NoSuchElementException, el.find_element, By.XPATH, "cheese") 207 208 def test_not_found_implicit_wait_from_element(self): 209 self.marionette.timeout.implicit = 0.5 210 self.marionette.navigate(id_html) 211 el = self.marionette.find_element(By.ID, "foo") 212 self.assertRaises( 213 NoSuchElementException, el.find_element, By.CLASS_NAME, "cheese" 214 ) 215 self.assertRaises( 216 NoSuchElementException, el.find_element, By.CSS_SELECTOR, "cheese" 217 ) 218 self.assertRaises(NoSuchElementException, el.find_element, By.ID, "cheese") 219 self.assertRaises( 220 NoSuchElementException, el.find_element, By.LINK_TEXT, "cheese" 221 ) 222 self.assertRaises(NoSuchElementException, el.find_element, By.NAME, "cheese") 223 self.assertRaises( 224 NoSuchElementException, el.find_element, By.PARTIAL_LINK_TEXT, "cheese" 225 ) 226 self.assertRaises( 227 NoSuchElementException, el.find_element, By.TAG_NAME, "cheese" 228 ) 229 self.assertRaises(NoSuchElementException, el.find_element, By.XPATH, "cheese") 230 231 def test_css_selector_scope_doesnt_start_at_rootnode(self): 232 self.marionette.navigate(parent_child_html) 233 el = self.marionette.find_element(By.ID, "child") 234 parent = self.marionette.find_element(By.ID, "parent") 235 found = parent.find_element(By.CSS_SELECTOR, "p") 236 self.assertEqual(el, found) 237 238 def test_unknown_selector(self): 239 with self.assertRaises(InvalidSelectorException): 240 self.marionette.find_element("foo", "bar") 241 242 def test_invalid_xpath_selector(self): 243 with self.assertRaises(InvalidSelectorException): 244 self.marionette.find_element(By.XPATH, "count(//input)") 245 with self.assertRaises(InvalidSelectorException): 246 parent = self.marionette.execute_script("return document.documentElement") 247 parent.find_element(By.XPATH, "count(//input)") 248 249 def test_invalid_css_selector(self): 250 with self.assertRaises(InvalidSelectorException): 251 self.marionette.find_element(By.CSS_SELECTOR, "") 252 with self.assertRaises(InvalidSelectorException): 253 parent = self.marionette.execute_script("return document.documentElement") 254 parent.find_element(By.CSS_SELECTOR, "") 255 256 def test_finding_active_element_returns_element(self): 257 self.marionette.navigate(id_html) 258 active = self.marionette.execute_script("return document.activeElement") 259 self.assertEqual(active, self.marionette.get_active_element()) 260 261 262 class TestFindElementXHTML(MarionetteTestCase): 263 def setUp(self): 264 MarionetteTestCase.setUp(self) 265 self.marionette.timeout.implicit = 0 266 267 def test_id(self): 268 self.marionette.navigate(id_xhtml) 269 expected = self.marionette.execute_script("return document.querySelector('p')") 270 found = self.marionette.find_element(By.ID, "foo") 271 self.assertIsInstance(found, WebElement) 272 self.assertEqual(expected, found) 273 274 def test_child_element(self): 275 self.marionette.navigate(parent_child_xhtml) 276 parent = self.marionette.find_element(By.ID, "parent") 277 child = self.marionette.find_element(By.ID, "child") 278 found = parent.find_element(By.TAG_NAME, "p") 279 self.assertEqual(found.tag_name, "p") 280 self.assertIsInstance(found, WebElement) 281 self.assertEqual(child, found) 282 283 def test_tag_name(self): 284 self.marionette.navigate(children_xhtml) 285 el = self.marionette.execute_script("return document.querySelector('p')") 286 found = self.marionette.find_element(By.TAG_NAME, "p") 287 self.assertIsInstance(found, WebElement) 288 self.assertEqual(el, found) 289 290 def test_class_name(self): 291 self.marionette.navigate(class_xhtml) 292 el = self.marionette.execute_script("return document.querySelector('.foo')") 293 found = self.marionette.find_element(By.CLASS_NAME, "foo") 294 self.assertIsInstance(found, WebElement) 295 self.assertEqual(el, found) 296 297 def test_by_name(self): 298 self.marionette.navigate(name_xhtml) 299 el = self.marionette.execute_script( 300 "return document.querySelector('[name=foo]')" 301 ) 302 found = self.marionette.find_element(By.NAME, "foo") 303 self.assertIsInstance(found, WebElement) 304 self.assertEqual(el, found) 305 306 def test_css_selector(self): 307 self.marionette.navigate(children_xhtml) 308 el = self.marionette.execute_script("return document.querySelector('p')") 309 found = self.marionette.find_element(By.CSS_SELECTOR, "p") 310 self.assertIsInstance(found, WebElement) 311 self.assertEqual(el, found) 312 313 def test_xpath(self): 314 self.marionette.navigate(id_xhtml) 315 el = self.marionette.execute_script("return document.querySelector('#foo')") 316 found = self.marionette.find_element(By.XPATH, "id('foo')") 317 self.assertIsInstance(found, WebElement) 318 self.assertEqual(el, found) 319 320 def test_css_selector_scope_does_not_start_at_rootnode(self): 321 self.marionette.navigate(parent_child_xhtml) 322 el = self.marionette.find_element(By.ID, "child") 323 parent = self.marionette.find_element(By.ID, "parent") 324 found = parent.find_element(By.CSS_SELECTOR, "p") 325 self.assertEqual(el, found) 326 327 def test_active_element(self): 328 self.marionette.navigate(id_xhtml) 329 active = self.marionette.execute_script("return document.activeElement") 330 self.assertEqual(active, self.marionette.get_active_element()) 331 332 333 class TestFindElementsHTML(MarionetteTestCase): 334 def setUp(self): 335 MarionetteTestCase.setUp(self) 336 self.marionette.timeout.implicit = 0 337 338 def assertItemsIsInstance(self, items, typ): 339 for item in items: 340 self.assertIsInstance(item, typ) 341 342 def test_child_elements(self): 343 self.marionette.navigate(children_html) 344 parent = self.marionette.find_element(By.TAG_NAME, "div") 345 children = self.marionette.find_elements(By.TAG_NAME, "p") 346 found = parent.find_elements(By.TAG_NAME, "p") 347 self.assertItemsIsInstance(found, WebElement) 348 self.assertSequenceEqual(found, children) 349 350 def test_tag_name(self): 351 self.marionette.navigate(children_html) 352 els = self.marionette.execute_script("return document.querySelectorAll('p')") 353 found = self.marionette.find_elements(By.TAG_NAME, "p") 354 self.assertItemsIsInstance(found, WebElement) 355 self.assertSequenceEqual(els, found) 356 357 def test_class_name(self): 358 self.marionette.navigate(class_html) 359 els = self.marionette.execute_script("return document.querySelectorAll('.foo')") 360 found = self.marionette.find_elements(By.CLASS_NAME, "foo") 361 self.assertItemsIsInstance(found, WebElement) 362 self.assertSequenceEqual(els, found) 363 364 def test_by_name(self): 365 self.marionette.navigate(name_html) 366 els = self.marionette.execute_script( 367 "return document.querySelectorAll('[name=foo]')" 368 ) 369 found = self.marionette.find_elements(By.NAME, "foo") 370 self.assertItemsIsInstance(found, WebElement) 371 self.assertSequenceEqual(els, found) 372 373 def test_css_selector(self): 374 self.marionette.navigate(children_html) 375 els = self.marionette.execute_script("return document.querySelectorAll('p')") 376 found = self.marionette.find_elements(By.CSS_SELECTOR, "p") 377 self.assertItemsIsInstance(found, WebElement) 378 self.assertSequenceEqual(els, found) 379 380 def test_invalid_css_selector_should_throw(self): 381 with self.assertRaises(InvalidSelectorException): 382 self.marionette.find_elements(By.CSS_SELECTOR, "#") 383 384 def test_xpath(self): 385 self.marionette.navigate(children_html) 386 els = self.marionette.execute_script("return document.querySelectorAll('p')") 387 found = self.marionette.find_elements(By.XPATH, ".//p") 388 self.assertItemsIsInstance(found, WebElement) 389 self.assertSequenceEqual(els, found) 390 391 def test_css_selector_scope_doesnt_start_at_rootnode(self): 392 self.marionette.navigate(parent_child_html) 393 els = self.marionette.find_elements(By.ID, "child") 394 parent = self.marionette.find_element(By.ID, "parent") 395 found = parent.find_elements(By.CSS_SELECTOR, "p") 396 self.assertSequenceEqual(els, found) 397 398 def test_unknown_selector(self): 399 with self.assertRaises(InvalidSelectorException): 400 self.marionette.find_elements("foo", "bar") 401 402 def test_invalid_xpath_selector(self): 403 with self.assertRaises(InvalidSelectorException): 404 self.marionette.find_elements(By.XPATH, "count(//input)") 405 with self.assertRaises(InvalidSelectorException): 406 parent = self.marionette.execute_script("return document.documentElement") 407 parent.find_elements(By.XPATH, "count(//input)") 408 409 def test_invalid_css_selector(self): 410 with self.assertRaises(InvalidSelectorException): 411 self.marionette.find_elements(By.CSS_SELECTOR, "") 412 with self.assertRaises(InvalidSelectorException): 413 parent = self.marionette.execute_script("return document.documentElement") 414 parent.find_elements(By.CSS_SELECTOR, "") 415 416 417 class TestFindElementsXHTML(MarionetteTestCase): 418 def setUp(self): 419 MarionetteTestCase.setUp(self) 420 self.marionette.timeout.implicit = 0 421 422 def assertItemsIsInstance(self, items, typ): 423 for item in items: 424 self.assertIsInstance(item, typ) 425 426 def test_child_elements(self): 427 self.marionette.navigate(children_xhtml) 428 parent = self.marionette.find_element(By.TAG_NAME, "div") 429 children = self.marionette.find_elements(By.TAG_NAME, "p") 430 found = parent.find_elements(By.TAG_NAME, "p") 431 self.assertItemsIsInstance(found, WebElement) 432 self.assertSequenceEqual(found, children) 433 434 def test_tag_name(self): 435 self.marionette.navigate(children_xhtml) 436 els = self.marionette.execute_script("return document.querySelectorAll('p')") 437 found = self.marionette.find_elements(By.TAG_NAME, "p") 438 self.assertItemsIsInstance(found, WebElement) 439 self.assertSequenceEqual(els, found) 440 441 def test_class_name(self): 442 self.marionette.navigate(class_xhtml) 443 els = self.marionette.execute_script("return document.querySelectorAll('.foo')") 444 found = self.marionette.find_elements(By.CLASS_NAME, "foo") 445 self.assertItemsIsInstance(found, WebElement) 446 self.assertSequenceEqual(els, found) 447 448 def test_by_name(self): 449 self.marionette.navigate(name_xhtml) 450 els = self.marionette.execute_script( 451 "return document.querySelectorAll('[name=foo]')" 452 ) 453 found = self.marionette.find_elements(By.NAME, "foo") 454 self.assertItemsIsInstance(found, WebElement) 455 self.assertSequenceEqual(els, found) 456 457 def test_css_selector(self): 458 self.marionette.navigate(children_xhtml) 459 els = self.marionette.execute_script("return document.querySelectorAll('p')") 460 found = self.marionette.find_elements(By.CSS_SELECTOR, "p") 461 self.assertItemsIsInstance(found, WebElement) 462 self.assertSequenceEqual(els, found) 463 464 @skip("XHTML namespace not yet supported") 465 def test_xpath(self): 466 self.marionette.navigate(children_xhtml) 467 els = self.marionette.execute_script("return document.querySelectorAll('p')") 468 found = self.marionette.find_elements(By.XPATH, "//xhtml:p") 469 self.assertItemsIsInstance(found, WebElement) 470 self.assertSequenceEqual(els, found) 471 472 def test_css_selector_scope_doesnt_start_at_rootnode(self): 473 self.marionette.navigate(parent_child_xhtml) 474 els = self.marionette.find_elements(By.ID, "child") 475 parent = self.marionette.find_element(By.ID, "parent") 476 found = parent.find_elements(By.CSS_SELECTOR, "p") 477 self.assertSequenceEqual(els, found)