Selenium:在没有输入标签的字段中输入文本 – 如何找到它?

我需要将文本输入到没有输入标记的表中的字段中.此XPath唯一指出该字段

//div[@id="contentBody"]//div[@row="0"]/div[contains(@class, "l4") and contains(@class, "r4")]

(可以为此XPath添加尾部/ div,它没有区别)

我可以使用此XPath来读取此字段,但当我尝试在同一字段中插入一些文本时,我收到一条错误消息:

InvalidElementStateException: Message: invalid element state: Element must be user-editable in order to clear it.

这是单元格的HTML

<div class="slick-cell l4 r4  alignRight uppercase highint editable-cell active selected" aria-describedby="inforDataGrid731693C5" tabindex="-1" role="gridcell">
    <div class="edit-cell">2,0</div></div>

我发现了这个问题(BTW,似乎错误地标记为重复)

Element must be user-editable in order to clear it exception in selenium

那里的评论似乎对我的情况有意义:我的XPath指向div,而不是输入字段(但正如你所看到的,div的类是“edit-cell”所以…)但我不认为我可以选择指向输入字段.我如何解决这个问题 – 如何找到要定位的元素,以便我可以成功设置其文本,而不会例外?

最佳答案 您得出的结论是更正后的结果 – 您无法将输入发送到< div>标签,这不是浏览器通常如何工作(规则的例外在“编辑2”中给出).代码异常清楚地说明了 – “元素必须是用户可编辑的才能清除它”.无论div具有“编辑单元”的类值 – 这只是开发人员选择的名称,用于说明提议;它并不意味着div能够接受输入.

很可能应用程序使用的UI使用此< div>用于风格化呈现用户设置的值;有一个隐藏的 获取实际键盘条目的元素,javascript代码更新< div>跟他们.
您必须找到该输入标记,并根据您的更改进行定位.

edit1:使用JS通过其值查找输入标记.

以下是如何查找输入标记 – 在浏览器中(手动)将值设置为对页面唯一的字符串 – 例如,“myMegaSpecialString”.然后在控制台中运行以下js:

[...document.getElementsByTagName("input")].forEach(function(el){ if (el.value == "myMegaSpecialString"){console.log(el);} })

它将打印< input>具有“特殊”值的元素.

edit2:使用JS查找其值的任何标签.

根据评论中的讨论,没有< input>发现元素具有此值.正如我对@Andersson正确纠正的那样,在特殊情况下,除输入之外的其他元素可以接收,khm,输入 – 它们应该具有contenteditable属性,并且它是从父元素继承的 – 例如如果设置在< body>标签,您可以键入页面中的任何元素.

所以 – 修改版本的javascript来定位“谁拥有我们的价值”;谢天谢地,getElementsByTagName()支持参数的通配符 – 它将匹配任何元素:

[...document.getElementsByTagName("*")].forEach(function(el){ if (el.value == "myMegaSpecialString"){console.log(el);} })

它可能会慢一点 – 但它必须打印value属性等于“myMegaSpecialString”的元素.

edit3:使用JS查找文本内容的任何标签.

任务继续 – 你输入的文字没有出现在任何元素的value属性中?没问题,让我们在元素文本内容中查找它.
当您实际编辑< span>,< div>的内容时可能会出现这种情况.或类似标签(手指交叉…… :)).

这是以前版本的变体 – 手动将文本设置为整个页面中唯一的值(以限制输出),并在控制台中运行:

[...document.getElementsByTagName("*")].forEach(function(el){ if (el.textContent.indexOf("myMegaSpecialString") !== -1){console.log(el);} })

,(应该?可能?我不再确定任何东西:D)在控制台中打印所有DOM元素,这些元素将该字符串作为其文本的一部分.

细分javascript中的内容,以便将来进行更改:

> document.getElementsByTagName(“*”)]返回具有该标记名称的所有元素作为数组;参数asterisk(*) – 任何标签名称.
> forEach – 集合元素上的循环,将每个元素传递给其中的匿名函数.
> el.textContent – 返回节点(及其子节点)的文本内容.
> indexOf() – 返回字符串中参数的位置,如果不存在,则返回-1(使用indexOf()vs contains()以获得兼容性,后者在ES6中使用).
>如果条件返回true,则console.log(el)将在控制台中打印它.

点赞