3

在 Selenium 中,您可以通过 IWebElement 实例访问浏览器的底层 DOM。像这样:

IWebElement domWrapper = driver.FindElement(By.Name("q"));

假设您有如上例所示的“domWrapper”实例,但是您没有等式的右侧;这意味着您 a) 不知道元素实际代表什么,并且 b) 您不知道它是如何定位的。鉴于这两个前提条件,是否可以使用 selenium 为元素分配 id?我见过的所有为元素分配 id 的示例都利用 javascript 和定位器在 dom 中查找实例。

我最初是如何表达这个问题的(没有人理解:-))

关于如何将 id 分配给 Selenium 中的任意元素的任何想法?我通过 IWebElement 接口引用了 DOM 中的元素,并且我知道驱动程序支持 Javascript 的执行,但我只是不知道如何在没有 id 的情况下唯一地引用元素。

Psedu 代码示例(此代码通过使用它唯一设置的属性来定位 dom 元素以操纵 id,在我的情况下,我没有这样的唯一属性可以依赖)。

    public string Id
    {
        get { return GetAttribute("id"); }
        set
        {
            var finder = string.Format("document.querySelector('[{0}=\"{1}\"]')", "data-bind", element.GetAttribute("data-bind"));

            string setId = "('id', '_id__'+(Math.floor(Math.random()*10000000)+1));";
            string js = finder + ".setAttribute" + setId + ";";
            Driver.ExecuteJavascript(js);
        }
    }
4

1 回答 1

4

当访问 DOM 时,Selenium 中 IWebElement 的实现实际上是“真实”DOM 元素的代理(相当于执行例如 document.getElementsByClass 或类似操作)。这反过来意味着您可以将 IWebElement 作为传递给浏览器的 Javascript 方法的参数传递。

最简单的方法是向浏览器传递一个脚本,该脚本创建一个新函数,接受两个参数 - DOM 元素和新 ID:

在 Javascript 中,函数如下所示:

var setId = function(elem, newId)
{
   elem.id = newId
};

我们会这样称呼它:

setId(document.elementFromPoint(1, 2), 'myNewId');

因此,从 Selenium 中,我们可以利用将 IWebDriver 转换为 IJavaScriptExecutor 时获得的 ExecuteJavascript 方法:

public void SetIdForElement(IWebElement element, string id)
{
     // same as above, compressed to a one-liner.
     string scriptString = "sId=function(e, i){e.id = i;};sId(arguments[0], arguments[1]);"

     ((IJavaScriptExecutor)driver).ExecuteScript(scriptString, element, id);
}

您现在可以轻松地为您可以从 Selenium 测试中访问的任何元素设置 ID。

于 2013-09-02T07:07:19.540 回答