A Quick Frame-switching Trick
Back in my day (pre-AJAX, etc.)… a common design layout method was to use frames to load navigate around. And there are a lot of sites from that era still operating just fine behind corporate firewalls that haven’t been refreshed.
Nor should the be, really.
But this does pose a bit of a problem, well, more nuisance, when dealing with WebDriver since you have to switch context to a frame before it can be used. This means crawling through frames. A lot. Using Page Objects though, we can hide all of this chaos using something like this towards the top of your PO heirarchy.
<pre lang="python">def switch_to_frame(self, frame_name=None):
if not frame_name:
self.driver.switch_to_default_context()
return
if frame_name == "main_frame":
self.switch_to_default_context()
f = self.driver.find_element(By.CSS_SELECTOR, 'frame[name="main_frame"]')
self.driver.switch_to_frame(f)
elif frame_name == "top_frame":
self.switch_to_frame('main_frame')
f = self.driver.find_element(By.CSS_SELECTOR, 'frame[name="top_frame"]')
self.driver.switch_to_frame(f)
elif frame_name == "search_frame":
self.switch_to_frame('main_frame')
f = self.driver.find_element(By.CSS_SELECTOR, 'frame[name="search_frame"]')
self.driver.switch_to_frame(f)
else:
raise UnknownFrameException('% is not a known frame.' % frame_name)
I’ve had to use this pattern a couple times recently and I employ it even if there is only one frame to switch to in the app since there is only one … until a second appears and its easier to add to an existing method than refactor a whole bunch of page objects.
Its also been pretty bomb-proof on Firefox, but I have one client where the level of nesting is pretty impressive and we can make it hang Chrome predictably. I suspect that is more due to a bug[s] in the chomedriver than anything else since doing the script manually works just fine.