如何基于capybara中的元素发送JavaScript

我希望在Capybara做类似的事情:

browser.execute_script("arguments[0].setAttribute('value', 'value')", element) 

上面的行是在selenium / ruby​​上运行的,但是使用带有capybara的execute_script只需要1个参数(脚本),因此我无法定义我希望执行脚本的元素……任何想法?

选项1 – 直接调用Selenium的execute_script

最快的解决方案是绕过Capybara API并直接调用Selenium-WebDriver的execute_script方法。

为此,您需要使用以下命令访问底层的Selenium :: WebDriver :: Driver:

 page.driver.browser 

同样,传递给Selenium的execute_script的元素需要是Selenium :: WebDriver :: Element(而不是Capybara :: Node :: Element)。 这是通过:

 element.native 

例如,假设您有一个包含文本字段的页面:

  

然后以下将更改字段的值:

 element = find('#field') p element.value #=> "5" page.driver.browser.execute_script("arguments[0].setAttribute('value', 'value')", element.native) p element.value #=> "value" 

选项2 – 补丁Capybara允许参数

如果你需要经常这样做,你可以修补Capybara的execute_script方法来获取参数,将参数转换为Selenium对象,然后将其传递给Selenium-WebDriver的方法。 补丁将是:

 require 'capybara' class Capybara::Session def execute_script(script, *args) @touched = true driver.execute_script(script, *args) end end class Capybara::Selenium::Driver def execute_script(script, *args) args.map! { |e| e.kind_of?(Capybara::Node::Element) ? e.native : e } browser.execute_script(script, *args) end end 

这将允许您将Capybara元素传递给会话execute_script方法:

 element = page.find('#field') p element.value #=> "5" page.execute_script("arguments[0].setAttribute('value', 'value')", element) p element.value #=> "value" 

从Capybara开始,2.12参数通过Session#execute_script传递,并且也应该与最新的poltergeist和capybara-webkit驱动程序一起使用。

 page.execute_script("arguments[0].setAttribute('value', 'value')", element)