Selenium:在没有输入标签的字段中输入文本 - 如何找到它是哪一个?

标签 selenium selenium-webdriver xpath webdriver robotframework

我需要将文本输入到没有输入标签的表中的字段中。这个 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>

我发现了这个问题(顺便说一句,它似乎被错误地标记为重复)

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

那里的评论似乎对我的情况有意义:我的 XPath 指向一个 div,而不是一个输入字段(但如您所见,div 的类是“edit-cell”,所以...)但我不知道我想我没有指向输入字段的选项。我该如何解决这个问题 - 如何找到要定位的元素,以便我可以成功设置其文本,没有任何异常(exception)?

最佳答案

您得出的结论是正确的 - 您不能将输入发送到 <div>标记,这不是浏览器通常的工作方式(“edit 2”中给出了该规则的异常(exception)情况)。代码异常清楚地说明了这一点——“元素必须是用户可编辑的才能清除它”。不管 div 的类值为“edit-cell”——这只是开发人员选择的名称,用于说明性提议;这并不意味着 div 将能够接受输入。

应用程序使用的 UI 很可能使用这个 <div>用于用户设置的值的程式化表示;有一个隐藏的<input>采用实际键盘输入的元素,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> 上设置标记,您可以在页面中的任何元素上键入内容。

So - javascript 的修改版本,用于定位“谁拥有我们的值(value)”;谢天谢地,getElementsByTagName()支持参数的通配符 - 这将匹配任何元素:

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

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

edit3:使用 JS 根据文本内容查找任何标签。

任务继续 - 您输入的文本不会出现在任何元素的 value 中属性(property)?没问题,我们在元素文本中寻找吧。
当您实际编辑 <span> 的内容时可能会出现这种情况。 , <div>或类似的标签(祈祷... :))

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

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

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

分解 javascript 中的内容,以备将来更改:

  • document.getElementsByTagName("*")]返回具有该标签名称的所有元素作为数组;参数星号 ( * ) - 任何标签名称。
  • forEach - 遍历集合元素,将每个元素传递给其中的匿名函数。
  • el.textContent - 返回节点(及其子节点)的文本内容。
  • indexOf() - 返回参数在字符串中的位置,-1如果它不存在(使用 indexOf()contains() 以实现兼容性,后者出现在 ES6 中)。
  • 如果条件返回真,console.log(el)将在控制台中打印出来。

关于Selenium:在没有输入标签的字段中输入文本 - 如何找到它是哪一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54111402/

相关文章:

html - 如何在Ruby中解析面包屑

java - Webdriver 闪光灯按钮

c# - 系统不支持异常: 'Collection is read-only.' thrown when removing object from iList

haskell - 任何可用于 Selenium2/WebDriver 的纯函数式语言绑定(bind)?

xpath - Selenium IDE 中 XPath 表达式中的括号

c# - Selenium XPath 无法识别表格单元格中的文本

c# - 如果我已经拥有 FindsBy 的元素,如何将 Wait.Until 与 Selenium 一起使用

Python Selenium 浏览器 火狐

selenium - 无法连接到 Firefox

java - 如何在 Selenium WebDriver (Selenium 2) 中运行 Firebug?