Selenium - Get location after clicking on an ancho

2019-07-21 16:40发布

I'm trying to check the fact that when I click on an anchor link, some section is really at the top of the browser (I hope I'm making sense here.)

My test looks like that:

class Tests(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(chromedriver)
        self.accept_next_alert = True
        self.driver.set_window_size(1100, 800)
        self.base_url = "http://someurl"

    def test_anchor(self):
        driver = self.driver
        driver.get(self.base_url)
        driver.implicitly_wait(1)
        location = driver.find_element_by_xpath(
            "//section[@id='123123']").location
        print location

        driver.find_element_by_partial_link_text("anchor_text").click()
        location = driver.find_element_by_xpath(
            "//section[@id='123123']").location
        print location

        self.assertTrue(False)

The assertion is just so I can see my prints. What I get from that is that even though I see that the anchor worked, the location dict stays the same. So I guess I'm not using the right feature.

Could you think of another way to check that the click on the anchor had the expected effect? (by either not looking at the location or by looking at the location the right way or else)

3条回答
beautiful°
2楼-- · 2019-07-21 17:09

Another approach would be to click the link and assert that the page (or element, part of a page) looks like it should by comparing the screenshots with the help of cssneedle package:

from needle.cases import NeedleTestCase

class Tests(NeedleTestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(chromedriver)
        self.accept_next_alert = True
        self.driver.set_window_size(1100, 800)
        self.base_url = "http://someurl"

    def test_anchor(self):
        driver = self.driver
        driver.get(self.base_url)
        driver.implicitly_wait(1)

        driver.find_element_by_partial_link_text("anchor_text").click()

        self.assertScreenshot('#my_element_id', 'screenshot-file-name')

To create the screenshot-file-name you need to first run the same tests with --with-save-baseline flag:

nosetests my_test.py --with-save-baseline
查看更多
不美不萌又怎样
3楼-- · 2019-07-21 17:22

To check whether an anchor is set to bring the user to the right location, I use two types of tests:

  1. Check that the href attribute on the a element has a value which is '#' concatenated with the id of the element to which it is supposed to point. (Yes, I know in general the URL could be much more complicated. I just code my applications so that I can perform such a simple test.) This takes care of cases where I have an a element that just points to another element, without any special JavaScript processing.

  2. For the more complicated cases (for instance, if I intercept the click event before letting the browser scroll the window), I check the location of the element after clicking on it relative to the viewport. The problem with the .location field is that it is relative to the document and thus does not change with scrolling. You can get a position which is relative to the viewport like this:

    position = driver.execute_script("""
    var rect = arguments[0].getBoundingClientRect();
    return {left: rect.left, top: rect.top};
    """, element)
    

    where element is the element's whose coordinates you want. The position object will be a dictionary with the "left" and "top" keys corresponding to the x and y coordinates of your element relative to the viewport. If the element is near the top of the viewport then "top" will be 0 or close to 0. The fact is that there are sometimes rounding issues from browser to browser or some other factors affecting coordinates so I would not assert whether "top" is exactly 0 but I would use a few pixels tolerance either way.

I would not use screenshot comparisons to perform this test as such test would surely fail if I changed the styling of the element(s) of interest, even though in fact there is no problem with the code.

查看更多
趁早两清
4楼-- · 2019-07-21 17:22

I would say you use size which gives the absolute location of the element before click and after click then compare the value. That would be a easiest way to accomplish that.

driver = webdriver.Firefox()
e = driver.find_element_by_xpath("//someXpath")
location = e.location
size = e.size
print(location)
print(size)

Returns:

{'y': 202, 'x': 165}
{'width': 77, 'height': 22}

Code directly taken from here

查看更多
登录 后发表回答