Skip to content

Commit

Permalink
select_elements_from_context_menu (#147)
Browse files Browse the repository at this point in the history
* send for testing

* tests

* copy mistake

* that should do it for 100% coverage

* v2.5.6

* Tommy caught my typo
  • Loading branch information
Wolfe1 committed Nov 4, 2020
1 parent cb095e2 commit 6619871
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/APILibraryDocumentation.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DesktopLibraryDocumentation.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/GUILibraryDocumentation.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/MobileLibraryDocumentation.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/SOAPLibraryDocumentation.html
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@
jQuery.extend({highlight:function(e,t,n,r){if(e.nodeType===3){var i=e.data.match(t);if(i){var s=document.createElement(n||"span");s.className=r||"highlight";var o=e.splitText(i.index);o.splitText(i[0].length);var u=o.cloneNode(true);s.appendChild(u);o.parentNode.replaceChild(s,o);return 1}}else if(e.nodeType===1&&e.childNodes&&!/(script|style)/i.test(e.tagName)&&!(e.tagName===n.toUpperCase()&&e.className===r)){for(var a=0;a<e.childNodes.length;a++){a+=jQuery.highlight(e.childNodes[a],t,n,r)}}return 0}});jQuery.fn.unhighlight=function(e){var t={className:"highlight",element:"span"};jQuery.extend(t,e);return this.find(t.element+"."+t.className).each(function(){var e=this.parentNode;e.replaceChild(this.firstChild,this);e.normalize()}).end()};jQuery.fn.highlight=function(e,t){var n={className:"highlight",element:"span",caseSensitive:false,wordsOnly:false};jQuery.extend(n,t);if(e.constructor===String){e=[e]}e=jQuery.grep(e,function(e,t){return e!=""});e=jQuery.map(e,function(e,t){return e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")});if(e.length==0){return this}var r=n.caseSensitive?"":"i";var i="("+e.join("|")+")";if(n.wordsOnly){i="\\b"+i+"\\b"}var s=new RegExp(i,r);return this.each(function(){jQuery.highlight(this,s,n.element,n.className)})}
</script>
<script type="text/javascript">
libdoc = {"all_tags":[],"contains_tags":false,"doc":"<p>Zoomba SOAP Library\x3c/p>\n<p>This class is the base Library used to generate automated SOAP Tests in the Zoomba Automation Framework.\x3c/p>","generated":"2020-10-28 09:21:59","inits":[],"keywords":[{"args":["action=None","soap_object=None"],"doc":"<p>Call Soap Method. Calls soap method with list object\x3c/p>\n<p>action: (string) SOAP Action to be called.\x3c/p>\n<p>soap_object: (list) Soap Object in list format, list must be ordered wrt schema\x3c/p>","matched":true,"name":"Call Soap Method With List Object","shortdoc":"Call Soap Method. Calls soap method with list object ","tags":[]},{"args":["action=None","**soap_object"],"doc":"<p>Call Soap Method with dictionary object. Calls soap method\x3c/p>\n<p>action: (string) SOAP Action to be called.\x3c/p>\n<p>soap_object: (dict) Soap Object in dict format, dict must contain all required parts of schema object.\x3c/p>","matched":true,"name":"Call Soap Method With Object","shortdoc":"Call Soap Method with dictionary object. Calls soap method ","tags":[]},{"args":["soap_response=None"],"doc":"<p>Convert Soap Response To Dictionary: This keyword builds a dictionary from the sudsLibrary response\x3c/p>\n<p>json_actual_response: (request response object) The response from an API.\x3c/p>\n<p>return: There is no actual returned output, other than error messages when comparisons fail.\x3c/p>","matched":true,"name":"Convert Soap Response To Json","shortdoc":"Convert Soap Response To Dictionary: This keyword builds a dictionary from the sudsLibrary response","tags":[]},{"args":["host=None","endpoint=None","alias=None","**kwargs"],"doc":"<p>Create Soap Session. This Keyword utilizes the WSDL to create a soap client.\x3c/p>\n<p>host: (string) The host url.\x3c/p>\n<p>endpoint: (string) SOAP API endpoint containing the actions to be referenced.\x3c/p>\n<p>**kwargs: (optional) Parameters that could be included to add options to client creation. Current supported parameters are:\x3c/p>\n<p>set_location: http address\x3c/p>","matched":true,"name":"Create Soap Session","shortdoc":"Create Soap Session. This Keyword utilizes the WSDL to create a soap client.","tags":[]},{"args":["host=None","endpoint=None","alias=None","**kwargs"],"doc":"<p>Create Soap Session. This Keyword utilizes the WSDL and directly accesses calls from sudsLibrary.\x3c/p>\n<p>host: (string) The host url.\x3c/p>\n<p>endpoint: (string) SOAP API endpoint containing the actions to be referenced.\x3c/p>\n<p>alias: (string} Sets the alias for the SudsLibrary Framework **kwargs: (optional) Parameters that could be included to add options to client creation. Current supported parameters are:\x3c/p>\n<p>set_location: http address\x3c/p>","matched":true,"name":"Create Soap Session And Fix Wsdl","shortdoc":"Create Soap Session. This Keyword utilizes the WSDL and directly accesses calls from sudsLibrary.","tags":[]},{"args":["host=None","endpoint=None","alias=None","set_location=None","fix=False"],"doc":"<p>Create Soap Session and Set Location. In addition to the client creation, this keyword sets the location as specified.\x3c/p>\n<p>host: (string) The host url.\x3c/p>\n<p>endpoint: (string) SOAP API endpoint containing the actions to be referenced.\x3c/p>\n<p>set_location: (string) If set will overwrite the WSDL location with specified address.\x3c/p>\n<p>If set to None will replace location with host and endpoint specified\x3c/p>","matched":true,"name":"Create Soap Session And Set Location","shortdoc":"Create Soap Session and Set Location. In addition to the client creation, this keyword sets the location as specified.","tags":[]},{"args":["wsdl_type=None","object_dict=None"],"doc":"<p>Create Wsdl Objects. This Keyword utilizes the WSDL to create a WSDL object based on the information provided.\x3c/p>\n<p>wsdl_type: (string) Wsdl object to be created.\x3c/p>\n<p>object_dict: (dict) Python Dictionary containing values and nested dictionaries with construction similar to wsdl defined objects.\x3c/p>\n<p>return: (response object) Returns the SOAP client object.\x3c/p>","matched":true,"name":"Create Wsdl Objects","shortdoc":"Create Wsdl Objects. This Keyword utilizes the WSDL to create a WSDL object based on the information provided.","tags":[]}],"name":"SOAP_Library","named_args":true,"scope":"TEST","version":"2.5.5"};
libdoc = {"all_tags":[],"contains_tags":false,"doc":"<p>Zoomba SOAP Library\x3c/p>\n<p>This class is the base Library used to generate automated SOAP Tests in the Zoomba Automation Framework.\x3c/p>","generated":"2020-11-04 13:09:29","inits":[],"keywords":[{"args":["action=None","soap_object=None"],"doc":"<p>Call Soap Method. Calls soap method with list object\x3c/p>\n<p>action: (string) SOAP Action to be called.\x3c/p>\n<p>soap_object: (list) Soap Object in list format, list must be ordered wrt schema\x3c/p>","matched":true,"name":"Call Soap Method With List Object","shortdoc":"Call Soap Method. Calls soap method with list object ","tags":[]},{"args":["action=None","**soap_object"],"doc":"<p>Call Soap Method with dictionary object. Calls soap method\x3c/p>\n<p>action: (string) SOAP Action to be called.\x3c/p>\n<p>soap_object: (dict) Soap Object in dict format, dict must contain all required parts of schema object.\x3c/p>","matched":true,"name":"Call Soap Method With Object","shortdoc":"Call Soap Method with dictionary object. Calls soap method ","tags":[]},{"args":["soap_response=None"],"doc":"<p>Convert Soap Response To Dictionary: This keyword builds a dictionary from the sudsLibrary response\x3c/p>\n<p>json_actual_response: (request response object) The response from an API.\x3c/p>\n<p>return: There is no actual returned output, other than error messages when comparisons fail.\x3c/p>","matched":true,"name":"Convert Soap Response To Json","shortdoc":"Convert Soap Response To Dictionary: This keyword builds a dictionary from the sudsLibrary response","tags":[]},{"args":["host=None","endpoint=None","alias=None","**kwargs"],"doc":"<p>Create Soap Session. This Keyword utilizes the WSDL to create a soap client.\x3c/p>\n<p>host: (string) The host url.\x3c/p>\n<p>endpoint: (string) SOAP API endpoint containing the actions to be referenced.\x3c/p>\n<p>**kwargs: (optional) Parameters that could be included to add options to client creation. Current supported parameters are:\x3c/p>\n<p>set_location: http address\x3c/p>","matched":true,"name":"Create Soap Session","shortdoc":"Create Soap Session. This Keyword utilizes the WSDL to create a soap client.","tags":[]},{"args":["host=None","endpoint=None","alias=None","**kwargs"],"doc":"<p>Create Soap Session. This Keyword utilizes the WSDL and directly accesses calls from sudsLibrary.\x3c/p>\n<p>host: (string) The host url.\x3c/p>\n<p>endpoint: (string) SOAP API endpoint containing the actions to be referenced.\x3c/p>\n<p>alias: (string} Sets the alias for the SudsLibrary Framework **kwargs: (optional) Parameters that could be included to add options to client creation. Current supported parameters are:\x3c/p>\n<p>set_location: http address\x3c/p>","matched":true,"name":"Create Soap Session And Fix Wsdl","shortdoc":"Create Soap Session. This Keyword utilizes the WSDL and directly accesses calls from sudsLibrary.","tags":[]},{"args":["host=None","endpoint=None","alias=None","set_location=None","fix=False"],"doc":"<p>Create Soap Session and Set Location. In addition to the client creation, this keyword sets the location as specified.\x3c/p>\n<p>host: (string) The host url.\x3c/p>\n<p>endpoint: (string) SOAP API endpoint containing the actions to be referenced.\x3c/p>\n<p>set_location: (string) If set will overwrite the WSDL location with specified address.\x3c/p>\n<p>If set to None will replace location with host and endpoint specified\x3c/p>","matched":true,"name":"Create Soap Session And Set Location","shortdoc":"Create Soap Session and Set Location. In addition to the client creation, this keyword sets the location as specified.","tags":[]},{"args":["wsdl_type=None","object_dict=None"],"doc":"<p>Create Wsdl Objects. This Keyword utilizes the WSDL to create a WSDL object based on the information provided.\x3c/p>\n<p>wsdl_type: (string) Wsdl object to be created.\x3c/p>\n<p>object_dict: (dict) Python Dictionary containing values and nested dictionaries with construction similar to wsdl defined objects.\x3c/p>\n<p>return: (response object) Returns the SOAP client object.\x3c/p>","matched":true,"name":"Create Wsdl Objects","shortdoc":"Create Wsdl Objects. This Keyword utilizes the WSDL to create a WSDL object based on the information provided.","tags":[]}],"name":"SOAP_Library","named_args":true,"scope":"TEST","version":"2.5.6"};
</script>
<title></title>
</head>
Expand Down
37 changes: 36 additions & 1 deletion src/Zoomba/DesktopLibrary.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def get_keyword_names(self):
'drag_and_drop_by_offset', 'send_keys', 'send_keys_to_element',
'capture_page_screenshot', 'save_appium_screenshot', 'select_element_from_combobox',
'driver_setup', 'driver_teardown', 'select_elements_from_menu',
'select_elements_from_context_menu',
# External Libraries
'clear_text', 'click_button', 'click_element', 'close_all_applications',
'close_application', 'element_attribute_should_match', 'element_should_be_disabled',
Expand Down Expand Up @@ -611,7 +612,7 @@ def select_elements_from_menu(self, *args):
"""Selects N number of elements in the order they are given. This is useful for working
though a nested menu listing of elements.
On failure this keyword wil attempt to select the elements from the desktop session due to
On failure this keyword will attempt to select the elements from the desktop session due to
the nature of some pop-out menus in Windows."""
count = 0
try:
Expand All @@ -630,6 +631,40 @@ def select_elements_from_menu(self, *args):
count += 1
self.switch_application(original_index)

@keyword("Select Elements From Context Menu")
def select_elements_from_context_menu(self, *args):
"""Context clicks the first element and then selects N number of elements in the order they
are given. This is useful for working though a nested context menu listing of elements.
On failure this keyword will attempt to select the elements from the desktop session due to
the nature of some pop-out menus in Windows."""
count = 0
try:
for each in args:
if count == 0:
self.mouse_over_and_context_click_element(each)
else:
self.click_element(each)
count += 1
except NoSuchElementException:
original_index = self._cache.current_index
self.switch_application('Desktop')
for each in args[count:]:
try:
if count == 0:
self.mouse_over_and_context_click_element(each)
else:
self.click_element(each)
except NoSuchElementException:
if count == 0:
self._wait_until_page_contains_element(each, self.get_appium_timeout())
self.mouse_over_and_context_click_element(each)
else:
self._wait_until_page_contains_element(each, self.get_appium_timeout())
self.click_element(each)
count += 1
self.switch_application(original_index)

# Private
def _move_to_element(self, actions, element, x_offset=0, y_offset=0):
if x_offset != 0 or y_offset != 0:
Expand Down
27 changes: 27 additions & 0 deletions test/Desktop/test_desktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,33 @@ def test_select_elements_from_menu_no_desktop(self):
DesktopLibrary.select_elements_from_menu(mock_desk, 'some_locator', 'another_locator')
mock_desk.click_element.assert_called_with('another_locator')

def test_select_elements_from_context_menu_retry_desktop(self):
mock_desk = MagicMock()
mock_desk.mouse_over_and_context_click_element = MagicMock(side_effect=[NoSuchElementException, True, True])
DesktopLibrary.select_elements_from_context_menu(mock_desk, 'some_locator', 'another_locator')
mock_desk.click_element.mouse_over_and_context_click('some_locator')
mock_desk.click_element.assert_called_with('another_locator')

def test_select_elements_from_context_menu_retry_desktop_2(self):
mock_desk = MagicMock()
mock_desk.mouse_over_and_context_click_element = MagicMock(side_effect=[NoSuchElementException, NoSuchElementException, True, True])
DesktopLibrary.select_elements_from_context_menu(mock_desk, 'some_locator', 'another_locator')
mock_desk.click_element.mouse_over_and_context_click('some_locator')
mock_desk.click_element.assert_called_with('another_locator')

def test_select_elements_from_context_menu_retry_desktop_3(self):
mock_desk = MagicMock()
mock_desk.click_element = MagicMock(side_effect=[NoSuchElementException, NoSuchElementException, True, True])
DesktopLibrary.select_elements_from_context_menu(mock_desk, 'some_locator', 'another_locator')
mock_desk.click_element.mouse_over_and_context_click('some_locator')
mock_desk.click_element.assert_called_with('another_locator')

def test_select_elements_from_context_menu_no_desktop(self):
mock_desk = MagicMock()
DesktopLibrary.select_elements_from_context_menu(mock_desk, 'some_locator', 'another_locator')
mock_desk.click_element.mouse_over_and_context_click('some_locator')
mock_desk.click_element.assert_called_with('another_locator')

def test_wait_until_page_contains_private(self):
mock_desk = MagicMock()
DesktopLibrary._wait_until_page_contains(mock_desk, 'some_text', 5)
Expand Down
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "2.5.5"
VERSION = "2.5.6"

0 comments on commit 6619871

Please sign in to comment.