获取WebElement的javascript选择器

时间:2014-01-21 14:45:22

标签: javascript python selenium-webdriver

所以我有一个包装WebElement的类,并添加了一些功能,使它在我的页面对象中更有用。我现在需要设置文本输入的文本,我能看到的唯一方法就是注入javascript来查找元素并设置其value属性。

对于我有一个id要关闭的简单情况,这很简单,但是如果有动态生成的表单,可能没有一个有用的ID可以去掉 - 其中一些是通过找到封闭的表单然后找到的在其中寻找一个css选择器,其他输入匹配其他形式的同一个css选择器。

我可以看到我可以通过xpath找到所有内容来解决这个问题,但是必须有一个不那么脆弱/破坏性的解决方案。我知道你可以从Javascript执行器获取一个WebElement,我想知道是否可以向给定的WebElement注入javascript对象引用,如果没有,可以从现有的WebElement中获取运行时唯一的xpath

我正在使用python,但其他语言的解决方案可能是可转移的。


修改

我知道某处有一个webdriver元素缓存,我可以在该缓存中获取一个元素的id:

enter image description here

有没有办法在注入的javascript中使用它?

1 个答案:

答案 0 :(得分:3)

如果我正确理解您的问题,您就会问如何将Selenium WebElement对象传递给JavaScript。如果被测试的页面使用的是jQuery,它可能如下所示:

# select the element in python
form1 = driver.find_element_by_id('id_of_the_form')

# execute javascript which references the object
execute_script("$(arguments[0]).find('input.childOfInterest').val('newValue')", form1)

因为execute_script()接受String(JS执行)和可选的第二个参数(对象引用),所以使用arguments[0]引用对象(在本例中为WebElement)。在这个例子中,我传入了父表单元素,然后使用jQuery选择表单,使其成为一个jQuery对象,然后调用jQuery的.find(),传入一个css选择器来定位子元素,然后调用jQuery的.val()来更新元素的值。


您还询问了如何在运行时生成xpath。 以下是此示例(完整答案here):

// javascript
function getPathTo(element) {
    if (element.id!=='')
        return 'id("'+element.id+'")';
    if (element===document.body)
        return element.tagName;

    var ix= 0;
    var siblings= element.parentNode.childNodes;
    for (var i= 0; i<siblings.length; i++) {
        var sibling= siblings[i];
        if (sibling===element)
            return getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';
        if (sibling.nodeType===1 && sibling.tagName===element.tagName)
            ix++;
    }
}

以下是在Selenium中实施它的步骤

# define xpath generation JS in python
xpathJS = "function getPathTo(element){ if(element....."

# add new function to the page
execute_script(xpathJS)

# select an element with SE
element1 = driver.find_element_by_id('id_of_element')

# get the xpath of the element
xpath1 = execute_script("return getPathTo(arguments[0])", element1)