【问题标题】:How to select an inline element using watir in ruby如何在 ruby​​ 中使用 watir 选择内联元素
【发布时间】:2017-01-19 06:27:39
【问题描述】:

我希望在打开网页后点击文本“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

【问题讨论】:

  • 我也尝试过使用inner_htmlinnertext 来识别元素,但还是不行,那会显示nomethoderror

标签: ruby xpath cucumber watir


【解决方案1】:

问题在于链接的文本不是“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 不解释样式,所以只知道文本节点是“热图”。

识别出链接后,点击还是有问题:

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

【讨论】:

  • 谢谢!现在有一个进展,我一直在使用相同的命令,但使用 ng-scope 类,因为它嵌套在 li 中。目前,我发现 chrome 正在启动页面,并关闭页面,没有给我任何错误或输出,也没有点击。
  • 我什至尝试过使用lin = browser.ul(class: 'page-nav').link(text: 'Heatmaps') lin.exist? lin.click 知道为什么吗?
  • 你可能要小心ng-scope这个类。它相当笼统,并不能清楚地表明您在定位什么。听起来代码正在运行,但是由于异步行为,Chrome 会在新页面加载之前继续运行。默认情况下,Chrome 会在脚本结束时关闭。因此,如果您有其他代码跟随,您将看不到页面加载。对于调试,您应该告诉 Chrome 在最后停止关闭(请参阅更新)。
  • 兄弟!你太棒了!非常感谢您提供这些信息。在过去的 2 天里,我一直在忙着这件事,我希望我能来这里问,但仍然值得学习挑战。非常感谢贾斯汀!
【解决方案2】:

您的目标链接没有任何文字。我向 nokogiri 确认 &lt;a&gt; 标签的文本包含子 &lt;span&gt; 标签内的文本,结果证明 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 启动,然后我看到的是登录页面,而不是在您的链接中显示给我的页面。

啊……真是浪费时间。我认为 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 查找具有两个属性的 &lt;a&gt; 标记:

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

它有一个具有三个属性的子 &lt;span&gt;(即直接子):

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

在我以编程方式点击链接后:

target_link.click

Watir 转到下一页。

【讨论】:

  • 感谢您的回复。我明白了这个结构,但我的问题是,element nameclass name 是什么,我必须在我的 ruby​​ 代码中识别那个元素?我已经通过开发人员工具检查选项获得了 html 和结构。但是,当单击复制 xpath 时,我得到的是 //*[@id="main-container"]/ul/li[3]/a/span 不确定,为什么给你一个登录页面,因为当我执行问题中提到的相同代码时,每次都会打开仪表板。
  • 由于 URL 中的空格(对于代码示例),出现登录页面。如果您取出空间,它会按预期导航。
  • 好的!但是我仍然找到了代码,而不是单击我指定的元素。你能做到吗?
  • @MrityunjeyanS,是的——现在我有了正确的网址。我发布了几个解决方案。
  • @7stud 很好,我确实尝试过watir-ng,但我再次觉得我使用了太多模块,因此排除了这种方法。但是,xpath 方法仍然是我做的第一个方法,但不知道代码需要如何完成的格式,以实现点击。我会记下所有这些方法以供将来参考。非常感谢
猜你喜欢
  • 1970-01-01
  • 2018-06-17
  • 1970-01-01
  • 2011-07-04
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多