无法使用 PageObject 和 Watir 访问数组中元素的文本

Can't access text of an element in an array using PageObject and Watir

我收集了一个数组:

array= @browser.ul(:class => 'parent').links

然后我尝试访问数组中特定元素上的文本,像这样遍历数组:

array.each_with_index do |i, index|

如果我这样做:

array[index]

我取回锚元素对象。如果我这样做:

array[index].element

我会取回一个 HTML 元素对象。但是,如果我尝试获取任何特定元素,例如:

array[index].text
array[index].value

然后我收到 "unable to locate element" 错误。

我正在使用 Watir、页面对象和 Ruby。

下面是整个数组迭代的作用域,比较简单:

array= @browser.ul(:class => 'parent').links
array.each_with_index do |i, index|
  if index == array.length-1
    sleep 1
    @browser.button(:text => 'Complete').when_present.click
  else
    sleep 1
    @browser.button(:text => 'Complete').when_present.click
    @browser.a(:text => 'Next').when_present.click
  end
end

我正在尝试添加一个 elsif 来检查 link 的文本,这样如果它在那个特定的 page/link 上,它就会在那个页面上做一些特定的事情。

例如伪代码中:

If array element text = "Instructions", then dont click the complete button, just click next.

我想我愿意以任何方式解决这个问题,让我识别它当前打开的 link,这样我就可以执行设定的操作,但我想抓住当前的文本link 将是最简单的,因此问题。

如何访问此数组中元素的文本或特定属性?

很可能你的元素的 DOM 在一些交互之后发生了变化(比如点击 'Complete' 按钮)。

我的建议是在每次交互后再次查找所有元素。

尝试这样的事情:

array = @browser.ul(:class => 'parent').links
index = 0
array.length.times do
  sleep 1
  if index == array.length-1
    @browser.button(:text => 'Complete').when_present.click
    array = @browser.ul(:class => 'parent').links #We are finding new array after possible change
  elsif  array[index].text == 'Instructions'
    @browser.a(:text => 'Next').when_present.click
  else
    @browser.button(:text => 'Complete').when_present.click
    @browser.a(:text => 'Next').when_present.click
  end
  array = @browser.ul(:class => 'parent').links #And once again
  index = index+1
end

注意:我不能保证上面的代码一定会工作,因为我没有页面可以对其进行测试以确保。如果它不起作用 - 尝试使用 idea

修改它

遍历 link 的列表并提取有关它们的信息相当简单,只要 DOM 不变,就应该可以可靠地工作。一旦您开始单击某些内容,或采取导致部分或全部页面更新的操作,所有赌注都会被取消,因为您的 collection 可能包含对 UI 中已被删除或替换的元素的引用。

您似乎对 .each 迭代器的工作原理也有点困惑。该方法的基本形式 returns 你每个 object 在 collection 中依次进行。 with_index 版本 returns 每个 object 加上它在数组中的索引。在大多数情况下,除非您关心索引是什么,否则您不会使用 with_index 形式。

例如,要遍历 collection 并输出每个 link 的文本,您可以简单地执行

links_list = @browser.ul(:class => 'parent').links
links_list.each do |link|
  puts "the link text is: #{link.text}"
end

如果你想指出每个 link 的索引,那么你可以

links_list = @browser.ul(:class => 'parent').links
links_list.each_with_index do |link, index|
  puts "the text for link number #{index} is: #{link.text}"
end

如果您想按照这样的 link 列表工作,并对它们做一些可能导致页面更新的事情,那么您最好使用其他答案中提出的策略,您根据列表的大小创建一个循环,但 re-fetch 循环内的列表,以便它始终是 'fresh' 并且可能不包含DOM.

中不再存在的对 object 的引用