Skip to content

Commit 9f87267

Browse files
committed
refactory: split robotframework's logic into more files
1 parent cbb3d07 commit 9f87267

15 files changed

+229
-212
lines changed

DebugLibrary/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
from .keywords import DebugKeywords
2+
from .version import VERSION
23

34
"""A debug library and REPL for RobotFramework."""
45

56

67
class DebugLibrary(DebugKeywords):
78
"""Debug Library for RobotFramework."""
9+
810
ROBOT_LIBRARY_SCOPE = 'GLOBAL'
11+
ROBOT_LIBRARY_VERSION = VERSION

DebugLibrary/cmdcompleter.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from prompt_toolkit.completion import Completer, Completion
22

3-
from .robotutils import parse_keyword
3+
from .robotkeyword import parse_keyword
44

55

66
class CmdCompleter(Completer):

DebugLibrary/debugcmd.py

+21-17
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import os
22

3+
from robot.api import logger
34
from robot.errors import ExecutionFailed, HandlerExecutionFailed
45

56
from .cmdcompleter import CmdCompleter
67
from .prompttoolkitcmd import PromptToolkitCmd
7-
from .robotutils import (SELENIUM_WEBDRIVERS, get_builtin_libs, get_keywords,
8-
get_lib_keywords, get_libs, get_libs_dict,
9-
get_robot_instance, match_libs,
10-
reset_robotframework_exception, run_keyword,
11-
start_selenium_commands)
8+
from .robotapp import get_robot_instance, reset_robotframework_exception
9+
from .robotkeyword import get_keywords, get_lib_keywords, run_keyword
10+
from .robotlib import get_builtin_libs, get_libs, get_libs_dict, match_libs
11+
from .robotselenium import SELENIUM_WEBDRIVERS, start_selenium_commands
12+
from .robotvar import assign_variable
1213
from .styles import (DEBUG_PROMPT_STYLE, get_debug_prompt_tokens, print_error,
1314
print_output)
1415

@@ -20,21 +21,23 @@ def run_robot_command(robot_instance, command):
2021
if not command:
2122
return
2223

24+
result = ''
2325
try:
2426
result = run_keyword(robot_instance, command)
25-
if result:
26-
head, message = result
27-
print_output(head, message)
2827
except ExecutionFailed as exc:
2928
print_error('! keyword:', command)
30-
print_error('!', exc.message)
29+
print_error('! execution failed:', str(exc))
3130
except HandlerExecutionFailed as exc:
3231
print_error('! keyword:', command)
33-
print_error('!', exc.full_message)
32+
print_error('! handler execution failed:', exc.full_message)
3433
except Exception as exc:
3534
print_error('! keyword:', command)
3635
print_error('! FAILED:', repr(exc))
3736

37+
if result:
38+
head, message = result
39+
print_output(head, message)
40+
3841

3942
class DebugCmd(PromptToolkitCmd):
4043
"""Interactive debug shell for robotframework."""
@@ -100,8 +103,7 @@ def get_completer(self):
100103
'Keyword[{0}.]: {1}'.format(keyword['lib'], keyword['doc']),
101104
))
102105

103-
cmd_completer = CmdCompleter(commands, self)
104-
return cmd_completer
106+
return CmdCompleter(commands, self)
105107

