无法使用 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 的引用
我收集了一个数组:
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 的引用