Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error importing SeleniumLibrary #55

Open
hskn opened this issue Jun 18, 2019 · 5 comments
Open

Error importing SeleniumLibrary #55

hskn opened this issue Jun 18, 2019 · 5 comments

Comments

@hskn
Copy link

hskn commented Jun 18, 2019

As a background, I have to use .net Robot Framework, because some complex testing libraries are .net based. So my idea was to use robotremoteserver to also utilize SeleniumLibrary (not supported by .net rf).

import sys
from robotremoteserver import RobotRemoteServer
from SeleniumLibrary import SeleniumLibrary

RobotRemoteServer(SeleniumLibrary())

This yields

RobotRemoteServer(SeleniumLibrary()) File "/usr/local/lib/python3.7/site-packages/robotremoteserver.py", line 73, in __init__ self._library = RemoteLibraryFactory(library) File "/usr/local/lib/python3.7/site-packages/robotremoteserver.py", line 259, in RemoteLibraryFactory return DynamicRemoteLibrary(library, get_keyword_names, run_keyword) File "/usr/local/lib/python3.7/site-packages/robotremoteserver.py", line 362, in __init__ HybridRemoteLibrary.__init__(self, library, get_keyword_names) File "/usr/local/lib/python3.7/site-packages/robotremoteserver.py", line 355, in __init__ StaticRemoteLibrary.__init__(self, library) File "/usr/local/lib/python3.7/site-packages/robotremoteserver.py", line 280, in __init__ self._names, self._robot_name_index = self._get_keyword_names(library) File "/usr/local/lib/python3.7/site-packages/robotremoteserver.py", line 285, in _get_keyword_names for name, kw in inspect.getmembers(library): File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/inspect.py", line 341, in getmembers value = getattr(object, key) File "/usr/local/lib/python3.7/site-packages/SeleniumLibrary/__init__.py", line 415, in driver raise NoOpenBrowser('No browser is open.') SeleniumLibrary.errors.NoOpenBrowser: No browser is open.

Similar error also with python 2.7.
According to Tatu Aaltonen and Pekka Klärck, there's a bug in remote server.

@pekkaklarck
Copy link
Member

pekkaklarck commented Aug 8, 2019

There are actually two bugs here: blindly using inspect.getmembers() with static libraries and the fact that this method is called at all with hybrid and dynamic libraries such as SeleniumLibrary. I explain them below.

= Using inspect.getmembers() with static libraries =

StaticRemoteLibrary uses inspect.getmembers(library) to find out what attributes the library has to check which of those attributes are actually method implementing keywords. The problem is that this method blindly accesses all properties of the library instance and SeleniunLibrary has some properties that can be successfully used only if a browser is open.

The problem can be avoided by not using inspect.getmembers() and instead getting attributes defined in the class (like properties) directly from the class, not from the instance. Both Robot Framework itself and PythonLibCore project do that and the same approach as used by the latter would probably work here as well.

One thing to take into account is that is that PythonLibCore only allows using new style classes (and modules) as libraries but there are no such restriction here. Thus the exact code linked above doesn't work, but using library.__class__ instead of type(instance) with old style classes ought to fix that.

= Hybdic and dynamic libraries calling inspect.getmembers() =

SeleniumLibrary is a dynamic library and they, similarly as hybrid libraries, expose their keywords using get_keyword_names. With them there's thus no need to get attributes from the library instance in the first place.

This problem happens because DynamicRemoteLibrary inherits HybridRemoteLibrary which inherits StaticRemoteLibrary, and StaticRemoteLibrary ends up calling inspect.getmembers() in its __init__. It's somewhat questionable is this whole inheritance hierarchy useful, but at least code should be changed so that attributes are only accessed with static libraries.

@pekkaklarck
Copy link
Member

Because there are two bugs, we probably should also have two bug reports. Fixing the problem with inspect.getmembers() would fix the issue with SeleniumLibrary, but avoiding calling that method in the first place with hybrid and dynamic libraries would be even better fix.

@mkorpela
Copy link
Member

Linking to forum post https://forum.robotframework.org/t/one-suite-setup-parallel-testlevelsplit/274/6?u=mkorpela

@mkorpela
Copy link
Member

281c282,283
<         self._names, self._robot_name_index = self._get_keyword_names(library)
---
>         self._names = None
>         self._robot_name_index = None
283c285
<     def _get_keyword_names(self, library):
---
>     def _construct_keyword_names(self):
286c288
<         for name, kw in inspect.getmembers(library):
---
>         for name, kw in inspect.getmembers(self._library):
295a298,299
>         if self._names is None:
>             self._names, self._robot_name_index = self._construct_keyword_names()
302a307,308
>         if self._names is None:
>             self._names, self._robot_name_index = self._construct_keyword_names()
378c384
<         args = [name, args, kwargs] if kwargs else [name, args]
---
>         args = [name, args, kwargs] if kwargs else [name, args, {}]

@mkorpela
Copy link
Member

Thats the changes I did to make dynamic libs work.

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

No branches or pull requests

3 participants