0

只是为了给你一个背景,我正在使用 Ruby 以及 Selenium、Cucumber、Capybara 和 SitePrism 来创建自动化测试。我有一些测试需要检查页面上某个元素的文本,例如:

def get_section_id
  return section.top.course.section_id.text
end

但是,我想在调用.text嵌套course_and_section_id元素之前检查所有父元素是否存在。例如,要检查这个特定元素的文本,我会这样做:

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中是否存在这样的东西?可以这样称呼的东西:has_text?(section.top.course.section_id)也许?

4

3 回答 3

2

听起来您可能想要以下内容。

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

因为reduce没有参数,所以备忘录 e的初始值为section. 如果e变为nilfalse它将保持该值。

于 2018-03-08T19:22:52.120 回答
2

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
于 2018-03-08T21:13:07.753 回答
1

虽然这有点过时了,&.但当它最优雅时不会在这里工作的事实可能会导致这是一个有用的功能

如果您可以在 GH 上通过一个有用的示例页面提出它,那么我们可以考虑引入它

卢克

于 2019-02-22T14:45:47.707 回答