Рекурсивно перебирать кадры, чтобы найти элемент в Watir-WebDriver? (Работает в Watir, а не в WebDriver) - PullRequest
0 голосов
/ 17 февраля 2012

Мы написали какой-то Watir, который рекурсивно просматривал бы фреймы страницы, пока не нашел нужный элемент, а затем вернул бы его вам. Не похоже, что мы можем сделать это с Watir-WebDriver.

Что мы привыкли делать:

По сути, мы запустили бы что-то вроде:
findButton(:id, "Login_button")

И мы будем перебирать все фреймы на странице в поисках этой кнопки.

def findButton(desc, b = @browser)
# look for object in main page  
    if b.button(desc).exist?  
        obj = b.button(desc)  
        #return and be done.
    else  
        # look for object in frames  
        count = b.document.frames.length  
        (1..count).each do |i|  
            if b.frame(:index,i).button(desc).exist?  
                obj = b.frame(:index,i).button(desc)  
                break  
            end  
        end  
        if obj == nil  
            (1..count).each do |i|  
                obj = find(desc, b.frame(:index,i))  
                if obj != nil  
                    break  
                end  
            end  
        end  
    end  
    if obj == nil && b == @browser  
        raise "Can't find button with descriptor #{desc}"  
    end  
    obj  
end

Затем мы использовали бы возвращаемый объект элемента:
findButton(:id, "login_button").click, например.

Почему кажется, что мы больше не можем

Итак, теперь мы оцениваем Watir-WebDriver, и элемент документа больше не является частью объекта браузера Watir ... но это нормально, верно? Итак, я пошел и посмотрел кадры, коллекция:

browser = Watir::Browser.new :ie
{......}
browser.frames

Во-первых, Browser.frames требуется около 2-3 секунд, чтобы вернуть любые данные, даже когда есть только один кадр (последняя версия Gem watir-webdriver на сегодняшний день, Ruby 193p0 и IE9). Во-вторых, не похоже, что возвращаемый объект фрейма на самом деле содержит нужный мне элемент доступа. browser.frames[1].button(:id, "Login_Button") возвращает множество ошибок, в зависимости от того, что я ищу.

Почти кажется, что это выставляет ограничение WebDriver, которое Watir-WebDriver надеялся обойти, в этом WebDriver просто не похож на структуру DOM, а элементы не всегда имеют надлежащие "типы", которые знакомы Watir, и фактически к самому DOM.

Кто-то может сказать, что глупо циклически просматривать кадры в поисках элемента, но это всего лишь один из тех случаев, когда лучше иметь такую ​​возможность. Наше приложение использует 3-5 кадров в любой момент времени, и вы не всегда можете предсказать, в каком кадре или в каком порядке может быть элемент.

Я что-то пропустил? Я не понимаю фундаментальный принцип Watir-WebDriver?

1 Ответ

0 голосов
/ 17 февраля 2012

Похоже, нет проблем с API watir-webdriver. Например:

require 'watir-webdriver'

def find_element_in_all_frames browser, &block
  element = block.call browser
  return element if element.exists?
  browser.frames.each do |frame|
    result = find_element_in_all_frames frame, &block
    return result if result
  end
  return nil
end

Watir::always_locate = false
browser = Watir::Browser.start 'http://www.w3schools.com/html/tryit.asp?filename=tryhtml_frame_mix'
element = find_element_in_all_frames(browser) { |b| b.h3(:text => 'Frame A') }
puts element.text
browser.close

работает полностью нормально и возвращает правильный элемент. При работе с Watir :: always_locate, установленным в значение true, это займет около 5 секунд, а при значении false - около 2 секунд.

Вы бы использовали это как:

element = find_element_in_all_frames(browser) { |b| b.button(:id :> "login_button") }
element.click

Я не думаю, что это время неразумно, так как инструмент в основном переключает контексты несколько раз, чтобы найти элемент.

Если вы действительно хотите, чтобы все работало лучше, пришло время переписать ваше приложение без фреймов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...