106108
def do_selenium(self, arg):
107109
"""Start a selenium webdriver and open url in browser you expect.
@@ -121,7 +123,8 @@ def complete_selenium(self, text, line, begin_idx, end_idx):
121123
"""Complete selenium command."""
122124
if len(line.split()) == 3:
123125
command, url, driver_name = line.lower().split()
124-
return [d for d in SELENIUM_WEBDRIVERS if d.startswith(driver_name)]
126+
return [driver for driver in SELENIUM_WEBDRIVERS
127+
if driver.startswith(driver_name)]
125128
elif len(line.split()) == 2 and line.endswith(' '):
126129
return SELENIUM_WEBDRIVERS
127130
return []
@@ -143,9 +146,9 @@ def do_libs(self, args):
143146
for lib in get_libs():
144147
print_output(' {}'.format(lib.name), lib.version)
145148
if lib.doc:
146-
print(' {}'.format(lib.doc.split('\n')[0]))
149+
logger.console(' {}'.format(lib.doc.split('\n')[0]))
147150
if '-s' in args:
148-
print(' {}'.format(lib.source))
151+
logger.console(' {}'.format(lib.source))
149152
print_output('<', 'Builtin libraries:')
150153
for name in sorted(get_builtin_libs()):
151154
print_output(' ' + name, '')
@@ -199,8 +202,9 @@ def do_docs(self, kw_name):
199202
for lib in get_libs():
200203
for keyword in get_lib_keywords(lib, long_format=True):
201204
if keyword['name'].lower() == kw_name.lower():
202-
print(keyword['doc'])
205+
logger.console(keyword['doc'])
203206
return
204-
print("could not find documentation for keyword {}".format(kw_name))
207+
208+
print_error('< not find keyword', kw_name)
205209

206210
do_d = do_docs

DebugLibrary/keywords.py

-4
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@
22

33
from .debugcmd import DebugCmd
44
from .styles import print_output
5-
from .version import VERSION
65
from .webdriver import get_remote_url, get_session_id, get_webdriver_remote
76

87

98
class DebugKeywords(object):
109
"""Debug Keywords for RobotFramework."""
1110

12-
ROBOT_LIBRARY_SCOPE = 'GLOBAL'
13-
ROBOT_LIBRARY_VERSION = VERSION
14-
1511
def debug(self):
1612
"""Open a interactive shell, run any RobotFramework keywords.
1713
File renamed without changes.

DebugLibrary/prompttoolkitcmd.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ class BaseCmd(cmd.Cmd):
1010
"""Basic REPL tool."""
1111

1212
def emptyline(self):
13-
"""By default Cmd runs last command if an empty line is entered.
14-
Disable it."""
13+
"""Do not repeat last command if press enter only."""
1514

1615
def do_exit(self, arg):
1716
"""Exit the interpreter. You can also use the Ctrl-D shortcut."""

DebugLibrary/robotapp.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
from robot.api import logger
3+
from robot.libraries.BuiltIn import BuiltIn
4+
from robot.running.signalhandler import STOP_SIGNAL_MONITOR
5+
6+
7+
def get_robot_instance():
8+
"""Get robotframework builtin instance as context."""
9+
return BuiltIn()
10+
11+
12+
def reset_robotframework_exception():
13+
"""Resume RF after press ctrl+c during keyword running."""
14+
if STOP_SIGNAL_MONITOR._signal_count:
15+
STOP_SIGNAL_MONITOR._signal_count = 0
16+
STOP_SIGNAL_MONITOR._running_keyword = True
17+
logger.info('Reset last exception of DebugLibrary')
18+
19+
20+
def assign_variable(robot_instance, variable_name, args):
21+
"""Assign a robotframework variable."""
22+
variable_value = robot_instance.run_keyword(*args)
23+
robot_instance._variables.__setitem__(variable_name, variable_value)
24+
return variable_value

