SeleniumLibrary icon indicating copy to clipboard operation
SeleniumLibrary copied to clipboard

Value error: not enough values to unpack (expected 2, got 1)

Open hudderstrom opened this issue 3 years ago • 8 comments

Environment

Browser: firefox 78.12.0esr (64-bit) and chrome Version 92.0.4515.131 Browser driver: ChromeDriver 92.0.4515.107 Operating System: Windows10 Enterprise 1909 Libraries robotframework-seleniumlibrary 5.1.3 robotframework 4.1 robotframework-pythonlibcore 3.0.0

Steps to reproduce the issue & Error messages and additional information

I pasted a screenshot here to showcase how open browser keyword was used and what error it gave

Screenshot of the error

hudderstrom avatar Aug 17 '21 09:08 hudderstrom

@hudderstrom I can reproduce what you are seeing and see a point where the Library is not as helpful as it could be. From the screenshot you have this line

   Open Browser  www.amazon.com  browser=chrome  alias=None  remote_url=False  desired_capabilities=None  ff_profile_dir=None

The problem lies in that the library is reading your desired capabilities as the string None instead of Python None variable or ${None}. The same is true, with this keyword and the value for remote_url. Here you would want it to be ${False} instead of False. One last issue in the Open Browser line above is the url. As per the WebDriver spec you need the http:// prefix (or protocol) within the url. Changing the above to

   Open Browser  http://www.amazon.com  browser=chrome  alias=${None}  remote_url=${False}  desired_capabilities=${None}  ff_profile_dir=${None}

should work for you. I'll also note that the optional arguments of alias, remote_url_desired_capabilities, and ff_profile_dir as you are not changing them above from their default values, you could leave them out and have you line simply as

   Open Browser  http://www.amazon.com  browser=chrome

This would be the suggested way to call the keyword.

emanlove avatar Aug 29 '21 17:08 emanlove

SeleniumLibrary relies on Robot Framework to do the type conversion based on the type hints https://github.com/robotframework/SeleniumLibrary/blob/master/src/SeleniumLibrary/keywords/browsermanagement.py#L66

In short the first succeeding type conversion should win, but in this case it looks like None conversion doesn't work and argument is converted as string. Then the parsing to string fails.

If bug can not be found, then fault might be found from Robot Framework or PythonLibCore side.

aaltat avatar Aug 29 '21 18:08 aaltat

I wasn't sure if None would have gotten converted by the type hints. I was surprised by False not converting. I can dig a little further down.

emanlove avatar Aug 30 '21 01:08 emanlove

.. well None type is listed in the docs as a converted type and desired_capabilitie and ff_profile_dir have it listed as a possible type. Alias does not .. looks like I definitely need to dig deeper ..

emanlove avatar Aug 30 '21 01:08 emanlove

I tested with PLC and it looks it returns argument types as expected. I think this is bug in RF core side. @emanlove would you talk with Pekka how it should work. I am not familiar with that side of RF code.

aaltat avatar Sep 16 '21 20:09 aaltat

I did do some testing and I think this is problem with Robot Framework core side, see https://github.com/robotframework/robotframework/issues/4090 for explanation why I think so.

But in any case, bugs in upstream is pretty normal and perhaps we should fail the keyword if we receive wrong type in RF side. The difficult part is to fix and test all keywords where this might be possible, because there is many keywords which have similar type definition. @emanlove what you think?

aaltat avatar Sep 17 '21 20:09 aaltat

Well, Robot Framework converted works as designed and the only way currently is fix it in SeleniumLibrary side. So I guess is_noney should be used in this and other keywords arguments.

aaltat avatar Sep 17 '21 22:09 aaltat

Yeah, Robot's argument conversion works as designed. Unfortunately that design doesn't work great in this particular case, but as discussion in robotframework/robotframework#4090 explains it's still the design with the smaller amount of problems.

I personally don't consider this particular issue high severity. It only occurs if you explicitly use desired_capabilities=None but as @emanlove already explained it's easiest to just omit that altogether. Regardless the severity, this should obviously be fixed.

One possible solution would be changing the current signature from

desired_capabilities: Union[dict, None, str] = None

to

desired_capabilities: Optional[DesiredCapabilities] = None

This would obviously requiring adding new DesiredCapabilities class and then the code could be something like

if not isinstance(desired_capabilities, DesiredCapabilities):
    desired_capabilitires = DesiredCapabilities.from_input(desired_capabilities)

That from_input classmethod would then handle parsing the argument and return DesiredCapabilities object. I'm not entirely sure how desired capabilities are used. If they in the end are needed as a string, then str(desired_capabilities) could be used at that point.

The motivation of the above design is that in the future when RF supports custom argument converters (robotframework/robotframework#4088), it would be easy to use that functionality. That feature isn't yet fully designed, but most likely would only need @library(converters={DesiredCapabilities: DesiredCapabilities.from_input}) on library level or same config with @keyword if this is the only keyword using DesiredCapabilities.

pekkaklarck avatar Sep 20 '21 09:09 pekkaklarck