Minras
Minras

Reputation: 4346

Send a keyword to another keyword as a parameter

I created a keyword which works similar to Wait Until Keyword Succeeds, so I want to send another keyword to it:

def keyword_expecting_keyword(self, func, *args):
    return func(*args)

def normal_keyword(self, arg):
    return arg

Now I expect to call keyword_expecting_keyword and pass normal_keyword as an argument:

Keyword Expecting Keyword    Normal Keyword    123

But when I do that, I get a TypeError: 'unicode' object is not callable, so instead of Normal Keyword reference robot sends a function name.

Note: if it matters, I use an old-old RobotFramework 1.2.3 (robot is v2.8, so it's OK, the ride GUI was v1.2.3)

Updated With Real Code:

Keywords code

class ElementKeywords(object):
    def has_text(self, element):
        return bool(self.get_element_property(element, 'text'))

    def wait_until_result(self, timeout, poll_period, func, *args):
        time_spent = 0
        timeout = convert_time(timeout)
        poll_period = convert_time(poll_period)
        result = False
        thrown_exception = None
        while True:
            try:
                result = func(*args)
                thrown_exception = None
            except Exception as exc:
                result = False
                thrown_exception = exc
            if result or poll_period > timeout or time_spent > timeout:
                break
            time_spent += poll_period
            time.sleep(poll_period)
        if result:
            return True
        if thrown_exception:
            raise thrown_exception

        msg = 'Failed to receive positive result from {func} in {timeout} ' \
              'seconds'.format(func=func.__name__, timeout=str(timeout))
        raise TimeoutError(msg)

Test case

*** Settings ***
Test Setup        Web Setup
Test Teardown     Web Teardown
Resource          web_resources.txt

*** Test Cases ***
Check Index
    [Tags]    US123456
    Web Login
    Clean Redis
    ${job_id}=    Create Pool
    Web Refresh
    ${data_pool_element}=    Get Element By Xpath    //div[@id="progress-pool"]/div[1]
    Wait Until Result    20    1    Has Text    ${data_pool_element}
    Validate Pool    ${job_id}

Stack Trace

20150723 14:42:02.293 :  INFO : 
//div[@id="progress-pki-pool"]/div[1]
(None, u'//div[@id="progress-pki-pool"]/div[1]')
20150723 14:42:02.293 : TRACE : Return: <selenium.webdriver.remote.webelement.WebElement object at 0x7f74173f2450>
20150723 14:42:02.294 :  INFO : ${pki_pool_element} = <selenium.webdriver.remote.webelement.WebElement object at 0x7f74173f2450>
20150723 14:42:02.295 : TRACE : Arguments: [ u'20' | u'1' | u'Has Text' | <selenium.webdriver.remote.webelement.WebElement object at 0x7f74173f2450> ]
20150723 14:42:23.315 :  FAIL : TypeError: 'unicode' object is not callable
20150723 14:42:23.316 : DEBUG : 
Traceback (most recent call last):
  File "/home/andrii/projects/automated-tests/library/keywords/element_keywords.py", line 88, in wait_until_result
    raise thrown_exception
20150723 14:42:23.317 : TRACE : Arguments: [  ]
20150723 14:42:23.317 : DEBUG : DELETE http://127.0.0.1:50355/hub/session/ee7b5402-a2fc-47fc-ade3-38c2c28cc208 {"sessionId": "ee7b5402-a2fc-47fc-ade3-38c2c28cc208"}
20150723 14:42:23.323 : DEBUG : Finished Request

Upvotes: 1

Views: 526

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 385970

func is passed in as a string, and you are trying to execute the string, which is why you get the error that you do. Simply put, you can't expect to do func(), it will never work because you aren't being passed a reference to a function.

What you need to do is get a handle to the built-in library, and use it to execute the keyword for you. I have no idea if this is possible with such an old version of robot.

The solution would look domething like this:

from robot.libraries.BuiltIn import BuiltIn
...
result = BuiltIn().run_keyword(func, *args)

The robot framework user guide mentions this in the section named Using BuiltIn library and Using other libraries directly

Upvotes: 1

Related Questions