Skip to content

Commit d88545d

Browse files
committed
Merge pull request #443 from rtomac/default-screenshot-dir
Added screenshot_root_directory argument and set_screenshot_directory keyword
2 parents 97e2e79 + ab1e481 commit d88545d

File tree

7 files changed

+97
-23
lines changed

7 files changed

+97
-23
lines changed

CHANGES.rst

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,20 @@ Release Notes
33

44
1.7.2 (Unreleased)
55
----------------
6+
- Added an argument called screenshot_root_directory that can be passed into S2L's
7+
constructor to specify where to store screenshots.
8+
- Added new keyword 'set_screenshot_directory' which can be used to set the output
9+
of screenshots.
10+
[zephraph]
11+
12+
- Added new keyword Input Text Into Prompt
613
- Modified 'get_alert_message' to accept a parameter 'dismiss' (defaults to true) which can be
714
used to prevent closing the alert message and instead will just return the alerts text.
815
Also created new keyword 'dismiss_alert' to dismiss (default) or confirm the alert without
916
reading the text of the alert.
1017
[KingWarin]
11-
12-
- Added new keyword Input Text Into Prompt
18+
19+
- Added new keyword Input Text Into Prompt
1320
[boakley][ekasteel]
1421

1522
- Fixed issue that caused tests to fail when selenium > 2.26

src/Selenium2Library/__init__.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,13 @@ class Selenium2Library(
135135
ROBOT_LIBRARY_SCOPE = 'GLOBAL'
136136
ROBOT_LIBRARY_VERSION = VERSION
137137

138-
def __init__(self, timeout=5.0, implicit_wait=0.0, run_on_failure='Capture Page Screenshot'):
138+
def __init__(self,
139+
timeout=5.0,
140+
implicit_wait=0.0,
141+
run_on_failure='Capture Page Screenshot',
142+
screenshot_root_directory=None
143+
):
144+
139145
"""Selenium2Library can be imported with optional arguments.
140146
141147
`timeout` is the default timeout used to wait for all waiting actions.
@@ -156,6 +162,9 @@ def __init__(self, timeout=5.0, implicit_wait=0.0, run_on_failure='Capture Page
156162
`Register Keyword To Run On Failure` keyword for more information about this
157163
functionality.
158164
165+
`screenshot_root_directory` specifies the default root directory that screenshots should be
166+
stored in. If not provided the default directory will be where robotframework places its logfile.
167+
159168
Examples:
160169
| Library `|` Selenium2Library `|` 15 | # Sets default timeout to 15 seconds |
161170
| Library `|` Selenium2Library `|` 0 `|` 5 | # Sets default timeout to 0 seconds and default implicit_wait to 5 seconds |
@@ -165,6 +174,7 @@ def __init__(self, timeout=5.0, implicit_wait=0.0, run_on_failure='Capture Page
165174
"""
166175
for base in Selenium2Library.__bases__:
167176
base.__init__(self)
177+
self.screenshot_root_directory = screenshot_root_directory
168178
self.set_selenium_timeout(timeout)
169179
self.set_selenium_implicit_wait(implicit_wait)
170180
self.register_keyword_to_run_on_failure(run_on_failure)

src/Selenium2Library/keywords/_logging.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import os
22
import sys
3-
from robot.libraries.BuiltIn import BuiltIn
43
from robot.api import logger
54
from keywordgroup import KeywordGroup
5+
from robot.libraries.BuiltIn import BuiltIn
66

77
class _LoggingKeywords(KeywordGroup):
88

@@ -13,6 +13,7 @@ def _debug(self, message):
1313

1414
def _get_log_dir(self):
1515
variables = BuiltIn().get_variables()
16+
1617
logfile = variables['${LOG FILE}']
1718
if logfile != 'NONE':
1819
return os.path.dirname(logfile)
Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,37 @@
1-
import os, errno
21
import robot
2+
import os, errno
3+
4+
from Selenium2Library import utils
35
from keywordgroup import KeywordGroup
6+
from robot.libraries.BuiltIn import RobotNotRunningError
7+
48

59
class _ScreenshotKeywords(KeywordGroup):
610

711
def __init__(self):
812
self._screenshot_index = 0
13+
self._screenshot_path_stack = []
14+
self.screenshot_root_directory = None
915

1016
# Public
1117

18+
def set_screenshot_directory(self, path, persist=False):
19+
"""Sets the root output directory for captured screenshots.
20+
21+
``path`` argument specifies the location to where the screenshots should
22+
be written to. If the specified ``path`` does not exist, it will be created.
23+
Setting ``persist`` specifies that the given ``path`` should
24+
be used for the rest of the test execution, otherwise the path will be restored
25+
at the end of the currently executing scope.
26+
"""
27+
self._create_directory(path)
28+
if persist is False:
29+
self._screenshot_path_stack.append(self.screenshot_root_directory)
30+
# Restore after current scope ends
31+
utils.events.on('scope_end', 'current', self._restore_screenshot_directory)
32+
33+
self.screenshot_root_directory = path
34+
1235
def capture_page_screenshot(self, filename=None):
1336
"""Takes a screenshot of the current page and embeds it into the log.
1437
@@ -18,22 +41,14 @@ def capture_page_screenshot(self, filename=None):
1841
the Robot Framework log file is written into. The `filename` is
1942
also considered relative to the same directory, if it is not
2043
given in absolute format. If an absolute or relative path is given
21-
but the path does not exist it will be created.
44+
but the path does not exist it will be created.
2245
2346
`css` can be used to modify how the screenshot is taken. By default
2447
the bakground color is changed to avoid possible problems with
2548
background leaking when the page layout is somehow broken.
2649
"""
2750
path, link = self._get_screenshot_paths(filename)
28-
29-
target_dir = os.path.dirname(path)
30-
if not os.path.exists(target_dir):
31-
try:
32-
os.makedirs(target_dir)
33-
except OSError as exc:
34-
if exc.errno == errno.EEXIST and os.path.isdir(target_dir):
35-
pass
36-
else: raise
51+
self._create_directory(path)
3752

3853
if hasattr(self._current_browser(), 'get_screenshot_as_file'):
3954
if not self._current_browser().get_screenshot_as_file(path):
@@ -47,14 +62,42 @@ def capture_page_screenshot(self, filename=None):
4762
'<img src="%s" width="800px"></a>' % (link, link))
4863

