Ruby 中无法使用 Watir 为表单元素设置文本
Cannot set text for form element using Watir in Ruby
在成功编写了一些代码以使用 mechanize 与我的笔记本电脑上托管的小型网站进行交互后,我才刚刚开始修补 watir。但我正在努力让 watir 工作。
require 'watir-webdriver'
b = Watir::Browser.new :firefox
b.goto('https://dev.mitdev.org.uk/login')
body = b.body
body.forms.each do |f|
p f.name
f.text_field(:name, 'IDToken1').wait_until_present(5).set('test')
end
我发现打印 f.name 有效,我看到登录表单被称为 "Login"。但是,如果我添加行来设置文本,我会超时。
查看 FF 我可以看到表单已经呈现,所以我很困惑为什么我似乎无法与之交互。
我尝试过其他设置值的方法,例如:
body.text_field(:name => 'IDToken2').wait_until_present(5).set('Password')
但无济于事。
在线教程使这看起来如此简单,以至于我怀疑我只是在犯一个菜鸟错误,而且我太累了,看不到它。
感谢您的回复。至于例外,我看到它不会呈现,除非我等待并超时。如果有办法强制它告诉我我的语法有误,我将不胜感激知道该怎么做。
表格如下:
<form id="Login" name="Login" action="/login" method="post">
<div class="sign-in">
<fieldset>
<legend class="form-title heading-large">Sign in</legend>
<div class="form-group">
<label class="form-label" for="IDToken1">
User ID
</label>
<input class="form-control" type="text" name="IDToken1" id="IDToken1" value="" maxlength="50" tabindex="1" />
</div>
<div class="form-group">
<label class="form-label" for="IDToken2">
Password
</label>
<input type="hidden" id="goto" name="goto" value=""/>
<input class="form-control" type="password" name="IDToken2" id="IDToken2" value="" maxlength="100" autocomplete="off" tabindex="2" />
<input type="hidden" name="_csrf_token" value=" deleted ">
</div>
</fieldset>
<nav class="module-content-navigation">
<input name="Login.Submit" type="submit" class="button" value="Sign in" tabindex="3" />
<ul class="content-navigation__secondary">
<li>
<a href="/forgotten-password" tabindex="4">Forgotten password</a>
</li>
</ul>
</nav>
</div>
<input name="IDButton" type="hidden" style="display: none;">
</form>
我在网上发现了一个很好的教程,向我展示了如何使用散列来进一步限定元素的地址,但我仍然无法使用这种形式:
b = Watir::Browser.new
b.goto('https://dev.mitdev.org.uk/login')
b.wait(3)
b.text_field(:class => 'form-control',
:type => 'text',
:name => 'IDToken1',
:id => 'IDToken1').set('test')
我仍然收到超时或无需等待的异常:
[remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:10092:in `fxdriver.preconditions.visible': Element is not currently visible and so may not be interacted with (Selenium::WebDriver::Error::ElementNotVisibleError)
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:12644:in `DelayedCommand.prototype.checkPreconditions_'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:12661:in `DelayedCommand.prototype.executeInternal_/h'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:12666:in `DelayedCommand.prototype.executeInternal_'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:12608:in `DelayedCommand.prototype.execute/<'
再归零一点,这将打印文本字段的 ID:
p b.text_field(:type => 'text',
:name => 'IDToken1',
:id => 'IDToken1').id
但这无法设置文本:
b.text_field(:type => 'text',
:name => 'IDToken1',
:id => 'IDToken1').when_present(5).set('test')
这看起来越来越像是与页面有关,而不是我对 water 语法的掌握:
p b.text_field(:name => /Token1/).name
p b.text_field(:type => 'text',
:name => 'IDToken1',
:id => 'IDToken1').id
p b.text_field(:name => /Token1/).exists?
b.text_field(:name => /Token1/).double_click
b.text_field(:name => /Token1/).set 'test'
给我这个显示元素清楚存在的输出,但我看到这个奇怪的 "scroll" 双击堆栈跟踪。
"IDToken1"
"IDToken1"
true
[remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-2812-w3soqr/extensions/fxdriver@googlecode.com/components/driver-component.js:11072:in `FirefoxDriver.prototype.mouseMoveTo': Offset within element cannot be scrolled into view: (5, 17.5): [object HTMLInputElement] (Selenium::WebDriver::Error::MoveTargetOutOfBoundsError)
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-2812-w3soqr/extensions/fxdriver@googlecode.com/components/command-processor.js:12661:in `DelayedCommand.prototype.executeInternal_/h'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-2812-w3soqr/extensions/fxdriver@googlecode.com/components/command-processor.js:12666:in `DelayedCommand.prototype.executeInternal_'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-2812-w3soqr/extensions/fxdriver@googlecode.com/components/command-processor.js:12608:in `DelayedCommand.prototype.execute/<'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/response.rb:70:in `assert_ok'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/response.rb:34:in `initialize'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/http/common.rb:78:in `new'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/http/common.rb:78:in `create_response'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/http/default.rb:90:in `request'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/http/common.rb:59:in `call'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/bridge.rb:649:in `raw_execute'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/bridge.rb:627:in `execute'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/bridge.rb:419:in `mouseMoveTo'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/mouse.rb:71:in `move_to'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/mouse.rb:81:in `move_if_needed'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/mouse.rb:40:in `double_click'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/action_builder.rb:363:in `block in perform'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/action_builder.rb:362:in `each'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/action_builder.rb:362:in `perform'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/watir-webdriver-0.9.1/lib/watir-webdriver/elements/element.rb:147:in `block in double_click'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/watir-webdriver-0.9.1/lib/watir-webdriver/elements/element.rb:598:in `element_call'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/watir-webdriver-0.9.1/lib/watir-webdriver/elements/element.rb:147:in `double_click'
感觉离问题越来越近了:
p b.text_field(:name => /Token1/).exists?
p b.text_field(:id => /Token1/).visible?
p b.text_field(:name => /Token1/).present?
这对可见和存在显示假,但对存在显示真。
为什么这个元素对 watir 不可见而对我可见是我必须回答的下一个问题...
我试过你的脚本。它在我这边工作
require 'watir-webdriver'
b = Watir::Browser.new :chrome
b.goto 'file:///D:/WORKSPACE/Learning/demo1.html'
b.text_field(:name, 'IDToken1').when_present(5).set('test')
但不适用于表单和 body。
哇!终于...
所以 Selenium java 代码给了我正确的方向,我设法填写了这样的表格:
b.element(:xpath => "//*[contains(@id,'_tid1')]").send_keys('user')
b.element(:xpath => "//*[contains(@id,'_tid2')]").send_keys('password')
b.element(:name => "Login.Submit").click
p b.text_field(:name => /Token1/).exists?
p b.text_field(:id => /Token1/).visible?
这两行对我有帮助。谢谢
在成功编写了一些代码以使用 mechanize 与我的笔记本电脑上托管的小型网站进行交互后,我才刚刚开始修补 watir。但我正在努力让 watir 工作。
require 'watir-webdriver'
b = Watir::Browser.new :firefox
b.goto('https://dev.mitdev.org.uk/login')
body = b.body
body.forms.each do |f|
p f.name
f.text_field(:name, 'IDToken1').wait_until_present(5).set('test')
end
我发现打印 f.name 有效,我看到登录表单被称为 "Login"。但是,如果我添加行来设置文本,我会超时。
查看 FF 我可以看到表单已经呈现,所以我很困惑为什么我似乎无法与之交互。
我尝试过其他设置值的方法,例如:
body.text_field(:name => 'IDToken2').wait_until_present(5).set('Password')
但无济于事。
在线教程使这看起来如此简单,以至于我怀疑我只是在犯一个菜鸟错误,而且我太累了,看不到它。
感谢您的回复。至于例外,我看到它不会呈现,除非我等待并超时。如果有办法强制它告诉我我的语法有误,我将不胜感激知道该怎么做。
表格如下:
<form id="Login" name="Login" action="/login" method="post">
<div class="sign-in">
<fieldset>
<legend class="form-title heading-large">Sign in</legend>
<div class="form-group">
<label class="form-label" for="IDToken1">
User ID
</label>
<input class="form-control" type="text" name="IDToken1" id="IDToken1" value="" maxlength="50" tabindex="1" />
</div>
<div class="form-group">
<label class="form-label" for="IDToken2">
Password
</label>
<input type="hidden" id="goto" name="goto" value=""/>
<input class="form-control" type="password" name="IDToken2" id="IDToken2" value="" maxlength="100" autocomplete="off" tabindex="2" />
<input type="hidden" name="_csrf_token" value=" deleted ">
</div>
</fieldset>
<nav class="module-content-navigation">
<input name="Login.Submit" type="submit" class="button" value="Sign in" tabindex="3" />
<ul class="content-navigation__secondary">
<li>
<a href="/forgotten-password" tabindex="4">Forgotten password</a>
</li>
</ul>
</nav>
</div>
<input name="IDButton" type="hidden" style="display: none;">
</form>
我在网上发现了一个很好的教程,向我展示了如何使用散列来进一步限定元素的地址,但我仍然无法使用这种形式:
b = Watir::Browser.new
b.goto('https://dev.mitdev.org.uk/login')
b.wait(3)
b.text_field(:class => 'form-control',
:type => 'text',
:name => 'IDToken1',
:id => 'IDToken1').set('test')
我仍然收到超时或无需等待的异常:
[remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:10092:in `fxdriver.preconditions.visible': Element is not currently visible and so may not be interacted with (Selenium::WebDriver::Error::ElementNotVisibleError)
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:12644:in `DelayedCommand.prototype.checkPreconditions_'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:12661:in `DelayedCommand.prototype.executeInternal_/h'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:12666:in `DelayedCommand.prototype.executeInternal_'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-12708-sjjxdp/extensions/fxdriver@googlecode.com/components/command-processor.js:12608:in `DelayedCommand.prototype.execute/<'
再归零一点,这将打印文本字段的 ID:
p b.text_field(:type => 'text',
:name => 'IDToken1',
:id => 'IDToken1').id
但这无法设置文本:
b.text_field(:type => 'text',
:name => 'IDToken1',
:id => 'IDToken1').when_present(5).set('test')
这看起来越来越像是与页面有关,而不是我对 water 语法的掌握:
p b.text_field(:name => /Token1/).name
p b.text_field(:type => 'text',
:name => 'IDToken1',
:id => 'IDToken1').id
p b.text_field(:name => /Token1/).exists?
b.text_field(:name => /Token1/).double_click
b.text_field(:name => /Token1/).set 'test'
给我这个显示元素清楚存在的输出,但我看到这个奇怪的 "scroll" 双击堆栈跟踪。
"IDToken1"
"IDToken1"
true
[remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-2812-w3soqr/extensions/fxdriver@googlecode.com/components/driver-component.js:11072:in `FirefoxDriver.prototype.mouseMoveTo': Offset within element cannot be scrolled into view: (5, 17.5): [object HTMLInputElement] (Selenium::WebDriver::Error::MoveTargetOutOfBoundsError)
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-2812-w3soqr/extensions/fxdriver@googlecode.com/components/command-processor.js:12661:in `DelayedCommand.prototype.executeInternal_/h'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-2812-w3soqr/extensions/fxdriver@googlecode.com/components/command-processor.js:12666:in `DelayedCommand.prototype.executeInternal_'
from [remote server] file:///var/folders/f4/6vwp2t_d75v803226gs84v100000gp/T/webdriver-profile20160612-2812-w3soqr/extensions/fxdriver@googlecode.com/components/command-processor.js:12608:in `DelayedCommand.prototype.execute/<'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/response.rb:70:in `assert_ok'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/response.rb:34:in `initialize'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/http/common.rb:78:in `new'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/http/common.rb:78:in `create_response'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/http/default.rb:90:in `request'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/http/common.rb:59:in `call'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/bridge.rb:649:in `raw_execute'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/bridge.rb:627:in `execute'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/remote/bridge.rb:419:in `mouseMoveTo'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/mouse.rb:71:in `move_to'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/mouse.rb:81:in `move_if_needed'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/mouse.rb:40:in `double_click'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/action_builder.rb:363:in `block in perform'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/action_builder.rb:362:in `each'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/selenium-webdriver-2.53.1/lib/selenium/webdriver/common/action_builder.rb:362:in `perform'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/watir-webdriver-0.9.1/lib/watir-webdriver/elements/element.rb:147:in `block in double_click'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/watir-webdriver-0.9.1/lib/watir-webdriver/elements/element.rb:598:in `element_call'
from /Users/atkinsb/.rvm/gems/ruby-2.2.1/gems/watir-webdriver-0.9.1/lib/watir-webdriver/elements/element.rb:147:in `double_click'
感觉离问题越来越近了:
p b.text_field(:name => /Token1/).exists?
p b.text_field(:id => /Token1/).visible?
p b.text_field(:name => /Token1/).present?
这对可见和存在显示假,但对存在显示真。
为什么这个元素对 watir 不可见而对我可见是我必须回答的下一个问题...
我试过你的脚本。它在我这边工作
require 'watir-webdriver'
b = Watir::Browser.new :chrome
b.goto 'file:///D:/WORKSPACE/Learning/demo1.html'
b.text_field(:name, 'IDToken1').when_present(5).set('test')
但不适用于表单和 body。
哇!终于...
所以 Selenium java 代码给了我正确的方向,我设法填写了这样的表格:
b.element(:xpath => "//*[contains(@id,'_tid1')]").send_keys('user')
b.element(:xpath => "//*[contains(@id,'_tid2')]").send_keys('password')
b.element(:name => "Login.Submit").click
p b.text_field(:name => /Token1/).exists?
p b.text_field(:id => /Token1/).visible?
这两行对我有帮助。谢谢