Monday, December 6, 2010

Dealing with frames

So I see a lot of people struggling to figure out frames and selenium.  In my opinion, they are always a pain.  Many times they are dynamic, meaning they have a different id or name every time you run your tests.  Also, having to call selectFrame every few lines of code to go back and forth between functional areas is annoying, not to mention the pain of having to figure out what the frame names are.

I'm here to tell you that for the most part, you don't even need to deal with them.  The IDE throws in TONS of selectFrame commands when it records.  Your tests will work 3x better if you remove them all.  There are two things that selecting a frame really does. 
1) It limits your scope. 
2) It tells selenium what page you using.

1)  For the most part, limiting your scope is BAD.  It makes your tests less stable (if a button moves from one frame to another, you will have to change your tests, which should be avoided whenever possible).   In addition, any frame will AUTOMATICALLY look in all child frames for elements.  So if you select the main window frame, you will be looking through all subframes on the page.  You can do this with selectWindow("null").  Passing "null" tells selenium to look at the root frame, the one that was opened when you created a new browser.

2)  There is only one reason you need to select a frame: When you need to tell selenium what page you're referencing.  This happens for one of two reasons:
   A)  When a selenium command references the page.
   B)  When you have a popup or more than one window. 

A) A typical website has multiple pages, normally to separate navigation and content.  Commands like waitForPageToLoad, and verifyTextPresent use the currently selected page ONLY.  So you will need to selectFrame before you use these types of commands.  If you have the wrong frame selected, they will fail. 

B)  PopUp windows need to be selected to be interacted with.   Since there are typically only 1 popup open at a time, you can look for ANY popup, and avoid trying to determine the ID or name of the popup.  For example, by passing a blank string, selenium will return the first popup it finds.  I use this:
            selenium.WaitForPopUp("");
            selenium.SelectPopUp("");
 
In addition, besides PopUps, sometimes a new browser window or tab is opened with something like target=_blank.  The easiest way to find the window is by looking for the title, with something like this:  selectWindow("title=My Title").   Lastly you can call getAllWindowIds to get an array of ID's, and then call selectWindow with one of the returned values. 

No comments:

Post a Comment