1
votes

Helo, guys! We're using watir-webdriver with cucumber and page-object gem provided by Cheezy. Our project using ExtJS so there is a lot of ajax. In one of ours scenarios there is a step when user clicks on button(in iframe, let's say iframe1) and system populates the same page in different iframe(let's say frame2), in our PageObject class we have something like this:

in_iframe(:width=>"100%") do |frame| //some elements end

So, the questions is there a way to instantiate new PageObject with the concrete iframe or to change iframe for currently used PageObject?

Will be grateful for any help.

1
Can you clarify what you mean by "concrete iframe" and why you would need to "change iframe"? Based on the problem description, it just sounds like you have two elements in two different iframes, which would just mean having two in_iframe accessors?Justin Ko
Sorry, I'll try to decribe my problem more specifically. From start my steps are working with just one iframe - iframe1, and then during test running driver presses the button that creates iframe2, all further steps need to be done in iframe2, but driver continues to interact with elements in iframe1(Cause iframe1 and iframe2 have the identical elements). So I would like to do something like this: @current_page.frame = browser.iframes(:width=>100%)[1] to change current working iframe for driver.Smooyk
I had a similar problem and ultimately had to abandon Cheezy's gem in favor of "rolling my own" as described by Alister Scott here: watirmelon.com/2012/06/04/roll-your-own-page-objectsAbe Heward
The details of my own solution can be found on the first 10 lines of this file: github.com/aheward/kuality-coeus/blob/master/lib/kuality-coeus/…Abe Heward
Thank you! I'll give it a try.Smooyk

1 Answers

3
votes

I am envisioning your page being like:

<html>
  <body>
    <iframe id="iframe1" src="test.htm" width="100%"></iframe>
    <iframe id="iframe2" src="test.htm" width="100%"></iframe>
  </body>
</html>

Where the test.htm is:

<html>
  <body>
    <input id="user_login" type="text">
  </body>
</html>

In other words, there are two frames with the same text field element.

This seems a bit hacky, but one approach you could take would be to define the various element methods. When you switch frames, you can redefine the methods to use the locator for the second frame. The page object would be:

class MyPage
  include PageObject 

  def self.setup(iframe_locator)
    in_iframe(iframe_locator) do |login_iframe|
      text_field(:email_field, :id => 'user_login', frame: login_iframe)
    end 
  end
  setup(:width => "100%")

  def frame=(iframe_locator)
    eval %Q{
      class << self
        setup(#{iframe_locator})
      end
    }
  end
end

The usage would be:

page = MyPage.new(browser)

# Input the text field in the first frame
page.email_field = 'hi'

# Redefine the frame locator to be the second frame
page.frame={:index=> 1, :width=>'100%'}

# Input the text field in the second frame
page.email_field = 'bye'