Skip to content

Commit 9eeada3

Browse files
authored
Add methot to replace Python format for PY2 and PY3 (robotframework#1468)
/path/{to}/file-{index}.log types of paths causes problems for Python format method. This is now fixed. Fixes robotframework#1452
1 parent 69e94b3 commit 9eeada3

File tree

6 files changed

+92
-5
lines changed

6 files changed

+92
-5
lines changed

atest/acceptance/keywords/screenshots.robot

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ Set Screenshot Directory set back to previous value
5353
Capture page screenshot with unique index
5454
[Setup] Remove Directory ${OUTPUTDIR}/screenshot-and-index recursive
5555
${file1} = Capture Page Screenshot ${OUTPUTDIR}/screenshot-and-index/other-{index}-name.png
56-
${file2} = Capture Page Screenshot ${OUTPUTDIR}/screenshot-and-index/some-other-name-{index}.png
56+
${file2} = Capture Page Screenshot ${OUTPUTDIR}/screenshot-and-index/some-{other}-name-{index}.png
5757
${file3} = Capture Page Screenshot ${OUTPUTDIR}/screenshot-and-index/other-{index}-name.png
5858
File Should Exist ${OUTPUTDIR}/screenshot-and-index/other-1-name.png
5959
Should Be Equal ${file1} ${OUTPUTDIR}${/}screenshot-and-index${/}other-1-name.png
60-
File Should Exist ${OUTPUTDIR}/screenshot-and-index/some-other-name-1.png
61-
Should Be Equal ${file2} ${OUTPUTDIR}${/}screenshot-and-index${/}some-other-name-1.png
60+
File Should Exist ${OUTPUTDIR}/screenshot-and-index/some-{other}-name-1.png
61+
Should Be Equal ${file2} ${OUTPUTDIR}${/}screenshot-and-index${/}some-{other}-name-1.png
6262
File Should Exist ${OUTPUTDIR}/screenshot-and-index/other-2-name.png
6363
Should Be Equal ${file3} ${OUTPUTDIR}${/}screenshot-and-index${/}other-2-name.png
6464

src/SeleniumLibrary/keywords/screenshot.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from SeleniumLibrary.base import LibraryComponent, keyword
2222
from SeleniumLibrary.utils import is_noney
23+
from SeleniumLibrary.utils.path_formatter import _format_path
2324

2425

2526
class ScreenshotKeywords(LibraryComponent):
@@ -130,7 +131,7 @@ def _get_screenshot_path(self, filename):
130131
index = 0
131132
while True:
132133
index += 1
133-
formatted = filename.format(index=index)
134+
formatted = _format_path(filename, index)
134135
path = os.path.join(directory, formatted)
135136
# filename didn't contain {index} or unique path was found
136137
if formatted == filename or not os.path.exists(path):

src/SeleniumLibrary/keywords/webdrivertools/webdrivertools.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
from SeleniumLibrary.utils import is_falsy, is_truthy, is_noney, is_string, PY3
3030
from SeleniumLibrary.keywords.webdrivertools.sl_file_detector import SelLibLocalFileDetector
31+
from SeleniumLibrary.utils.path_formatter import _format_path
32+
3133
if not PY3:
3234
FileNotFoundError = object
3335

@@ -285,7 +287,7 @@ def _get_log_path(self, log_file):
285287
return None
286288
index = 1
287289
while True:
288-
formatted = log_file.format(index=index)
290+
formatted = _format_path(log_file, index)
289291
path = os.path.join(self.log_dir, formatted)
290292
# filename didn't contain {index} or unique path was found
291293
if formatted == log_file or not os.path.exists(path):
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright 2008-2011 Nokia Networks
2+
# Copyright 2011-2016 Ryan Tomac, Ed Manlove and contributors
3+
# Copyright 2016- Robot Framework Foundation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
from SeleniumLibrary.base.robotlibcore import PY2
17+
18+
19+
# Cab be deleted when Python 2 is not anymore supported.
20+
def _format_path(file_path, index):
21+
if PY2:
22+
import string
23+
return string.Formatter().vformat(file_path, (), _SafeFormatter(index=index))
24+
return file_path.format_map(_SafeFormatter(index=index))
25+
26+
27+
class _SafeFormatter(dict):
28+
29+
def __missing__(self, key):
30+
return '{%s}' % key
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Different file paths.
2+
3+
0) /foo/file.log
4+
1) /foo/file-1.log
5+
2) /foo/file-0001.log
6+
3) /foo/file-{foo}.log
7+
4) /{foo}/file-1.log
8+
5) /foo/file-001.log
9+
6) /foo/1234-file-1234.log
10+
7) /foo/file-{in dex}.log
11+
8) /foo/file-{in@dex}.log
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import os
2+
3+
import pytest
4+
from robot.utils import JYTHON
5+
6+
try:
7+
from approvaltests.approvals import verify_all
8+
from approvaltests.reporters.generic_diff_reporter_factory import GenericDiffReporterFactory
9+
except ImportError:
10+
if JYTHON:
11+
verify = None
12+
GenericDiffReporterFactory = None
13+
else:
14+
raise
15+
16+
from SeleniumLibrary.utils.path_formatter import _format_path
17+
18+
19+
@pytest.fixture(scope='module')
20+
def reporter():
21+
if JYTHON:
22+
return None
23+
else:
24+
path = os.path.dirname(__file__)
25+
reporter_json = os.path.abspath(os.path.join(path, '..', 'approvals_reporters.json'))
26+
factory = GenericDiffReporterFactory()
27+
factory.load(reporter_json)
28+
return factory.get_first_working()
29+
30+
31+
@pytest.mark.skipif(JYTHON, reason='ApprovalTest does not work with Jython')
32+
def test_normal_file_path(reporter):
33+
results = []
34+
results.append(_format_path('/foo/file.log', 1))
35+
results.append(_format_path('/foo/file-{index}.log', 1))
36+
results.append(_format_path('/foo/file-{index}.log', '0001'))
37+
results.append(_format_path('/foo/file-{foo}.log', 1))
38+
results.append(_format_path('/{foo}/file-{index}.log', 1))
39+
results.append(_format_path('/foo/file-{index:03}.log', 1))
40+
results.append(_format_path('/foo/{index}-file-{index}.log', '1234'))
41+
results.append(_format_path('/foo/file-{in dex}.log', '1234'))
42+
results.append(_format_path('/foo/file-{in@dex}.log', '1234'))
43+
verify_all('Different file paths.', results, reporter=reporter)

0 commit comments

Comments
 (0)