diff --git a/src/Selenium2Library/keywords/_screenshot.py b/src/Selenium2Library/keywords/_screenshot.py index 7c2c8a480..8e824ccc8 100644 --- a/src/Selenium2Library/keywords/_screenshot.py +++ b/src/Selenium2Library/keywords/_screenshot.py @@ -8,7 +8,7 @@ class _ScreenshotKeywords(KeywordGroup): def __init__(self): - self._screenshot_index = 0 + self._screenshot_index = {} self._screenshot_path_stack = [] self.screenshot_root_directory = None @@ -17,49 +17,86 @@ def __init__(self): def set_screenshot_directory(self, path, persist=False): """Sets the root output directory for captured screenshots. - ``path`` argument specifies the absolute path where the screenshots should - be written to. If the specified ``path`` does not exist, it will be created. - Setting ``persist`` specifies that the given ``path`` should - be used for the rest of the test execution, otherwise the path will be restored - at the end of the currently executing scope. + ``path`` argument specifies the absolute path where the screenshots + should be written to. If the specified ``path`` does not exist, + it will be created. Setting ``persist`` specifies that the given + ``path`` should be used for the rest of the test execution, otherwise + the path will be restored at the end of the currently executing scope. """ path = os.path.abspath(path) self._create_directory(path) if persist is False: self._screenshot_path_stack.append(self.screenshot_root_directory) # Restore after current scope ends - utils.events.on('scope_end', 'current', self._restore_screenshot_directory) + utils.events.on('scope_end', 'current', + self._restore_screenshot_directory) self.screenshot_root_directory = path - def capture_page_screenshot(self, filename=None): + def capture_page_screenshot(self, + filename='selenium-screenshot-{index}.png'): """Takes a screenshot of the current page and embeds it into the log. - `filename` argument specifies the name of the file to write the - screenshot into. If no `filename` is given, the screenshot is saved into file - `selenium-screenshot-.png` under the directory where - the Robot Framework log file is written into. The `filename` is + ``filename`` argument specifies the name of the file to write the + screenshot into. If no ``filename`` is given, the screenshot is saved + into file _selenium-screenshot-{index}.png_ under the directory where + the Robot Framework log file is written into. The ``filename`` is also considered relative to the same directory, if it is not given in absolute format. If an absolute or relative path is given but the path does not exist it will be created. - `css` can be used to modify how the screenshot is taken. By default - the bakground color is changed to avoid possible problems with - background leaking when the page layout is somehow broken. + Starting from Selenium2Library 1.8 if ``filename`` contains _{index}_ + characters, it will be automatically replaced with running index. + The running index is unique for each different filename. The absolute + path of the saved screenshot is always returned and it does not depend + does the ``filename`` contain _{index}_. See example 1 and 2 for more + details. + + The _{index}_ is replaced with the actual index by using Python's + [https://docs.python.org/2/library/stdtypes.html#str.format| + str.format] method, and it can be formatted using the standard + [https://docs.python.org/2/library/string.html#format-string-syntax| + format string syntax]. The example 3 shows this by setting the width and + the fill character. + + If there is a need to write literal _{index}_ or if ``filename`` + contains _{_ or _}_ characters, then the braces must be doubled. + + Example 1: + | ${file1} = | Capture Page Screenshot | + | File Should Exist | ${OUTPUTDIR}${/}selenium-screenshot-1.png | + | Should Be Equal | ${file1} | ${OUTPUTDIR}${/}selenium-screenshot-1.png | + | ${file2} = | Capture Page Screenshot | + | File Should Exist | ${OUTPUTDIR}${/}selenium-screenshot-2.png | + | Should Be Equal | ${file2} | ${OUTPUTDIR}${/}selenium-screenshot-2.png | + + Example 2: + | ${file1} = | Capture Page Screenshot | ${OTHER_DIR}${/}other-{index}-name.png | + | ${file2} = | Capture Page Screenshot | ${OTHER_DIR}${/}some-other-name-{index}.png | + | ${file3} = | Capture Page Screenshot | ${OTHER_DIR}${/}other-{index}-name.png | + | File Should Exist | ${OTHER_DIR}${/}other-1-name.png | + | Should Be Equal | ${file1} | ${OTHER_DIR}${/}other-1-name.png | + | File Should Exist | ${OTHER_DIR}${/}some-other-name-1.png | + | Should Be Equal | ${file2} | ${OTHER_DIR}${/}some-other-name-1.png | + | File Should Exist | ${OTHER_DIR}${/}other-2-name.png | + | Should Be Equal | ${file3} | ${OTHER_DIR}${/}other-2-name.png | + + Example 3: + | Capture Page Screenshot | ${OTHER_DIR}${/}sc-{index:06}.png | + | File Should Exist | ${OTHER_DIR}${/}sc-000001.png | """ path, link = self._get_screenshot_paths(filename) self._create_directory(path) - if hasattr(self._current_browser(), 'get_screenshot_as_file'): - if not self._current_browser().get_screenshot_as_file(path): - raise RuntimeError('Failed to save screenshot ' + filename) + if not self._current_browser().get_screenshot_as_file(path): + raise RuntimeError('Failed to save screenshot ' + link) else: - if not self._current_browser().save_screenshot(path): - raise RuntimeError('Failed to save screenshot ' + filename) - + if not self._current_browser().save_screenshot(path): + raise RuntimeError('Failed to save screenshot ' + link) # Image is shown on its own row and thus prev row is closed on purpose self._html('' '' % (link, link)) + return path # Private def _create_directory(self, path): @@ -87,14 +124,17 @@ def _restore_screenshot_directory(self): self.screenshot_root_directory = self._screenshot_path_stack.pop() def _get_screenshot_paths(self, filename): - if not filename: - self._screenshot_index += 1 - filename = 'selenium-screenshot-%d.png' % self._screenshot_index - else: - filename = filename.replace('/', os.sep) - - screenshotDir = self._get_screenshot_directory() - logDir = self._get_log_dir() - path = os.path.join(screenshotDir, filename) - link = robot.utils.get_link_path(path, logDir) + filename = filename.format( + index=self._get_screenshot_index(filename)) + filename = filename.replace('/', os.sep) + screenshotdir = self._get_screenshot_directory() + logdir = self._get_log_dir() + path = os.path.join(screenshotdir, filename) + link = robot.utils.get_link_path(path, logdir) return path, link + + def _get_screenshot_index(self, filename): + if filename not in self._screenshot_index: + self._screenshot_index[filename] = 0 + self._screenshot_index[filename] += 1 + return self._screenshot_index[filename] diff --git a/test/acceptance/keywords/screenshots.robot b/test/acceptance/keywords/screenshots.robot index 571ac69b6..6e25887bc 100644 --- a/test/acceptance/keywords/screenshots.robot +++ b/test/acceptance/keywords/screenshots.robot @@ -7,9 +7,10 @@ Resource ../resource.robot Capture page screenshot to default location [Documentation] LOG 2:3 REGEXP: [Setup] Remove Files ${OUTPUTDIR}/selenium-screenshot-*.png - Capture Page Screenshot + ${file} = Capture Page Screenshot ${count} = Count Files In Directory ${OUTPUTDIR} selenium-screenshot-*.png Should Be Equal As Integers ${count} 1 + Should Be Equal ${file} ${OUTPUTDIR}${/}selenium-screenshot-1.png Click Link Relative Wait Until Page Contains Element tag=body Capture Page Screenshot @@ -38,11 +39,42 @@ Capture page screenshot to custom root directory [Documentation] Capture page screenshot to custom root directory [Setup] Remove Directory ${OUTPUTDIR}/custom-root recursive Set Screenshot Directory ${OUTPUTDIR}/custom-root - Capture Page Screenshot custom-root-screenshot.png + ${file} = Capture Page Screenshot custom-root-screenshot.png File Should Exist ${OUTPUTDIR}/custom-root/custom-root-screenshot.png + Should Be Equal ${file} ${OUTPUTDIR}${/}custom-root${/}custom-root-screenshot.png Ensure screenshot captures revert to default root directory [Documentation] Ensure screenshot captures revert to default root directory [Setup] Remove Files ${OUTPUTDIR}/default-root-screenshot.png Capture Page Screenshot default-root-screenshot.png File Should Exist ${OUTPUTDIR}/default-root-screenshot.png + +Capture page screenshot with unique index + [Setup] Remove Directory ${OUTPUTDIR}${/}screenshot-and-index recursive + ${file1} = Capture Page Screenshot ${OUTPUTDIR}${/}screenshot-and-index${/}other-{index}-name.png + ${file2} = Capture Page Screenshot ${OUTPUTDIR}${/}screenshot-and-index${/}some-other-name-{index}.png + ${file3} = Capture Page Screenshot ${OUTPUTDIR}${/}screenshot-and-index${/}other-{index}-name.png + File Should Exist ${OUTPUTDIR}${/}screenshot-and-index${/}other-1-name.png + Should Be Equal ${file1} ${OUTPUTDIR}${/}screenshot-and-index${/}other-1-name.png + File Should Exist ${OUTPUTDIR}${/}screenshot-and-index${/}some-other-name-1.png + Should Be Equal ${file2} ${OUTPUTDIR}${/}screenshot-and-index${/}some-other-name-1.png + File Should Exist ${OUTPUTDIR}${/}screenshot-and-index${/}other-2-name.png + Should Be Equal ${file3} ${OUTPUTDIR}${/}screenshot-and-index${/}other-2-name.png + +Capturing a page screenshot with two indexes should not cause an error + ${file} = Capture Page Screenshot ${OUTPUTDIR}${/}screenshot-and-index${/}two-{index}-in-{index}-name.png + File Should Exist ${OUTPUTDIR}${/}screenshot-and-index${/}two-1-in-1-name.png + Should Be Equal ${file} ${OUTPUTDIR}${/}screenshot-and-index${/}two-1-in-1-name.png + +Capture page screenshot with index formatting + Capture Page Screenshot ${OUTPUTDIR}${/}screenshot-and-index${/}format-{index:06}-name.png + Capture Page Screenshot ${OUTPUTDIR}${/}screenshot-and-index${/}format-{index:06}-name.png + File Should Exist ${OUTPUTDIR}${/}screenshot-and-index${/}format-000001-name.png + File Should Exist ${OUTPUTDIR}${/}screenshot-and-index${/}format-000002-name.png + +Capture page screenshot with escaped braces + ${file} = Capture Page Screenshot ${OUTPUTDIR}${/}screenshot-and-index${/}brackets-{{index}}-name.png + File Should Exist ${OUTPUTDIR}${/}screenshot-and-index${/}brackets-{index}-name.png + Should Be Equal ${file} ${OUTPUTDIR}${/}screenshot-and-index${/}brackets-{index}-name.png + ${file} = Capture Page Screenshot ${OUTPUTDIR}${/}screenshot-and-index${/}brackets-{{index-name.png + File Should Exist ${OUTPUTDIR}${/}screenshot-and-index${/}brackets-{index-name.png