-
Notifications
You must be signed in to change notification settings - Fork 220
Frames and iFrames
The page-object
gem provides a way to declare items are within frames or iframes. In fact, these frames can be nested infinitely. Let's look at a simple case.
class RegistrationPage
include PageObject
in_frame(:id => 'left-frame') do |frame|
text_field(:address, :id => 'address_id', :frame => frame)
end
end
As you see in this example, we are declaring that the text field resides within a frame with an id of 'left-frame'. You can identify frames or iframes by :id
, :name
, or :index
. Also note that a frame
variable is passed into the block and that it is added as an additional identifier in the call to text_field
.
If you have an iframe you simply use the in_iframe
call instead of the in_frame
call.
Let's take another look at how the code would look if we have nested frames. We'll take the same example from above except we assume there is another nested frame.
class RegistrationPage
include PageObject
in_frame(:id => 'left-frame') do |outer_frame|
in_frame({:id => 'left-top-frame'}, outer_frame) do |inner_frame|
text_field(:address, :id => 'address_id', :frame => inner_frame)
end
end
end
Notice that we had to pass the frame
from the outer frame to the second call to in_frame
. This also forced us to place {} around the identifier in this call.
After the declaration of the nested frames you can use the elements directly. For example, to set the value in the address
field you would have to do this:
@page.address = 'Some Address'
When describing nested frames in this manner, you have the ability to declare elements in each frame without affecting the scope of elements in other frames. This means that you can safely and concisely declare elements in any level of nested frames. Let's modify the previous example yet again -- this time, let's assume there is another text field in the top-level outer_frame
:
class RegistrationPage
include PageObject
in_frame(:id => 'left-frame') do |outer_frame|
text_field(:username, :id => 'username_id', :frame => outer_frame)
in_frame({:id => 'left-top-frame'}, outer_frame) do |inner_frame|
text_field(:address, :id => 'address_id', :frame => inner_frame)
end
end
end
This behaves as you would expect: the RegistrationPage
should now be able to use the @page.username
element that is in the left-frame
in addition to the @page.address
element located within the left-top-frame
. This feature of the in_frame
and in_iframe
methods affords you the power to describe any arbitrary nested frame/iframe structure.