Skip to content

Instantly share code, notes, and snippets.

@emanlove
Created January 7, 2016 11:11
Show Gist options
  • Select an option

  • Save emanlove/f716d7425bc2974d30d4 to your computer and use it in GitHub Desktop.

Select an option

Save emanlove/f716d7425bc2974d30d4 to your computer and use it in GitHub Desktop.
Overriding methods of object within another RF Library
mkdir override
cd override
virtualenv -p /usr/bin/python2.7 --no-site-packages library-python27-env
source library-python27-env/bin/activate
pip install decorator docutils robotframework robotframework-selenium2library selenium
# create/copy SampleLibrary.py and sample.robot here as listed above
pybot -T --pythonpath . sample.robot
*** Settings ***
Library Selenium2Library
Library SampleLibrary
Test Teardown Close All Browsers
*** Test Cases ***
Check Binding Locator Override
Open Browser http://www.angularjs.org
Get Webelements {{Binding}}
import types
from robot.libraries.BuiltIn import BuiltIn
class SampleLibrary(object):
_s2l = BuiltIn().get_library_instance('Selenium2Library')
def __init__(self):
# override Selenium2Library's _find_by_default method
import pdb,sys; pdb.Pdb(stdout=sys.__stdout__).set_trace()
# self._s2l._element_finder._find_by_default = types.MethodType(self._override_function, self._s2l._element_finder)
self._s2l._element_finder._find_by_default = types.MethodType(self._find_by_default, self._s2l._element_finder)
return
def _find_by_binding(self, browser, criteria, tag, constrains):
# not yet implemented error
raise ValueError("Element locator with prefix '{{...}}' is not yet implemented.")
# def _override_function():
def _find_by_default(self, browser, criteria, tag, constrains):
if criteria.startswith('//'):
return self._s2l._element_finder._find_by_xpath(browser, criteria, tag, constraints)
elif criteria.startswith('{{'):
return self._find_by_binding(browser, criteria, tag, constraints)
return self._find_by_key_attrs(browser, criteria, tag, constraints)
@emanlove
Copy link
Author

emanlove commented Jan 7, 2016

I am trying to override a method on an object within another library. In particular I am trying to override the _find_by_default method on the Selenium2Library in a separate library. I have posted a sample library trying to override that method with its own [1]. But what I am doing isn't working. I am expecting to see

Sample                                                                       
==============================================================================
Check Binding Locator Override                                        | FAIL |
Element locator with prefix '{{...}}' is not yet implemented.

... but what I am getting is ...

Sample                                                                       
==============================================================================
Check Binding Locator Override                                        | FAIL |
ValueError: Element locator '{{Binding}}' did not match any elements.

I also have posted a sample test case as well as steps for setting up a sample development environment and script (linux) so anyone can repeat my work [1]. I have left in some debug code, for example a pdb set_trace statement for debugging. Also with the override method of using types.MethodTypes I wasn't sure if my override method needed to be the same name or not. So I have tried both ways and left the code there.

Also if anyone has any hints or tips for debugging (like using dir(self._s2l) for example to get the methods and objects on the s2l instance) that would be helpful. Thanks for any help or insights you might provide.

@emanlove
Copy link
Author

Reworking using some of @ombre42's suggestions

from Selenium2Library.locators import ElementFinder
from robot.libraries.BuiltIn import BuiltIn

class ngElementFinder(ElementFinder):
    def _find_by_default(self, browser, criteria, tag, constraints):
        if criteria.startswith('//'):
            return self._s2l._element_finder._find_by_xpath(browser, criteria, tag, constraints)
        elif criteria.startswith('{{'):
            return self._find_by_binding(browser, criteria, tag, constraints)
        return self._find_by_key_attrs(browser, criteria, tag, constraints)

    def _find_by_binding(self, browser, criteria, tag, constraints):
        # not yet implemented error
        raise ValueError("Element locator with prefix '{{...}}' is not yet implemented.")

class SampleLibrary(object):

    _s2l = BuiltIn().get_library_instance('Selenium2Library')

    def __init__(self):
        # override Selenium2Library's _find_by_default method
        #import pdb,sys; pdb.Pdb(stdout=sys.__stdout__).set_trace()
        self._s2l._element_finder = ngElementFinder()
        return

#    @property
#    def _s2l(self):
#        return BuiltIn().get_library_instance('Selenium2Library')```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment