Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 递归检查嵌套元素是否存在_Ruby_Recursion_Cucumber_Capybara_Site Prism - Fatal编程技术网

Ruby 递归检查嵌套元素是否存在

Ruby 递归检查嵌套元素是否存在,ruby,recursion,cucumber,capybara,site-prism,Ruby,Recursion,Cucumber,Capybara,Site Prism,为了给大家一个背景,我使用Ruby与Selenium、Cucumber、Capybara和SitePrism一起创建自动化测试。我有一些测试需要检查页面上某个元素的文本,例如: def get_section_id return section.top.course.section_id.text end 但是,在调用嵌套的course\u和\u section\u id元素上的.text之前,我想检查是否存在所有父元素。例如,要检查此特定元素的文本,我将执行以下操作: if(has_se

为了给大家一个背景,我使用Ruby与Selenium、Cucumber、Capybara和SitePrism一起创建自动化测试。我有一些测试需要检查页面上某个元素的文本,例如:

def get_section_id
  return section.top.course.section_id.text
end
但是,在调用嵌套的
course\u和\u section\u id
元素上的
.text
之前,我想检查是否存在所有父元素。例如,要检查此特定元素的文本,我将执行以下操作:

if(has_section? && section.has_top? && section.top.has_course? && section.top.course.has_section_id?)
  return section.top.course.section_id.text
end

有没有办法递归地检查Ruby中是否存在这样的东西?可以称为这样的东西:
有\u文本?(section.top.course.section\u id)
可能?

听起来您可能需要以下内容

arr = [section, :top, :course, :section_id, :text]
arr.reduce { |e,m| e && e.respond_to?(m) && e.public_send(m) } 

因为
reduce
没有参数,所以备忘
e
的初始值是
部分
。如果
e
变为
nil
false
,它将保持该值。

听起来您可能需要以下内容

arr = [section, :top, :course, :section_id, :text]
arr.reduce { |e,m| e && e.respond_to?(m) && e.public_send(m) } 

因为
reduce
没有参数,所以备忘
e
的初始值是
部分
。如果
e
变为
nil
false
,它将保持该值。

ruby中没有内置任何东西可以做到这一点,因为您调用的方法返回元素或引发异常。如果他们返回元素或nil,那么Cary Swoveland建议使用
&.
就是答案

这里要记住的关键是你实际上要做什么。因为您正在编写自动化测试,所以(很可能)您没有尝试检查元素是否存在(测试应该是可预测的和可重复的,因此您应该知道元素将要存在),而只是等待元素存在后再获取文本。这意味着你真正想要的可能更像

def get_section_id
  wait_until_section_visible
  section.wait_until_top_visible
  section.top.wait_until_course_visible
  section.top.course.wait_until_section_id_visible
  return section.top.course.section_id.text
end
您可以编写一个助手方法来简化这一过程,例如

def get_text_from_nested_element(*args)
  args.reduce(self) do |scope, arg| 
    scope.send("wait_until_#{arg}_visible")
    scope.send(arg)
  end.text
end
可以称之为

def get_section_id
  get_text_from_nested_element(:section, :top, :course, :section_id)
end

ruby没有内置任何东西可以做到这一点,因为您调用的方法返回元素或引发异常。如果他们返回元素或nil,那么Cary Swoveland建议使用
&.
就是答案

这里要记住的关键是你实际上要做什么。因为您正在编写自动化测试,所以(很可能)您没有尝试检查元素是否存在(测试应该是可预测的和可重复的,因此您应该知道元素将要存在),而只是等待元素存在后再获取文本。这意味着你真正想要的可能更像

def get_section_id
  wait_until_section_visible
  section.wait_until_top_visible
  section.top.wait_until_course_visible
  section.top.course.wait_until_section_id_visible
  return section.top.course.section_id.text
end
您可以编写一个助手方法来简化这一过程,例如

def get_text_from_nested_element(*args)
  args.reduce(self) do |scope, arg| 
    scope.send("wait_until_#{arg}_visible")
    scope.send(arg)
  end.text
end
可以称之为

def get_section_id
  get_text_from_nested_element(:section, :top, :course, :section_id)
end

虽然这有点过时,但是当它是最优雅的时候,
&.
在这里不起作用,这可能是一个有用的特性

如果你能在GH上用一个示例页面来提升它,那么我们可以看看如何引入它


Luke

虽然这有点过时,但当它是最优雅的时候,
&.
在这里不起作用,这可能是一个有用的特性

如果你能在GH上用一个示例页面来提升它,那么我们可以看看如何引入它


卢克

谢谢@CarySwoveland,这当然有帮助。然而,我正在寻找一个更通用的解决方案,在这个解决方案中,我可以从
n
嵌套元素的数量中获取文本属性。我不确定这在Ruby中是否可行,但我知道在JS中你可以这样做:如果我的答案是你想要的,请告诉我。如果不是,我(可能还有其他人)不理解这个问题。@CarySwoveland您的建议将不起作用,因为
&.
要求对失败案例的响应为零-元素方法在找不到element@Thomas,谢谢你帮我澄清。我删除了我的评论。根据您对问题的理解,请告诉我修改后的答案是否正确。有人系统地查看了我的个人资料,并对我在Stackoverflow上提供的所有问题和答案进行了否决。管理员们似乎也很满足于让它发生。因此,我想请这篇文章的任何后续访问者真诚地投票,并留下评论,解释你为什么认为这篇文章有用或不有用。我并不是想沉溺于一些可悲的针锋相对,我只是想帮助下一个人。非常感谢。谢谢@CarySwoveland,这确实有帮助。然而,我正在寻找一个更通用的解决方案,在这个解决方案中,我可以从
n
嵌套元素的数量中获取文本属性。我不确定这在Ruby中是否可行,但我知道在JS中你可以这样做:如果我的答案是你想要的,请告诉我。如果不是,我(可能还有其他人)不理解这个问题。@CarySwoveland您的建议将不起作用,因为
&.
要求对失败案例的响应为零-元素方法在找不到element@Thomas,谢谢你帮我澄清。我删除了我的评论。根据您对问题的理解,请告诉我修改后的答案是否正确。有人系统地查看了我的个人资料,并对我在Stackoverflow上提供的所有问题和答案进行了否决。管理员们似乎也很满足于让它发生。因此,我想请这篇文章的任何后续访问者真诚地投票,并留下评论,解释你为什么认为这篇文章有用或不有用。我并不是想沉溺于一些可悲的针锋相对,我只是想帮助下一个人。非常感谢。这仍然存在一个问题,
public\u send(m)
将在元素尚未在页面上可见时引发Capybara::ElementNotFound(选中respond\u to?不会改变这一点)。请看我的答案