如何使用Watir/ruby在谷歌文档中插入text/value



谷歌文档嵌入到iframe中的网站上。

这是我用来在谷歌文档上插入随机文本的代码

sample_text = Faker::Lorem.sentence
$browser.iframe(id: 'google_iframe').div(xpath: "//div[@class='kix-lineview']//div[contains(@class, 'kix-lineview-content')]").send_keys (sample_text)
$advanced_text_info['google_doc_article'] = sample_text

但当我运行测试时,我出现了错误

element located, but timed out after 30 seconds, waiting for #<Watir::Div: located: true; {:id=>"google_iframe", :tag_name=>"iframe"} --> {:xpath=>"//div[@class='kix-lineview']//div[contains(@class, 'kix-lineview-content')]", :tag_name=>"div"}> to be present (Watir::Exception::UnknownObjectException)

问题

问题的根源在于谷歌文档是如何实现其应用程序的。您正在写入的div不包括contenteditable属性:

<div class="kix-lineview-content" style="margin-left: 0px; padding-top: 0px; top: -1px;">

因此,Selenium不认为这个元素处于可交互状态。引发Selenium::WebDriver::Error::ElementNotInteractableError异常。您可以绕过Watir并直接调用Selenium来看到这一点:

browser.div(class: 'kix-lineview-content').wd.send_keys('text')
#=> Selenium::WebDriver::Error::ElementNotInteractableError (element not interactable)

瓦蒂尔隐瞒了这个例外情况,把事情弄糊涂了。如以下代码所示,不可交互的错误作为元素不存在异常UnknownObjectException而引发。我不确定这是故意的(如向后兼容性(还是疏忽。

rescue Selenium::WebDriver::Error::ElementNotInteractableError
raise_present unless browser.timer.remaining_time.positive?
raise_present unless %i[wait_for_present wait_for_enabled wait_for_writable].include?(precondition)
retry

总之,问题是元素不被认为是可交互的,而不是因为它不存在。

解决方案

我认为这里最好的方法是在尝试设置文本之前使div可交互。您可以通过自己添加contenteditable属性来做到这一点:

content = browser.div(class: 'kix-lineview-content') # This was sufficient when using Google Docs directly - update this for your specific iframe
content.execute_script('arguments[0].setAttribute("contenteditable", "true")', content)
content.send_keys(sample_text)

最新更新