tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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)