From a3da65ffcbc230f5aeb9da77312a3b860976c3a2 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sat, 26 Jul 2014 21:16:05 -0400 Subject: [PATCH 01/21] Added 'Get Element' and 'Get Elements' keywords. --- src/Selenium2Library/keywords/_element.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index 9db21ab2d..507854f4c 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -9,6 +9,18 @@ class _ElementKeywords(KeywordGroup): def __init__(self): self._element_finder = ElementFinder() + # Public, get element(s) + + def get_element(): + pass + + def get_elements(self, locator): + """Returns list of elements matching locator. + + See `introduction` for details about locating elements. + """ + return self._element_find(locator, False, True) + # Public, element lookups def current_frame_contains(self, text, loglevel='INFO'): From d475be3f4e3598e6c12bd0c550f108f12980325f Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sat, 26 Jul 2014 21:29:21 -0400 Subject: [PATCH 02/21] Allow keywords to use WebDriver Element in addition to Locator. In some cases I want to be able to store the element itself and then act upon the element as compared to passing a locator each time and re-finding the element. At this point I am implementing this by checking the locator argument within keywords/_elements.py. This could possibly fit into the element finder code but this approach seems more desirable in that it is the point where the "locator" is passed in and an element is returned. Now instead it checks to see if the "locator" is a string and if so tries to find the element. And if it is an element is goes ahead and passes it through. Testing is needed to verify this doesn't break anything in addition to verify no other keywords would have issues if passed a WebDriver Element instead of a locator string. --- src/Selenium2Library/keywords/_element.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index 507854f4c..2db251b40 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -1,9 +1,18 @@ from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.remote.webelement import WebElement from Selenium2Library import utils from Selenium2Library.locators import ElementFinder from keywordgroup import KeywordGroup +try: + basestring # attempt to evaluate basestring + def isstr(s): + return isinstance(s, basestring) +except NameError: + def isstr(s): + return isinstance(s, str) + class _ElementKeywords(KeywordGroup): def __init__(self): @@ -572,7 +581,12 @@ def xpath_should_match_x_times(self, xpath, expected_xpath_count, message='', lo def _element_find(self, locator, first_only, required, tag=None): browser = self._current_browser() - elements = self._element_finder.find(browser, locator, tag) + if isstr(locator): + elements = self._element_finder.find(browser, locator, tag) + elif isinstance(locator, WebElement): + pass + # do some other stuff here like deal with list of webelements + # ... or raise locator/element specific error if required if required and len(elements) == 0: raise ValueError("Element locator '" + locator + "' did not match any elements.") if first_only: From dabcabd39ebfe7525444882271ee5bdfe0b924e4 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 27 Jul 2014 09:28:12 -0400 Subject: [PATCH 03/21] Fixed issues with code change to use elements in addtion to locators. Moved the checks for required and first_only under check for locator as if "locator" is a WebElement is found and singular. Pass WebElement "locator" into elements varaiable. ToDo: Still need to handle list of WebElements. --- src/Selenium2Library/keywords/_element.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index 2db251b40..c23be93f8 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -583,15 +583,15 @@ def _element_find(self, locator, first_only, required, tag=None): browser = self._current_browser() if isstr(locator): elements = self._element_finder.find(browser, locator, tag) + if required and len(elements) == 0: + raise ValueError("Element locator '" + locator + "' did not match any elements.") + if first_only: + if len(elements) == 0: return None + return elements[0] elif isinstance(locator, WebElement): - pass + elements = locator # do some other stuff here like deal with list of webelements # ... or raise locator/element specific error if required - if required and len(elements) == 0: - raise ValueError("Element locator '" + locator + "' did not match any elements.") - if first_only: - if len(elements) == 0: return None - return elements[0] return elements def _frame_contains(self, locator, text): From d980419e426dbae75e0ec1379fb4808e32bb6a05 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 27 Jul 2014 09:39:09 -0400 Subject: [PATCH 04/21] Added tests for new keyword 'Get Elements' --- test/acceptance/keywords/elements.txt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/acceptance/keywords/elements.txt b/test/acceptance/keywords/elements.txt index f6b4d2029..c29ae0a9d 100644 --- a/test/acceptance/keywords/elements.txt +++ b/test/acceptance/keywords/elements.txt @@ -1,8 +1,25 @@ *** Settings *** -Suite Setup Go To Page "links.html" +Test Setup Go To Page "links.html" Resource ../resource.txt *** Test Cases *** +Get Elements + @{links}= Get Elements //div[@id="div_id"]/a + Length Should Be ${links} 11 + +More Get Elements + [Setup] Go To Page "forms/prefilled_email_form.html" + @{checkboxes}= Get Elements //input[@type="checkbox"] + Length Should Be ${checkboxes} 2 + :For ${checkbox} in @{checkboxes} + \ Unselect Checkbox ${checkbox} + :For ${checkbox} in @{checkboxes} + \ Checkbox Should Not Be Selected ${checkbox} + :For ${checkbox} in @{checkboxes} + \ Select Checkbox ${checkbox} + :For ${checkbox} in @{checkboxes} + \ Checkbox Should Be Selected ${checkbox} + Assign Id To Element [Documentation] Tests also Reload Page keyword. Page Should Not Contain Element my id From 5d82653f81e3c8f440b397fc43e8e2e6cb50fd19 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 31 Aug 2014 17:32:19 -0400 Subject: [PATCH 05/21] Removed 'Get WebElement' (singular) keyword. Removing the placeholder for the (proposed) singular 'Get WebElement' keyword. In discussions with Kevin and Pekka it was suggested that the having only 'Get WebElements' (multiple) would provide both cases and help keep number of keywords to a reasonible number. In addition, it has been suggested to add either a index or firt-only flag to 'Get WebElements' (to come in another commit). --- src/Selenium2Library/keywords/_element.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index c23be93f8..6826b42fb 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -20,9 +20,6 @@ def __init__(self): # Public, get element(s) - def get_element(): - pass - def get_elements(self, locator): """Returns list of elements matching locator. From 7ad9866074f89d5ce195638271895dac65f0a326 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 31 Aug 2014 20:32:21 -0400 Subject: [PATCH 06/21] Renamed 'Get Elements' to 'Get WebElements'. --- src/Selenium2Library/keywords/_element.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index 6826b42fb..a8fa5a0c8 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -20,8 +20,8 @@ def __init__(self): # Public, get element(s) - def get_elements(self, locator): - """Returns list of elements matching locator. + def get_webelements(self, locator): + """Returns list of WebElement objects matching locator. See `introduction` for details about locating elements. """ From 41982661996877ebd014bda042b2ba14f6f59db6 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Mon, 6 Oct 2014 21:22:03 -0400 Subject: [PATCH 07/21] Initial documentation for using WebElements and Locators --- src/Selenium2Library/__init__.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/Selenium2Library/__init__.py b/src/Selenium2Library/__init__.py index 35dd54835..a7877345b 100644 --- a/src/Selenium2Library/__init__.py +++ b/src/Selenium2Library/__init__.py @@ -34,13 +34,24 @@ class Selenium2Library( imported into your Robot test suite (see `importing` section), and the `Open Browser` keyword must be used to open a browser to the desired location. - *Locating elements* + **--- Note important change starting with Version 1.6.0 release ---** + *Locating or getting elements* + *Locating or specifying elements* + *Locating or passing elements* All keywords in Selenium2Library that need to find an element on the page - take an argument, `locator`. By default, when a locator value is provided, - it is matched against the key attributes of the particular element type. - For example, `id` and `name` are key attributes to all elements, and - locating elements is easy using just the `id` as a `locator`. For example:: + take an argument, either a `locator` or now a 'webelement'. 'locator' + specifies an attribute of the element you are trying to locate and is a + scalar variable with a string value. 'webelement' is a variable which + holds [a representation of the element][a Selenium instance of the + WebElement][a Selenium WebElement instance of the element]. + + Using 'locator' + --------------- + By default, when a locator value is provided, it is matched against the + key attributes of the particular element type. For example, `id` and + `name` are key attributes to all elements, and locating elements is easy + using just the `id` as a `locator`. For example:: Click Element my_element @@ -60,6 +71,15 @@ class Selenium2Library( | sizzle | Click Element `|` sizzle=div.my_class | Matches by jQuery/sizzle selector | | tag | Click Element `|` tag=div | Matches by HTML tag name | + Using 'webelement' + ------------------ + Starting with version 1.6 of the Selenium2Library, one can ... For example: + + | ${elem} = | Get WebElements | id=my_element | + | Click Element | ${elem} | | + + Locating Tables, Table Rows, Columns, etc. + ------------------------------------------ Table related keywords, such as `Table Should Contain`, work differently. By default, when a table locator value is provided, it will search for a table with the specified `id` attribute. For example: From da4259a2345e8b874e47c0b3293992c2c943042d Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 12 Oct 2014 09:12:47 -0400 Subject: [PATCH 08/21] Updated documentation for locating objects using WebElements. --- src/Selenium2Library/__init__.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Selenium2Library/__init__.py b/src/Selenium2Library/__init__.py index a7877345b..82db92730 100644 --- a/src/Selenium2Library/__init__.py +++ b/src/Selenium2Library/__init__.py @@ -35,16 +35,13 @@ class Selenium2Library( `Open Browser` keyword must be used to open a browser to the desired location. **--- Note important change starting with Version 1.6.0 release ---** - *Locating or getting elements* *Locating or specifying elements* - *Locating or passing elements* All keywords in Selenium2Library that need to find an element on the page take an argument, either a `locator` or now a 'webelement'. 'locator' - specifies an attribute of the element you are trying to locate and is a - scalar variable with a string value. 'webelement' is a variable which - holds [a representation of the element][a Selenium instance of the - WebElement][a Selenium WebElement instance of the element]. + is a string that describes how to locate an element using a syntax + specifying different location strategies. 'webelement' is a variable that + holds a WebElement instance, which is a representation of the element. Using 'locator' --------------- @@ -73,7 +70,9 @@ class Selenium2Library( Using 'webelement' ------------------ - Starting with version 1.6 of the Selenium2Library, one can ... For example: + Starting with version 1.6 of the Selenium2Library, one can pass an argument + that contains a WebElement instead of a string locator. To get a WebElement, + use the new `Get WebElements` keyword. For example: | ${elem} = | Get WebElements | id=my_element | | Click Element | ${elem} | | @@ -92,6 +91,11 @@ class Selenium2Library( | css | Table Should Contain `|` css=table.my_class `|` text | Matches by @id or @name attribute | | xpath | Table Should Contain `|` xpath=//table/[@name="my_table"] `|` text | Matches by @id or @name attribute | + *Stale and Detached Elements* + + To be written... a talk about stale/detached elements, the dreaded + StaleElementReferenceException and how to deal with these situations. + *Timeouts* There are several `Wait ...` keywords that take timeout as an From 505e6b32c9ee4761eb0b4007dfab49bf3ee3a5a4 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 12 Oct 2014 11:10:20 -0400 Subject: [PATCH 09/21] Updated tests reflecting change in keyword name to 'Get WebElements'. --- test/acceptance/keywords/elements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/acceptance/keywords/elements.txt b/test/acceptance/keywords/elements.txt index c29ae0a9d..d488b6a90 100644 --- a/test/acceptance/keywords/elements.txt +++ b/test/acceptance/keywords/elements.txt @@ -4,12 +4,12 @@ Resource ../resource.txt *** Test Cases *** Get Elements - @{links}= Get Elements //div[@id="div_id"]/a + @{links}= Get WebElements //div[@id="div_id"]/a Length Should Be ${links} 11 More Get Elements [Setup] Go To Page "forms/prefilled_email_form.html" - @{checkboxes}= Get Elements //input[@type="checkbox"] + @{checkboxes}= Get WebElements //input[@type="checkbox"] Length Should Be ${checkboxes} 2 :For ${checkbox} in @{checkboxes} \ Unselect Checkbox ${checkbox} From c7f62085067795d668bd174ea08055c0f884f2ad Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sat, 26 Jul 2014 21:16:05 -0400 Subject: [PATCH 10/21] Added 'Get Element' and 'Get Elements' keywords. --- src/Selenium2Library/keywords/_element.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index a91edfbf6..769376a59 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -9,6 +9,18 @@ class _ElementKeywords(KeywordGroup): def __init__(self): self._element_finder = ElementFinder() + # Public, get element(s) + + def get_element(): + pass + + def get_elements(self, locator): + """Returns list of elements matching locator. + + See `introduction` for details about locating elements. + """ + return self._element_find(locator, False, True) + # Public, element lookups def current_frame_contains(self, text, loglevel='INFO'): From 81f479b923b931d976640741fdf59818b64cc4cb Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sat, 26 Jul 2014 21:29:21 -0400 Subject: [PATCH 11/21] Allow keywords to use WebDriver Element in addition to Locator. In some cases I want to be able to store the element itself and then act upon the element as compared to passing a locator each time and re-finding the element. At this point I am implementing this by checking the locator argument within keywords/_elements.py. This could possibly fit into the element finder code but this approach seems more desirable in that it is the point where the "locator" is passed in and an element is returned. Now instead it checks to see if the "locator" is a string and if so tries to find the element. And if it is an element is goes ahead and passes it through. Testing is needed to verify this doesn't break anything in addition to verify no other keywords would have issues if passed a WebDriver Element instead of a locator string. --- src/Selenium2Library/keywords/_element.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index 769376a59..c2f8a2d74 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -1,9 +1,18 @@ from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.remote.webelement import WebElement from Selenium2Library import utils from Selenium2Library.locators import ElementFinder from keywordgroup import KeywordGroup +try: + basestring # attempt to evaluate basestring + def isstr(s): + return isinstance(s, basestring) +except NameError: + def isstr(s): + return isinstance(s, str) + class _ElementKeywords(KeywordGroup): def __init__(self): @@ -600,7 +609,12 @@ def xpath_should_match_x_times(self, xpath, expected_xpath_count, message='', lo def _element_find(self, locator, first_only, required, tag=None): browser = self._current_browser() - elements = self._element_finder.find(browser, locator, tag) + if isstr(locator): + elements = self._element_finder.find(browser, locator, tag) + elif isinstance(locator, WebElement): + pass + # do some other stuff here like deal with list of webelements + # ... or raise locator/element specific error if required if required and len(elements) == 0: raise ValueError("Element locator '" + locator + "' did not match any elements.") if first_only: From 01ecb471e7470660a868d406d6fc495e9d897457 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 27 Jul 2014 09:28:12 -0400 Subject: [PATCH 12/21] Fixed issues with code change to use elements in addtion to locators. Moved the checks for required and first_only under check for locator as if "locator" is a WebElement is found and singular. Pass WebElement "locator" into elements varaiable. ToDo: Still need to handle list of WebElements. --- src/Selenium2Library/keywords/_element.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index c2f8a2d74..998cf61fc 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -611,15 +611,15 @@ def _element_find(self, locator, first_only, required, tag=None): browser = self._current_browser() if isstr(locator): elements = self._element_finder.find(browser, locator, tag) + if required and len(elements) == 0: + raise ValueError("Element locator '" + locator + "' did not match any elements.") + if first_only: + if len(elements) == 0: return None + return elements[0] elif isinstance(locator, WebElement): - pass + elements = locator # do some other stuff here like deal with list of webelements # ... or raise locator/element specific error if required - if required and len(elements) == 0: - raise ValueError("Element locator '" + locator + "' did not match any elements.") - if first_only: - if len(elements) == 0: return None - return elements[0] return elements def _frame_contains(self, locator, text): From 9b3e2b7c0f81ecac594deec5d2204c0905697915 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 27 Jul 2014 09:39:09 -0400 Subject: [PATCH 13/21] Added tests for new keyword 'Get Elements' --- test/acceptance/keywords/elements.txt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/acceptance/keywords/elements.txt b/test/acceptance/keywords/elements.txt index f6b4d2029..c29ae0a9d 100644 --- a/test/acceptance/keywords/elements.txt +++ b/test/acceptance/keywords/elements.txt @@ -1,8 +1,25 @@ *** Settings *** -Suite Setup Go To Page "links.html" +Test Setup Go To Page "links.html" Resource ../resource.txt *** Test Cases *** +Get Elements + @{links}= Get Elements //div[@id="div_id"]/a + Length Should Be ${links} 11 + +More Get Elements + [Setup] Go To Page "forms/prefilled_email_form.html" + @{checkboxes}= Get Elements //input[@type="checkbox"] + Length Should Be ${checkboxes} 2 + :For ${checkbox} in @{checkboxes} + \ Unselect Checkbox ${checkbox} + :For ${checkbox} in @{checkboxes} + \ Checkbox Should Not Be Selected ${checkbox} + :For ${checkbox} in @{checkboxes} + \ Select Checkbox ${checkbox} + :For ${checkbox} in @{checkboxes} + \ Checkbox Should Be Selected ${checkbox} + Assign Id To Element [Documentation] Tests also Reload Page keyword. Page Should Not Contain Element my id From f90516aa494849ae25a3fb0386118ac44b82527e Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 31 Aug 2014 17:32:19 -0400 Subject: [PATCH 14/21] Removed 'Get WebElement' (singular) keyword. Removing the placeholder for the (proposed) singular 'Get WebElement' keyword. In discussions with Kevin and Pekka it was suggested that the having only 'Get WebElements' (multiple) would provide both cases and help keep number of keywords to a reasonible number. In addition, it has been suggested to add either a index or firt-only flag to 'Get WebElements' (to come in another commit). --- src/Selenium2Library/keywords/_element.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index 998cf61fc..dade9e837 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -20,9 +20,6 @@ def __init__(self): # Public, get element(s) - def get_element(): - pass - def get_elements(self, locator): """Returns list of elements matching locator. From cee2d838fe4f14a4722e13ad8952c7f870940256 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 31 Aug 2014 20:32:21 -0400 Subject: [PATCH 15/21] Renamed 'Get Elements' to 'Get WebElements'. --- src/Selenium2Library/keywords/_element.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index dade9e837..c1298574f 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -20,8 +20,8 @@ def __init__(self): # Public, get element(s) - def get_elements(self, locator): - """Returns list of elements matching locator. + def get_webelements(self, locator): + """Returns list of WebElement objects matching locator. See `introduction` for details about locating elements. """ From da2544c1ec5cf0f678e6179864ec1de3610b2c7e Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Mon, 6 Oct 2014 21:22:03 -0400 Subject: [PATCH 16/21] Initial documentation for using WebElements and Locators --- src/Selenium2Library/__init__.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/Selenium2Library/__init__.py b/src/Selenium2Library/__init__.py index 2aff8ec88..a23a030d2 100644 --- a/src/Selenium2Library/__init__.py +++ b/src/Selenium2Library/__init__.py @@ -34,13 +34,24 @@ class Selenium2Library( imported into your Robot test suite (see `importing` section), and the `Open Browser` keyword must be used to open a browser to the desired location. - = Locating elements = + **--- Note important change starting with Version 1.7.0 release ---** + *Locating or getting elements* + *Locating or specifying elements* + *Locating or passing elements* All keywords in Selenium2Library that need to find an element on the page - take an argument, `locator`. By default, when a locator value is provided, - it is matched against the key attributes of the particular element type. - For example, `id` and `name` are key attributes to all elements, and - locating elements is easy using just the `id` as a `locator`. For example:: + take an argument, either a `locator` or now a 'webelement'. 'locator' + specifies an attribute of the element you are trying to locate and is a + scalar variable with a string value. 'webelement' is a variable which + holds [a representation of the element][a Selenium instance of the + WebElement][a Selenium WebElement instance of the element]. + + Using 'locator' + --------------- + By default, when a locator value is provided, it is matched against the + key attributes of the particular element type. For example, `id` and + `name` are key attributes to all elements, and locating elements is easy + using just the `id` as a `locator`. For example:: Click Element my_element @@ -69,6 +80,15 @@ class Selenium2Library( This can be fixed by changing the locator to: | Click Link default=page?a=b + Using 'webelement' + ------------------ + Starting with version 1.6 of the Selenium2Library, one can ... For example: + + | ${elem} = | Get WebElements | id=my_element | + | Click Element | ${elem} | | + + Locating Tables, Table Rows, Columns, etc. + ------------------------------------------ Table related keywords, such as `Table Should Contain`, work differently. By default, when a table locator value is provided, it will search for a table with the specified `id` attribute. For example: From 48e0e2b13c77980884e533f2bafbbe5a389ebdba Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 12 Oct 2014 09:12:47 -0400 Subject: [PATCH 17/21] Updated documentation for locating objects using WebElements. --- src/Selenium2Library/__init__.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Selenium2Library/__init__.py b/src/Selenium2Library/__init__.py index a23a030d2..62c056839 100644 --- a/src/Selenium2Library/__init__.py +++ b/src/Selenium2Library/__init__.py @@ -37,14 +37,12 @@ class Selenium2Library( **--- Note important change starting with Version 1.7.0 release ---** *Locating or getting elements* *Locating or specifying elements* - *Locating or passing elements* All keywords in Selenium2Library that need to find an element on the page take an argument, either a `locator` or now a 'webelement'. 'locator' - specifies an attribute of the element you are trying to locate and is a - scalar variable with a string value. 'webelement' is a variable which - holds [a representation of the element][a Selenium instance of the - WebElement][a Selenium WebElement instance of the element]. + is a string that describes how to locate an element using a syntax + specifying different location strategies. 'webelement' is a variable that + holds a WebElement instance, which is a representation of the element. Using 'locator' --------------- @@ -82,7 +80,9 @@ class Selenium2Library( Using 'webelement' ------------------ - Starting with version 1.6 of the Selenium2Library, one can ... For example: + Starting with version 1.6 of the Selenium2Library, one can pass an argument + that contains a WebElement instead of a string locator. To get a WebElement, + use the new `Get WebElements` keyword. For example: | ${elem} = | Get WebElements | id=my_element | | Click Element | ${elem} | | @@ -101,7 +101,16 @@ class Selenium2Library( | css | Table Should Contain `|` css=table.my_class `|` text | Matches by @id or @name attribute | | xpath | Table Should Contain `|` xpath=//table/[@name="my_table"] `|` text | Matches by @id or @name attribute | +<<<<<<< HEAD = Timeouts = +======= + *Stale and Detached Elements* + + To be written... a talk about stale/detached elements, the dreaded + StaleElementReferenceException and how to deal with these situations. + + *Timeouts* +>>>>>>> Updated documentation for locating objects using WebElements. There are several `Wait ...` keywords that take timeout as an argument. All of these timeout arguments are optional. The timeout From 7ee9e4f20d1ca0e5321f5da59ce86586a2b6bc7b Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 12 Oct 2014 11:10:20 -0400 Subject: [PATCH 18/21] Updated tests reflecting change in keyword name to 'Get WebElements'. --- test/acceptance/keywords/elements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/acceptance/keywords/elements.txt b/test/acceptance/keywords/elements.txt index c29ae0a9d..d488b6a90 100644 --- a/test/acceptance/keywords/elements.txt +++ b/test/acceptance/keywords/elements.txt @@ -4,12 +4,12 @@ Resource ../resource.txt *** Test Cases *** Get Elements - @{links}= Get Elements //div[@id="div_id"]/a + @{links}= Get WebElements //div[@id="div_id"]/a Length Should Be ${links} 11 More Get Elements [Setup] Go To Page "forms/prefilled_email_form.html" - @{checkboxes}= Get Elements //input[@type="checkbox"] + @{checkboxes}= Get WebElements //input[@type="checkbox"] Length Should Be ${checkboxes} 2 :For ${checkbox} in @{checkboxes} \ Unselect Checkbox ${checkbox} From 0a70f45dfdbf821c5fbdda7f53c28d96ff39bb2e Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Mon, 2 Feb 2015 15:22:52 -0500 Subject: [PATCH 19/21] Removed documentation stub for stale elements. This, yet to be written, section will be added later. Going to remove it for now from the changes made for using web elements as locators and will make a seperate commit/pull request for it. --- src/Selenium2Library/__init__.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Selenium2Library/__init__.py b/src/Selenium2Library/__init__.py index d5c34198a..b9383bf70 100644 --- a/src/Selenium2Library/__init__.py +++ b/src/Selenium2Library/__init__.py @@ -101,11 +101,6 @@ class Selenium2Library( | css | Table Should Contain `|` css=table.my_class `|` text | Matches by @id or @name attribute | | xpath | Table Should Contain `|` xpath=//table/[@name="my_table"] `|` text | Matches by @id or @name attribute | - *Stale and Detached Elements* - - To be written... a talk about stale/detached elements, the dreaded - StaleElementReferenceException and how to deal with these situations. - *Timeouts* There are several `Wait ...` keywords that take timeout as an From a2522b09367b6125cf54a33230a137ef9d0e4094 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Sun, 3 May 2015 19:59:23 -0400 Subject: [PATCH 20/21] Update documentation with minor corrections. --- src/Selenium2Library/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Selenium2Library/__init__.py b/src/Selenium2Library/__init__.py index b9383bf70..c56cf0065 100644 --- a/src/Selenium2Library/__init__.py +++ b/src/Selenium2Library/__init__.py @@ -35,7 +35,6 @@ class Selenium2Library( `Open Browser` keyword must be used to open a browser to the desired location. **--- Note important change starting with Version 1.7.0 release ---** - *Locating or getting elements* *Locating or specifying elements* All keywords in Selenium2Library that need to find an element on the page @@ -80,7 +79,7 @@ class Selenium2Library( Using 'webelement' ------------------ - Starting with version 1.6 of the Selenium2Library, one can pass an argument + Starting with version 1.7 of the Selenium2Library, one can pass an argument that contains a WebElement instead of a string locator. To get a WebElement, use the new `Get WebElements` keyword. For example: From 62626112daac55a9befd9e7d71aea4e91ee83630 Mon Sep 17 00:00:00 2001 From: Ed Manlove Date: Mon, 18 May 2015 22:05:40 -0400 Subject: [PATCH 21/21] Minor documentation and formatting corrections. --- src/Selenium2Library/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Selenium2Library/__init__.py b/src/Selenium2Library/__init__.py index 1161f7a8a..fad8a88c5 100644 --- a/src/Selenium2Library/__init__.py +++ b/src/Selenium2Library/__init__.py @@ -34,12 +34,12 @@ class Selenium2Library( `Open Browser` keyword must be used to open a browser to the desired location. **--- Note important change starting with Version 1.7.0 release ---** - *Locating or specifying elements* + = Locating or specifying elements = All keywords in Selenium2Library that need to find an element on the page - take an argument, either a `locator` or now a 'webelement'. 'locator' + take an argument, either a `locator` or now a `webelement`. `locator` is a string that describes how to locate an element using a syntax - specifying different location strategies. 'webelement' is a variable that + specifying different location strategies. `webelement` is a variable that holds a WebElement instance, which is a representation of the element. Using 'locator'