如何在ruby中使用watir选择内联元素

时间:2017-01-19 06:27:40

标签: ruby xpath cucumber watir

我想要文字" HEATMAPS"在打开网页后单击。我尝试了多种点击方法,包括识别为超链接,文本,使用xpath等。它们都没有工作。我觉得,我要么误解链接,要么是超链接或选择错误的xpath。

Link of the web page

PFB下面的代码

 require 'watir-webdriver'
 require 'watir-ng'
 WatirNg.patch!
 WatirNg.register(:ng_scope).patch!
 browser = Watir::Browser.new
 browser.goto 'http://app.vwo.com/#/campaign/108/summary?   token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0='

 lin = browser.link :text=> 'HEATMAPS'
 lin.exist?
 lin.click

有人可以指导我这个,关于如何与文本" HEATMAPS"在页面中点击。

我得到的错误:

`This code has slept for the duration of the default timeout waiting for an Element to exist. If the test is still passing, consider using Element#exists? instead of rescuing UnknownObjectException
C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:507:in `rescue in wait_for_exists': timed out after 30 seconds, waiting for {:text=>"HEATMAPS", :tag_name=>"a"} to be located (Watir::Exception::UnknownObjectException)
        from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:497:in `wait_for_exists'
        from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:515:in `wait_for_present'
        from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:533:in `wait_for_enabled'
        from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:656:in `element_call'
        from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:114:in `click'
        from C:/Users/Mrityunjeyan/Documents/GitHub/Simpleprograms/webautomation.rb:10:in `<main>'`

这会显示inner_html文本,但仍然不会点击

lin = browser.span(:class => 'ng-scope').inner_html puts lin

2 个答案:

答案 0 :(得分:3)

问题是链接的文本不是“HEATMAPS”。它实际上是“Heatmaps”。文本定位器区分大小写,这意味着您需要:

lin = browser.link :text=> 'Heatmaps'

如果您检查HTML,可以看到这一点:

<a ui-sref="campaign.heatmap-clickmap" href="#/analyze/analysis/108/heatmaps?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D">
  <!-- boIf: isAnalyticsCampaign -->
  <span bo-if="isAnalyticsCampaign" class="ng-scope">Heatmaps</span>
  <!-- boIf: !isAnalyticsCampaign -->
</a>

由于造型,它看起来只有“HEATMAPS”。其中一种样式包括text-transform: uppercase;,它可以在视觉上对文本进行大写。 Watir不解释样式,因此只知道文本节点是“Heatmaps”。

确定链接后,点击仍有问题:

lin.click
#=> Selenium::WebDriver::Error::UnknownError:
#=> unknown error: Element <a ui-sref="analyze.heatmaps" ng-class="{selected: (locationContains('analyze', 'heatmap') &amp;&amp; !locationContains('analyze', '/analysis') &amp;&amp; state.current.name !== 'campaign.heatmap-clickmap') || (isAnalyzeHeatmapEnabled &amp;&amp; (isAnalyzeDeprecatedHeatmapView || locationContains('analyze', '/analysis', 'heatmaps')) )}" data-qa="nav-main-analyze-heatmap" href="#/analyze/heatmap">...</a>
#=> is not clickable at point (90, 121).
#=> Other element would receive the click: <div ng-show="!isCROSetupView" class="">...</div>

找到的链接实际上是左侧菜单中的链接,它被禁用,而不是顶级菜单。您需要将链接定位器的范围仅限于顶部菜单。使用父ul元素似乎就足够了:

lin = browser.ul(class: 'page-nav').link(text: 'Heatmaps')
lin.click

要查看click完成情况,您可能希望告知Chrome不要在脚本末尾关闭。这可以通过使用以下选项打开浏览器来完成:

caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {'detach' => true})
browser = Watir::Browser.new :chrome, desired_capabilities: caps

答案 1 :(得分:1)

您的目标链接没有任何文字。我与nokogiri确认<a>标记的文字包含子<span>标记内的文字,结果表明Watir的工作方式相同。

如果您使用Chrome浏览器,则可以选择:

View > Developer > Developer tools

然后您可以在页面上选择一个元素,并突出显示html中的相应部分。这是html的样子:

<a ui-sref="campaign.heatmap-clickmap" 
   href="#/analyze/analysis/108/heatmaps?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D"> 
<!-- boIf: isAnalyticsCampaign -->

<span bo-if="isAnalyticsCampaign" class="ng-scope">Heatmaps</span> 

<!-- boIf: !isAnalyticsCampaign --> </a>

基本结构是:

<a><span>Heatmaps</span></a>

Chrome甚至还有一项功能,您可以右键单击某个元素并获取其xpath,您可以将其用于Watir。

但是,当我执行我的程序转到该页面时,我会看到Chrome启动,然后我会看到一个登录页面,而不是通过链接呈现给我的页面。

Arghhh ......多么浪费时间。我认为Watir必须被打破。使用正确的URL,我可以使用几种不同的技术获得链接:

1)

require 'watir'
require 'watir-ng'   #<=NOTE THIS

WatirNg.register(:'bo_if').patch!  #<= NOTE THIS

br = Watir::Browser.new :chrome
br.goto 'http://app.vwo.com/#/analyze/analysis/108/summary?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'

target_link = br.span(
  class: 'ng-scope',
  'bo_if': 'isAnalyticsCampaign', 
).parent  #<= NOTE THIS

puts target_link.text  #HEATMAPS
puts target_link.href  #http://app.vwo.com/#/analyze/analysis/1.....

2)

require 'watir'
require 'watir-ng'  #<=NOTE THIS

WatirNg.register(:ui_sref).patch!  #<=NOTE THIS

br = Watir::Browser.new :chrome
br.goto 'http://app.vwo.com/#/analyze/analysis/108/summary?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'

target_link = br.link(
  ui_sref: 'campaign.heatmap-clickmap',
  href: '#/analyze/analysis/108/heatmaps?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'
)

puts target_link.text   #HEATMAPS
puts target_link.href   #http://app.vwo.com/#/analyze/analysis/108...

3)右键点击Chrome中的链接获取xpath:

require 'watir'

br = Watir::Browser.new :chrome
br.goto 'http://app.vwo.com/#/analyze/analysis/108/summary?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'

target_link = br.link(
  xpath: '//*[@id="main-container"]/ul/li[3]/a'
)
puts target_link.text  #HEATMAPS
puts target_link.href  #http://app.vwo.com/#/analyze/analysis/108....

xpath可以处理任何标记或属性名称,与Watir不同,因此在这方面它似乎是一个很好的工具。

4)不太脆弱的xpath:

require 'watir'

br = Watir::Browser.new :chrome
br.goto 'http://app.vwo.com/#/analyze/analysis/108/summary?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'


a_href = "#/analyze/analysis/108/heatmaps?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D"

target_link = br.link(
  xpath: %Q{ //a[@href="#{a_href}"] } +
               '[@ui-sref="campaign.heatmap-clickmap"]' +
               '[child::span[@class="ng-scope"][@bo-if="isAnalyticsCampaign"][text()="Heatmaps"]]' 
)

xpath会查找包含两个属性的<a>标记:

//a[@href="blah"][@ui-sref="bleh"]

有一个孩子<span>(即直接孩子),有三个属性:

[child::span[@class="blih"][@bo-if="bloh"][text()="Heatmaps"]]

以编程方式点击链接后:

target_link.click

Watir进入下一页。