Skip to content

Commit

Permalink
Merge pull request #407 from divfor/Enhance-Select-Window
Browse files Browse the repository at this point in the history
Enhance select window
  • Loading branch information
zephraph committed Jun 5, 2015
2 parents 9336b8c + 2f6a88a commit 783580b
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 16 deletions.
8 changes: 8 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ Release Notes

1.7 (unreleased)
----------------
- Added keyword 'List Windows' to return a list of all window handles.
[divfor]

- Enabled 'Select Window' to return window handle as well as accept it as locator, and
select new popup window by excluding previous window handles (the strict way) or
by special locator 'new' (the simplified but less strict way).
[divfor]

- Added new keyword 'Wait Until Page Does Not Contain'.
[deiga]

Expand Down
25 changes: 21 additions & 4 deletions src/Selenium2Library/keywords/_browsermanagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from Selenium2Library.utils import BrowserCache
from Selenium2Library.locators import WindowManager
from keywordgroup import KeywordGroup
from selenium.common.exceptions import NoSuchWindowException

ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
FIREFOX_PROFILE_DIR = os.path.join(ROOT_DIR, 'resources', 'firefoxprofile')
Expand Down Expand Up @@ -289,8 +290,11 @@ def select_frame(self, locator):
self._current_browser().switch_to_frame(element)

def select_window(self, locator=None):
"""Selects the window found with `locator` as the context of actions.
"""Selects the window matching locator and return previous window handle.
locator: any of name, title, url, window handle, excluded handle's list, or special words.
return: either current window handle before selecting, or None if no current window.
If the window is found, all subsequent commands use that window, until
this keyword is used again. If the window is not found, this keyword fails.
Expand All @@ -299,7 +303,11 @@ def select_window(self, locator=None):
javascript name of the window. If multiple windows with
same identifier are found, the first one is selected.
Special locator `main` (default) can be used to select the main window.
There are some special locators for searching target window:
string 'main' (default): select the main window;
string 'self': only return current window handle;
string 'new': select the last-indexed window assuming it is the newest opened window
window list: select the first window not in given list (See 'List Windows' to get the list)
It is also possible to specify the approach Selenium2Library should take
to find a window by specifying a locator strategy:
Expand All @@ -315,7 +323,16 @@ def select_window(self, locator=None):
| Title Should Be | Popup Title |
| Select Window | | | # Chooses the main window again |
"""
self._window_manager.select(self._current_browser(), locator)
try:
return self._current_browser().get_current_window_handle()
except NoSuchWindowException:
pass
finally:
self._window_manager.select(self._current_browser(), locator)

def list_windows(self):
"""Return all current window handles as a list"""
return self._current_browser().get_window_handles()

def unselect_frame(self):
"""Sets the top frame as the current frame."""
Expand Down
53 changes: 41 additions & 12 deletions src/Selenium2Library/locators/windowmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,15 @@ def get_window_titles(self, browser):

def select(self, browser, locator):
assert browser is not None

if locator is not None:
if isinstance(locator, list):
self._select_by_excludes(browser, locator)
return
if locator.lower() == "self" or locator.lower() == "current":
return
if locator.lower() == "new" or locator.lower() == "popup":
self._select_by_last_index(browser)
return
(prefix, criteria) = self._parse_locator(locator)
strategy = self._strategies.get(prefix)
if strategy is None:
Expand Down Expand Up @@ -53,21 +61,42 @@ def _select_by_url(self, browser, criteria):

def _select_by_default(self, browser, criteria):
if criteria is None or len(criteria) == 0 or criteria.lower() == "null":
browser.switch_to_window('')
handles = browser.get_window_handles()
browser.switch_to_window(handles[0])
return

try:
self._select_by_name(browser, criteria)
return
except ValueError: pass

starting_handle = browser.get_current_window_handle()
except NoSuchWindowException:
starting_handle = None
for handle in browser.get_window_handles():
browser.switch_to_window(handle)
if criteria == handle:
return
for item in browser.get_current_window_info()[2:4]:
if item.strip().lower() == criteria.lower():
return
if starting_handle:
browser.switch_to_window(starting_handle)
raise ValueError("Unable to locate window with handle or name or title or URL '" + criteria + "'")

def _select_by_last_index(self, browser):
handles = browser.get_window_handles()
try:
self._select_by_title(browser, criteria)
return
except ValueError: pass

raise ValueError("Unable to locate window with name or title '" + criteria + "'")
if handles[-1] == browser.get_current_window_handle():
raise AssertionError("No new window at last index. Please use '@{ex}= | List Windows' + new window trigger + 'Select Window | ${ex}' to find it.")
except IndexError:
raise AssertionError("No window found")
except NoSuchWindowException:
raise AssertionError("Currently no focus window. where are you making a popup window?")
browser.switch_to_window(handles[-1])

def _select_by_excludes(self, browser, excludes):
for handle in browser.get_window_handles():
if handle not in excludes:
browser.switch_to_window(handle)
return
raise ValueError("Unable to locate new window")

# Private

def _parse_locator(self, locator):
Expand Down
34 changes: 34 additions & 0 deletions test/acceptance/windows.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,40 @@ Get Window Titles After Close Window
Close Window
${titles}= Get Window Titles

Select Window By Handle
Cannot Be Executed in IE
Click Link my popup
${parent}= Select Window Original
Title Should Be Original
${child}= Select Window ${parent}
Title Should Be Click link to show a popup window
Select Window ${child}
Close Window
${FromWindow}= Select Window ${parent}
Title Should Be Click link to show a popup window
Should Be True ${FromWindow} == None

Select Popup Window By Excluded List
Cannot Be Executed in IE
@{excluded_handle_list}= List Windows
Click Link my popup
${parent}= Select Window ${excluded_handle_list}
Title Should Be Original
Close Window
Select Window ${parent}
Title Should Be Click link to show a popup window

Select Window By Special Locator
Cannot Be Executed in IE
${start}= Select Window self
Click Link my popup
${parent}= Select Window new
Title Should Be Original
Should Be True '${start}' == '${parent}'
Close Window
Select Window main
Title Should Be Click link to show a popup window

*Keywords*
Open Popup Window, Select It And Verify
[Arguments] ${window_id}
Expand Down

0 comments on commit 783580b

Please sign in to comment.