Ruby:如果满足最终条件,则使用不同的代码重新运行循环

时间:2014-09-21 20:54:05

标签: ruby loops xpath while-loop selenium-webdriver

我有这个程序,我写了自动化我在工作中的任务。这是我第一次尝试编程,没有经验或训练,所以原谅任何愚蠢的错误。 (我删除了网站和我的用户名/密码)

require "rubygems"
require "selenium-webdriver"
require "nokogiri"
browser = Selenium::WebDriver.for :firefox
wait = Selenium::WebDriver::Wait.new(:timeout => 15)
#loads to unassigned results page
browser.get "-----------------"
p browser.title
browser.find_element(name: "user[username]").send_keys "--------"
browser.find_element(name: "user[password]").send_keys "--------"
browser.find_element(name: "commit").click
p browser.title
browser.find_element(class_name: "status_notification").click
begin
    browser.find_element(:xpath => ".//*[@id='sub_nav_content']/table/tbody/tr[2]/td[3]/a").click
    table = wait.until {
        element = browser.find_element(id: "possible_matched")
        element if element.displayed?
    }
    if table 
        puts "Table Found"
    else 
        puts "Table Error"
    end
    #creates an 2D array containing patient name, admit date and prints to screen
    names = browser.find_elements(:xpath => ".//*[@id='possible_matched']/table/tbody/tr/td[1]")
    name_array = []
    names.each { |name| name_array << name.text}
    admits = browser.find_elements(:xpath => ".//*[@id='possible_matched']/table/tbody/tr/td[5]")
    admit_array = []
    admits.each { |date| admit_array << date.text }
    name_admit_array = name_array.zip(admit_array)
    name_admit_array.each do |name, date|
        puts "#{name}: #{date}"
    end
    #finds the location of the sub-array containing patient name and collection associated admit date
    patient_name = browser.find_element(:xpath => ".//*[@id='dialog-modal-cancel-hl7-preview']/table/tbody/tr[2]/td[1]").text
    collected_date = browser.find_element(:xpath => ".//*[@id='dialog-modal-cancel-hl7-preview']/table/tbody/tr[2]/td[4]").text
    mo, da, yr = collected_date.split('/').map(&:to_i)
    cd = [yr, mo, da]
    bl = name_admit_array.each_with_index.select { |(name, date), i|
        m, d, y = date.split('/').map(&:to_i)
        dt = [y, m, d]
        name.downcase == patient_name.downcase and (dt <=> cd)<0
    }.map {|x, i| i }
    # presses the button associated with the correct sub-array
    blf = name_admit_array.values_at(*bl)
    if bl.any?
        bf = blf.rindex(blf.max) + 2
        browser.find_element(:xpath => ".//*[@id='possible_matched']/table/tbody/tr[#{bf}]/td[6]/div/a").click
    else
        browser.find_element(:xpath => "html/body/div[6]/div[1]/a/span").click
    end
end while bl.any?
puts "no name :("

因此它会运行循环,直到数组bl中找不到任何内容。我想要做的是再次运行此循环,但链接列表中的下一个链接。因此,在循环开始时,它应该browser.find_element(:xpath => ".//*[@id='sub_nav_content']/table/tbody/tr[3]/td[3]/a").click而不是browser.find_element(:xpath => ".//*[@id='sub_nav_content']/table/tbody/tr[2]/td[3]/a").click。然后应该以相同的方式运行循环的其余部分。我想让它在每次循环进入tr[]时继续递增br.any? => false

1 个答案:

答案 0 :(得分:0)

您可以创建一个xpath的数组,并为each运行此代码:

[
    ".//*[@id='sub_nav_content']/table/tbody/tr[3]/td[3]/a",
    ".//*[@id='sub_nav_content']/table/tbody/tr[2]/td[3]/a"
].each do |path|
    begin
        browser.find_element(:xpath => path).click
        // etc....

    end while bl.any?
end

我认为需要进行更多更改才能根据您的需求调整代码的可重用性