DebugLibrary/robotkeyword.py

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import re
2+
3+
from robot.libdocpkg.model import LibraryDoc
4+
5+
from .memoize import memoize
6+
from .robotlib import ImportedLibraryDocBuilder, get_libs
7+
from .robotvar import assign_variable
8+
9+
try:
10+
from robot.variables.search import is_variable
11+
except ImportError:
12+
from robot.variables import is_var as is_variable # robotframework < 3.2
13+
14+
KEYWORD_SEP = re.compile(' +|\t')
15+
16+
17+
def parse_keyword(command):
18+
"""Split a robotframework keyword string."""
19+
return KEYWORD_SEP.split(command)
20+
21+
22+
@memoize
23+
def get_lib_keywords(library, long_format=False):
24+
"""Get keywords of imported library."""
25+
lib = ImportedLibraryDocBuilder().build(library)
26+
keywords = []
27+
for keyword in lib.keywords:
28+
if long_format:
29+
doc = keyword.doc
30+
else:
31+
doc = keyword.doc.split('\n')[0]
32+
keywords.append({
33+
'name': keyword.name,
34+
'lib': library.name,
35+
'doc': doc,
36+
})
37+
return keywords
38+
39+
40+
def get_keywords():
41+
"""Get all keywords of libraries."""
42+
for lib in get_libs():
43+
yield from get_lib_keywords(lib)
44+
45+
46+
def run_keyword(robot_instance, keyword):
47+
"""Run a keyword in robotframewrk environment."""
48+
if not keyword:
49+
return
50+
51+
keyword_args = parse_keyword(keyword)
52+
keyword = keyword_args[0]
53+
args = keyword_args[1:]
54+
55+
is_comment = keyword.strip().startswith('#')
56+
if is_comment:
57+
return
58+
59+
variable_name = keyword.rstrip('= ')
60+
if is_variable(variable_name):
61+
variable_only = not args
62+
if variable_only:
63+
display_value = ['Log to console', keyword]
64+
robot_instance.run_keyword(*display_value)
65+
else:
66+
variable_value = assign_variable(
67+
robot_instance,
68+
variable_name,
69+
args,
70+
)
71+
echo = '{0} = {1!r}'.format(variable_name, variable_value)
72+
return ('#', echo)
73+
else:
74+
output = robot_instance.run_keyword(keyword, *args)
75+
if output:
76+
return ('<', repr(output))

DebugLibrary/robotlib.py

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import re
2+
3+
from robot.libdocpkg.model import LibraryDoc
4+
from robot.libdocpkg.robotbuilder import KeywordDocBuilder, LibraryDocBuilder
5+
from robot.libraries import STDLIBS
6+
from robot.running.namespace import IMPORTER
7+
8+
9+
def get_builtin_libs():
10+
"""Get robotframework builtin library names."""
11+
return list(STDLIBS)
12+
13+
14+
def get_libs():
15+
"""Get imported robotframework library names."""
16+
return sorted(IMPORTER._library_cache._items, key=lambda _: _.name)
17+
18+
19+
def get_libs_dict():
20+
"""Get imported robotframework libraries as a name -> lib dict"""
21+
return {lib.name: lib for lib in IMPORTER._library_cache._items}
22+
23+
24+
def match_libs(name=''):
25+
"""Find libraries by prefix of library name, default all"""
26+
libs = [_.name for _ in get_libs()]
27+
matched = [_ for _ in libs if _.lower().startswith(name.lower())]
28+
return matched
29+
30+
31+
class ImportedLibraryDocBuilder(LibraryDocBuilder):
32+
33+
def build(self, lib):
34+
libdoc = LibraryDoc(
35+
name=lib.name,
36+
doc=self._get_doc(lib),
37+
doc_format=lib.doc_format,
38+
)
39+
libdoc.inits = self._get_initializers(lib)
40+
libdoc.keywords = KeywordDocBuilder().build_keywords(lib)
41+
return libdoc

DebugLibrary/robotselenium.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
from .robotkeyword import parse_keyword
3+
4+
SELENIUM_WEBDRIVERS = ['firefox', 'chrome', 'ie',
5+
'opera', 'safari', 'phantomjs', 'remote']
6+
7+
8+
def start_selenium_commands(arg):
9+
"""Start a selenium webdriver and open url in browser you expect.
10+
11+
arg: [<url> or google] [<browser> or firefox]
12+
"""
13+
yield 'import library SeleniumLibrary'
14+
15+
# Set defaults, overriden if args set
16+
url = 'http://www.google.com/'
17+
browser = 'firefox'
18+
if arg:
19+
args = parse_keyword(arg)
20+
if len(args) == 2:
21+
url, browser = args
22+
else:
23+
url = arg
24+
if '://' not in url:
25+
url = 'http://' + url
26+
27+
yield 'open browser %s %s' % (url, browser)

0 commit comments

Comments
 (0)