Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c9d34be
Added Keywords "Get Browser Ids" and "Get Browser aliases" to get a l…
Snooz82 Jul 8, 2019
a01d4e9
Added "Switch Window" as replacement for select window.
Snooz82 Jul 8, 2019
171f45a
Added Option "browser" to "Switch Window" (only CURRENT or <id or ali…
Snooz82 Jul 8, 2019
9c13ba6
Updated Doc-Strings.
Snooz82 Jul 9, 2019
fca3b88
Added example for Browser and window handling in Doc
Snooz82 Jul 10, 2019
1275d5b
Select Window deprecation warning to silent.
Snooz82 Jul 10, 2019
7b209bd
more improvements in documentation on window related keywords.
Snooz82 Jul 10, 2019
7bd1b06
small improvement to Get Browser Aliases documentation.
Snooz82 Jul 10, 2019
efa0c5c
Moved window related keywords back to BrowserManagementKeywords to ov…
Snooz82 Jul 15, 2019
c635d48
Fixed ordering get_session_id
Snooz82 Jul 15, 2019
cfb63b4
Fixed Unittest to 173 Keywords instead of 170.
Snooz82 Jul 15, 2019
0230744
Set encoding to UTF-8 to be able to use all characters in Docstring
Snooz82 Jul 15, 2019
31bf5ea
Fixed Issues with aTest
Snooz82 Jul 15, 2019
338170d
Added acceptance tests for edited Window- and Browser-Information han…
Jul 16, 2019
4bb064e
Get rid of the for loop in atest because of Robot Framework 3.0.4 in …
Snooz82 Jul 16, 2019
d12a0b3
Cleaned up all Lines that are only made out of whitespaces.
Snooz82 Jul 22, 2019
a2af1cd
fixed not needed parenthesis
Snooz82 Jul 22, 2019
ce19471
Updating Doc. implementing review comments.
Snooz82 Jul 28, 2019
b03365f
Prepare Solve Conflict
Snooz82 Aug 1, 2019
e2cda08
prepare for solve conflicts
Snooz82 Aug 1, 2019
e6db026
Merge branch 'master' of https://github.com/robotframework/SeleniumLi…
Snooz82 Aug 1, 2019
a0200f7
Merge branch 'robotframework-master'
Snooz82 Aug 1, 2019
dd6f770
Added an exapmle Test to switch to w window of another Browser by its…
Snooz82 Aug 2, 2019
83d8a9d
Updated documentation
aaltat Aug 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 163 additions & 0 deletions atest/acceptance/multiple_browsers_multiple_windows.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
*** Setting ***
Documentation These tests must open own browser because windows opened by
... earlier tests would otherwise be visible to Get Window XXX keywords
... even if those windows were closed.
Suite Setup Open 3 Browsers with Windows
Suite Teardown Close All Browsers
Resource resource.robot

*** Variables ***
@{BrowserA_EXP_TITLES}= WindowA1 WindowA2 WindowA3
@{BrowserB_EXP_TITLES}= WindowB1 WindowB2
@{BrowserC_EXP_TITLES}= WindowC1
@{ALL_BROWSERS_EXP_TITLES}= @{BrowserA_EXP_TITLES} @{BrowserB_EXP_TITLES} @{BrowserC_EXP_TITLES}
@{EXP_ALIASES}= BrowserA BrowserB BrowserC
@{EXP_IDS}= ${1} ${2} ${3}


*** Test Cases ***
Check Titles of Multiple Browser-Windows
@{BrowserA_Titles}= Get Window Titles browser=BrowserA
Should Be Equal ${BrowserA_Titles} ${BrowserA_EXP_TITLES}
@{BrowserB_Titles}= Get Window Titles browser=BrowserB
Should Be Equal ${BrowserB_Titles} ${BrowserB_EXP_TITLES}
@{BrowserC_Titles}= Get Window Titles browser=BrowserC
Should Be Equal ${BrowserC_Titles} ${BrowserC_EXP_TITLES}
@{All_Browsers_Titles}= Get Window Titles browser=ALL
Should Be Equal ${All_Browsers_Titles} ${ALL_BROWSERS_EXP_TITLES}

Check Count of Handle
Check Handle Count 3 BrowserA
Check Handle Count 2 BrowserB
Check Handle Count 1 BrowserC
Check Handle Count 6 ALL

Check Count of Names
Check Name Count 3 BrowserA
Check Name Count 2 BrowserB
Check Name Count 1 BrowserC
Check Name Count 6 ALL

Check Count of Identifiers
Check Identifiers Count 3 BrowserA
Check Identifiers Count 2 BrowserB
Check Identifiers Count 1 BrowserC
Check Identifiers Count 6 ALL

Check Locations
@{Locations}= Get Locations browser=ALL
Should Be Equal As Strings @{Locations}[0] ${FRONT_PAGE}javascript/dynamic_content.html?1
Should Be Equal As Strings @{Locations}[1] ${FRONT_PAGE}javascript/dynamic_content.html?2
Should Be Equal As Strings @{Locations}[2] ${FRONT_PAGE}javascript/dynamic_content.html?3
Should Be Equal As Strings @{Locations}[3] ${FRONT_PAGE}javascript/dynamic_content.html?4
Should Be Equal As Strings @{Locations}[4] ${FRONT_PAGE}javascript/dynamic_content.html?5
Should Be Equal As Strings @{Locations}[5] ${FRONT_PAGE}javascript/dynamic_content.html?6
${count} Get Length ${Locations}
Should Be Equal As Integers 6 ${count}

Get Browser Ids and Alias
@{Aliases}= Get Browser Aliases
Should Be Equal ${Aliases} ${EXP_ALIASES}
&{Aliases}= Get Browser Aliases
Should Be Equal ${Aliases.BrowserA} ${1}
Should Be Equal ${Aliases.BrowserB} ${2}
Should Be Equal ${Aliases.BrowserC} ${3}
@{IDs}= Get Browser Ids
Should Be Equal ${IDs} ${EXP_IDS}

Select Window by Location
Switch Browser BrowserA
Switch Window WindowA1
Switch Window By Location ${FRONT_PAGE}javascript/dynamic_content.html?5
${location} Get Location
Should Be Equal ${FRONT_PAGE}javascript/dynamic_content.html?5 ${location}
Title Should Be WindowB2

Switch Window to Different Browser
Switch Browser BrowserC
Switch Window WindowC1
Location Should Be ${FRONT_PAGE}javascript/dynamic_content.html?6
Switch Window title:WindowA1 browser=BrowserA
Location Should Be ${FRONT_PAGE}javascript/dynamic_content.html?1
Switch Window url:${FRONT_PAGE}javascript/dynamic_content.html?4 browser=BrowserB
Title Should Be WindowB1

Get Specific Locations and Title
Switch Browser BrowserA
Switch Window title:WindowA1
Location Should Be ${FRONT_PAGE}javascript/dynamic_content.html?1
@{Locations}= Get Locations browser=BrowserB
Should Be Equal @{Locations}[0] ${FRONT_PAGE}javascript/dynamic_content.html?4
Should Be Equal @{Locations}[1] ${FRONT_PAGE}javascript/dynamic_content.html?5
${count}= Get Length ${Locations}
Should Be Equal As Integers ${count} 2
@{Titles}= Get Window Titles browser=BrowserC
Should Be Equal @{Titles}[0] WindowC1
${count}= Get Length ${Titles}
Should Be Equal As Integers ${count} 1


Fail Switching Window and Locations From Different Browser
Switch Browser BrowserA
Switch Window WindowA1
${Error_Msg}= Run Keyword And Expect Error * Switch Window WindowB1
Should Be Equal As Strings ${Error_Msg} No window matching handle, name, title or URL 'WindowB1' found.
${Error_Msg}= Run Keyword And Expect Error * Get Locations browser=UnknownBrowser
Should Be Equal As Strings ${Error_Msg} Non-existing index or alias 'UnknownBrowser'.
${Error_Msg}= Run Keyword And Expect Error * Get Window Handles browser=${4}
Should Be Equal As Strings ${Error_Msg} Non-existing index or alias '4'.



*** Keywords ***
Open 3 Browsers with Windows
Close All Browsers
Open Browser With Alias And Title BrowserA WindowA1 1
Open New Window and set Title WindowA2 2
Open New Window And Set Title WindowA3 3
Open Browser With Alias And Title BrowserB WindowB1 4
Open New Window And Set Title WindowB2 5
Open Browser With Alias And Title BrowserC WindowC1 6

Open New Window And Set Title
[Arguments] ${title} ${id}
Execute Javascript window.open("dynamic_content.html?${id}")
Switch Window locator=NEW
Set Window Title ${title}

Open Browser With Alias And Title
[Arguments] ${alias} ${title} ${id}
Open Browser ${FRONT_PAGE}javascript/dynamic_content.html?${id} ${BROWSER} alias=${alias}
Set Window Title ${title}

Set Window Title
[Arguments] ${title}
Input Text id:titleChangeTxt ${title}
Click Button id:titleChangeBtn
Title Should Be ${title}

Check Handle Count
[Arguments] ${length} ${browser_alias}=${None}
@{WinCountBrowser}= Get Window Handles ${browser_alias}
${len}= Get Length ${WinCountBrowser}
Should Be Equal As Integers ${len} ${length}

Check Name Count
[Arguments] ${length} ${browser_alias}=${None}
@{WinCountBrowser}= Get Window Names ${browser_alias}
${len}= Get Length ${WinCountBrowser}
Should Be Equal As Integers ${len} ${length}

Check Identifiers Count
[Arguments] ${length} ${browser_alias}=${None}
@{WinCountBrowser}= Get Window Identifiers ${browser_alias}
${len}= Get Length ${WinCountBrowser}
Should Be Equal As Integers ${len} ${length}

Switch Window By Location
[Arguments] ${selected_location}
@{IDs}= Get Browser Ids
:FOR ${id} IN @{IDs}
\ @{locations}= Get Locations browser=${id}
\ Run Keyword If '${selected_location}' in $locations
... Switch Window url:${selected_location} browser=${id}
22 changes: 16 additions & 6 deletions atest/resources/html/javascript/dynamic_content.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
<a href="javascript:return false;" onclick="add_content('target', 'added content'); return false;">add content</a><br/>
<a id="unicode" href="javascript:return false;" onclick="document.title='äää'; return false;">title to ääää</a><br/>
<p>
<input type="radio" name="group" value="title"
onclick="document.title='Changed by Button';" />Change Title<br/>
<input type="radio" name="group" value="content"
onclick="add_content('button_target', 'added by button');"/>Add Content<br/>
<input type="radio" name="group" value="title"
onclick="document.title='Changed by Button';" />Change Title<br/>
<input type="radio" name="group" value="content"
onclick="add_content('button_target', 'added by button');"/>Add Content<br/>
</p>
<div id="target">
</div>
Expand All @@ -30,8 +30,18 @@
<input type=button value="Change the title"
onClick="if(confirm('Really change the title?'))
document.title += ' Changed!';" >
</form>

</form>
<p>
<form name=titleChanger>
<td>
<input type=text id=titleChangeTxt value="Enter Title here">
</td>
<td>
<input type=button id=titleChangeBtn value="Set Title"
onClick="document.title = document.getElementById('titleChangeTxt').value;" >
</td>
</form>
</p>
</body>
</html>

70 changes: 70 additions & 0 deletions src/SeleniumLibrary/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class SeleniumLibrary(DynamicCore):
== Table of contents ==

- `Locating elements`
- `Browser and Window`
- `Timeouts, waits and delays`
- `Run-on-failure functionality`
- `Boolean arguments`
Expand Down Expand Up @@ -223,6 +224,75 @@ class SeleniumLibrary(DynamicCore):

See the `Add Location Strategy` keyword for more details.

= Browser and Window =

There is different conseptual meaning when SeleniumLibrary talks
windows and browsers. This chapter explains those differences.

== Browser ==

When `Open Browser` or `Create WebDriver` keyword is called, it
will create a new Selenium WebDriver instance by using the
[https://www.seleniumhq.org/docs/03_webdriver.jsp|Selenium WebDriver]
API. In SeleniumLibrary terms, a new broser is created. It is
possible to start multiple independent browsers (Selenium Webdriver
instances) at the same time, by calling `Open Browser` or
`Create WebDriver` multiple times. These browsers are usually
independent to each other and do not share data like cookies,
sessions or profiles. Typicall when browser starts, it
creates a single window in the desktop.

== Window ==

Windows are the part of a browser that loads the web site and presents
it to the user. All content of the site is content of the window.
Windows are children of a WebDriver instance, in SeleniumLibrary
WebDriver is referred as browser. One browser may have multiple
windows. Windows can appear as tabs or as separate windows with
different position and size. Windows belonning to the same browser
typically share the sessions detail, like cookies. If there is a
need to separate sessions detail, example login with two different
users, two browser (Selenium WebDriver instances) must be created.
New windows can be opened example by the application under test or
by example `Execute Javascript` keyword:

| `Execute Javascript` window.open() # Opens a new window with location about:blank

In the example in below opens multiple browser and windows,
to demonstrate how the different keywords can be used to interact
with a browser and windows atteched to the browser.

Structure:
| BrowserA
| Window 1 (location=https://robotframework.org/)
| Window 2 (location=https://robocon.io/)
| Window 3 (location=https://github.com/robotframework/)
|
| BrowserB
| Window 1 (location=https://github.com/)

Example:
| `Open Browser` | https://robotframework.org | ${BROWSER} | alias=BrowserA | # BrowserA with first window is opened. |
| `Execute Javascript` | window.open() | | | # In BrowserA second window is opened. |
| `Switch Window` | locator=NEW | | | # Switched to second window in BrowserA |
| `Go To` | https://robocon.io | | | # Second window navigates to to robocon site. |
| `Execute Javascript` | window.open() | | | # In BrowserA third window is opened. |
| ${handle} | `Switch Window` | locator=NEW | | # Switched to third window in BrowserA |
| `Go To` | https://github.com/robotframework/ | | | # Third windows goes to robot framework github site. |
| `Open Browser` | https://github.com | ${BROWSER} | alias=BrowserB | # BrowserB with first windows is opened. |
| ${location} | `Get Location` | | | # ${location} is: https://www.github.com |
| `Switch Window` | ${handle} | browser=BrowserA | | # BrowserA second windows is selected. |
| ${location} | `Get Location` | | | # ${location} = https://robocon.io/ |
| @{locations 1} | `Get Locations` | | | # By default lists locations under the currectly active browser. |
| @{locations 2} | `Get Locations` | browser=ALL | | # By using browser=ALL argument keyword list all locations from all browsers. |

The above example, @{locations 1} contains the following items:
https://robotframework.org/, https://robocon.io/ and
https://github.com/robotframework/'. The @{locations 2}
contains the following items: https://robotframework.org/,
https://robocon.io/, https://github.com/robotframework/'
and 'https://github.com/.

= Timeouts, waits and delays =

This section discusses different ways how to wait for elements to
Expand Down
46 changes: 42 additions & 4 deletions src/SeleniumLibrary/keywords/browsermanagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def open_browser(self, url, browser='firefox', alias=None,
| options = webdriver.ChromeOptions()
| options.add_argument('--disable-dev-shm-usage')
| return options

Then the `${options}` variable can be used as argument to
``options``.

Expand Down Expand Up @@ -350,6 +350,44 @@ def switch_browser(self, index_or_alias):
self.debug('Switched to browser with Selenium session id %s.'
% self.driver.session_id)

@keyword
def get_browser_ids(self):
"""Returns index of all active browser as list.

Example:
| @{browser_ids}= | Get Browser Ids | | |
| FOR | ${id} | IN | @{browser_ids} |
| | @{window_titles}= | Get Window Titles | browser=${id} |
| | Log | Browser ${id} has these windows: ${window_titles} | |
| END | | | |

See `Switch Browser` for more information and examples.

New in SeleniumLibrary 4.0
"""
return self.drivers.active_driver_ids

@keyword
def get_browser_aliases(self):
"""Returns aliases of all active browser that has an alias as NormalizedDict.
The dictionary contains the aliases as keys and the index as value.
This can be accessed as dictionary ``${aliases.key}`` or as list ``@{aliases}[0]``.

Example:
| `Open Browser` | https://example.com | alias=BrowserA | |
| `Open Browser` | https://example.com | alias=BrowserB | |
| &{aliases} | `Get Browser Aliases` | | # &{aliases} = { BrowserA=1|BrowserB=2 } |
| `Log` | ${aliases.BrowserA} | | # logs ``1`` |
| FOR | ${alias} | IN | @{aliases} |
| | `Log` | ${alias} | # logs ``BrowserA`` and ``BrowserB`` |
| END | | | |

See `Switch Browser` for more information and examples.

New in SeleniumLibrary 4.0
"""
return self.drivers.active_aliases

@keyword
def get_session_id(self):
"""Returns the currently active browser session id.
Expand All @@ -370,7 +408,7 @@ def get_title(self):

@keyword
def get_location(self):
"""Returns the current browser URL."""
"""Returns the current browser window URL."""
return self.driver.current_url

@keyword
Expand Down Expand Up @@ -413,7 +451,7 @@ def location_should_contain(self, expected, message=None):

@keyword
def log_location(self):
"""Logs and returns the current URL."""
"""Logs and returns the current browser window URL."""
url = self.get_location()
self.info(url)
return url
Expand Down Expand Up @@ -460,7 +498,7 @@ def go_back(self):

@keyword
def go_to(self, url):
"""Navigates the active browser instance to the provided ``url``."""
"""Navigates the current browser window to the provided ``url``."""
self.info("Opening url '%s'" % url)
self.driver.get(url)

Expand Down
2 changes: 1 addition & 1 deletion src/SeleniumLibrary/keywords/cookie.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def get_cookies(self, as_dict=False):
sending HTTP requests. The dictionary format is helpful when
the result can be passed to requests library's Create Session
keyword's optional cookies parameter.

The `` as_dict`` argument is new in SeleniumLibrary 3.3
"""
if is_falsy(as_dict):
Expand Down
6 changes: 3 additions & 3 deletions src/SeleniumLibrary/keywords/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,12 +435,12 @@ def get_element_size(self, locator):
@keyword
def cover_element(self, locator):
"""Will cover elements identified by ``locator`` with a blue div without breaking page layout.

See the `Locating elements` section for details about the locator
syntax.

New in SeleniumLibrary 3.3.0

Example:
|`Cover Element` | css:div#container |
"""
Expand Down
Loading