4964
# Private
65+
def _create_directory(self, path):
66+
target_dir = os.path.dirname(path)
67+
if not os.path.exists(target_dir):
68+
try:
69+
os.makedirs(target_dir)
70+
except OSError as exc:
71+
if exc.errno == errno.EEXIST and os.path.isdir(target_dir):
72+
pass
73+
else:
74+
raise
75+
76+
def _get_screenshot_directory(self):
77+
78+
# Use screenshot root directory if set
79+
if self.screenshot_root_directory is not None:
80+
return self.screenshot_root_directory
81+
82+
# Otherwise use RF's log directory
83+
try:
84+
return self._get_log_dir()
85+
86+
# Unless robotframework isn't running, then use working directory
87+
except RobotNotRunningError:
88+
return os.getcwd()
89+
90+
# should only be called by set_screenshot_directory
91+
def _restore_screenshot_directory(self):
92+
self.screenshot_root_directory = self._screenshot_path_stack.pop()
5093

5194
def _get_screenshot_paths(self, filename):
5295
if not filename:
5396
self._screenshot_index += 1
5497
filename = 'selenium-screenshot-%d.png' % self._screenshot_index
5598
else:
5699
filename = filename.replace('/', os.sep)
57-
logdir = self._get_log_dir()
58-
path = os.path.join(logdir, filename)
59-
link = robot.utils.get_link_path(path, logdir)
100+
screenshotDir = self._get_screenshot_directory()
101+
path = os.path.join(screenshotDir, filename)
102+
link = robot.utils.get_link_path(path, screenshotDir)
60103
return path, link

src/Selenium2Library/locators/elementfinder.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from Selenium2Library import utils
22
from robot.api import logger
33
from robot.utils import NormalizedDict
4-
from robot.libraries.BuiltIn import BuiltIn
54

65

76
class ElementFinder(object):
@@ -45,10 +44,7 @@ def register(self, strategy, persist):
4544

4645
if not persist:
4746
# Unregister after current scope ends
48-
suite = BuiltIn().get_variable_value('${SUITE NAME}')
49-
test = BuiltIn().get_variable_value('${TEST NAME}', '')
50-
scope = suite + '.' + test if test != '' else suite
51-
utils.events.on('scope_end', scope, self.unregister, strategy.name)
47+
utils.events.on('scope_end', 'current', self.unregister, strategy.name)
5248

5349
def unregister(self, strategy_name):
5450
if strategy_name in self._default_strategies:

src/Selenium2Library/utils/events/scope_event.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from event import Event
2+
from robot.libraries.BuiltIn import BuiltIn
23

34
class ScopeEvent(Event):
45
def __init__(self, scope, action, *args, **kwargs):
@@ -7,6 +8,11 @@ def __init__(self, scope, action, *args, **kwargs):
78
self.action_args = args
89
self.action_kwargs = kwargs
910

11+
if scope == 'current':
12+
suite = BuiltIn().get_variable_value('${SUITE NAME}')
13+
test = BuiltIn().get_variable_value('${TEST NAME}', '')
14+
self.scope = suite + '.' + test if test != '' else suite
15+
1016
def trigger(self, *args, **kwargs):
1117
if args[0] == self.scope:
1218
self.action(*self.action_args, **self.action_kwargs)

test/acceptance/keywords/screenshots.robot

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,14 @@ Capture page screenshot to non-existing directory
3131
[Setup] Remove Directory ${OUTPUTDIR}/screenshot recursive
3232
Capture Page Screenshot screenshot/test-screenshot.png
3333
File Should Exist ${OUTPUTDIR}/screenshot/test-screenshot.png
34+
35+
Capture page screenshot to custom root directory
36+
[Setup] Remove Directory ${OUTPUTDIR}/screenshot recursive
37+
Set Screenshot Directory ${OUTPUTDIR}/screenshot
38+
Capture Page Screenshot custom-root-screenshot.png
39+
File Should Exist ${OUTPUTDIR}/screenshot/custom-root-screenshot.png
40+
41+
Ensure screenshot captures revert to default root directory
42+
[Setup] Remove Files ${OUTPUTDIR}/default-root-screenshot.png
43+
Capture Page Screenshot default-root-screenshot.png
44+
File Should Exist ${OUTPUTDIR}/default-root-screenshot.png

0 commit comments

Comments
 (0)