Skip to content

Commit daa3c1e

Browse files
authored
Merge pull request #198 from reportportal/develop
Release
2 parents 992baa9 + 89a043e commit daa3c1e

File tree

5 files changed

+71
-22
lines changed

5 files changed

+71
-22
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44
### Added
5+
- `timezone` command line argument for `post_report.py` script, by @HardNorth
6+
7+
## [5.5.5]
8+
### Added
59
- Issue [#192](https://github.com/reportportal/agent-Python-RobotFramework/issues/192): Robot link markup to Markdown conversion, by @HardNorth
610

711
## [5.5.4]

robotframework_reportportal/post_report.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
[--variable RP_MAX_POOL_SIZE:"50"]
3535
[--variable RP_MODE:"DEBUG"]
3636
[--loglevel CRITICAL|ERROR|WARNING|INFO|DEBUG]
37+
[--timezone "+03:00"|"EST"|"Europe/Warsaw"]
3738
[output.xml]
3839
3940
This script needs to be run within the same directory as the report xml file.
@@ -66,10 +67,9 @@ def process(infile="output.xml"):
6667
def main():
6768
argument_list = sys.argv[1:]
6869
short_options = "hv:"
69-
long_options = ["help", "variable=", "loglevel="]
70+
long_options = ["help", "variable=", "loglevel=", 'timezone=']
7071
try:
71-
arguments, values = getopt.getopt(argument_list, short_options,
72-
long_options)
72+
arguments, values = getopt.getopt(argument_list, short_options, long_options)
7373
except getopt.error:
7474
sys.exit(1)
7575

@@ -83,6 +83,8 @@ def main():
8383
elif current_argument == "--loglevel":
8484
numeric_level = getattr(logging, current_value.upper(), None)
8585
logging.basicConfig(level=numeric_level)
86+
elif current_argument == "--timezone":
87+
_variables['RP_TIME_ZONE_OFFSET'] = current_value
8688

8789
try:
8890
process(*values)

robotframework_reportportal/result_visitor.py

+24-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414

1515
import re
1616
import string
17-
from datetime import datetime
17+
import sys
18+
from datetime import datetime, timedelta, timezone
19+
20+
if sys.version_info >= (3, 9):
21+
from zoneinfo import available_timezones, ZoneInfo
1822
from typing import List, Pattern, Optional
1923
from urllib.parse import unquote
2024

@@ -26,13 +30,28 @@
2630
from robotframework_reportportal.variables import _variables
2731

2832
listener = listener.listener()
33+
if sys.version_info >= (3, 9):
34+
AVAILABLE_TIMEZONES: set[str] = available_timezones()
35+
else:
36+
AVAILABLE_TIMEZONES = set()
2937

3038

3139
def to_timestamp(time_str: str) -> Optional[str]:
32-
if time_str:
33-
dt = datetime.strptime(time_str, '%Y%m%d %H:%M:%S.%f')
34-
return str(int(dt.timestamp() * 1000))
35-
return None
40+
if not time_str:
41+
return None
42+
43+
timezone_offset_str: Optional[str] = _variables.get('RP_TIME_ZONE_OFFSET', None)
44+
dt = datetime.strptime(time_str, '%Y%m%d %H:%M:%S.%f')
45+
46+
if timezone_offset_str:
47+
if timezone_offset_str in AVAILABLE_TIMEZONES:
48+
tz = ZoneInfo(timezone_offset_str)
49+
dt = dt.replace(tzinfo=tz)
50+
else:
51+
hours, minutes = map(int, timezone_offset_str.split(':'))
52+
offset = timedelta(hours=hours, minutes=minutes)
53+
dt = dt.replace(tzinfo=timezone(offset))
54+
return str(int(dt.timestamp() * 1000))
3655

3756

3857
class RobotResultsVisitor(ResultVisitor):

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from setuptools import setup
1919

2020

21-
__version__ = '5.5.5'
21+
__version__ = '5.5.6'
2222

2323

2424
def read_file(fname):

tests/unit/test_result_visitor.py

+37-13
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,47 @@
1313
limitations under the License
1414
"""
1515

16+
import sys
1617
import pytest
1718

19+
from robotframework_reportportal.result_visitor import to_timestamp
20+
from robotframework_reportportal.variables import _variables
1821

19-
class TestResultVisitorTest:
2022

21-
def test_parse_message_no_img_tag(self, visitor):
22-
with pytest.raises(AttributeError):
23-
visitor.parse_message('usual test comment without image')
23+
def test_parse_message_no_img_tag(visitor):
24+
with pytest.raises(AttributeError):
25+
visitor.parse_message('usual test comment without image')
2426

25-
def test_parse_message_bad_img_tag(self, visitor):
26-
with pytest.raises(AttributeError):
27-
visitor.parse_message('<img src=\'bad.html.img>')
2827

29-
def test_parse_message_contains_image(self, visitor):
30-
assert ['src="any.png"', 'any.png'] == visitor.parse_message(
31-
'<img alt="" src="any.png" />')
28+
def test_parse_message_bad_img_tag(visitor):
29+
with pytest.raises(AttributeError):
30+
visitor.parse_message('<img src=\'bad.html.img>')
3231

33-
def test_parse_message_contains_image_with_space(self, visitor):
34-
assert ['src="any%20image.png"', 'any image.png'] == \
35-
visitor.parse_message('<img alt="" src="any%20image.png" />')
32+
33+
def test_parse_message_contains_image(visitor):
34+
assert ['src="any.png"', 'any.png'] == visitor.parse_message(
35+
'<img alt="" src="any.png" />')
36+
37+
38+
def test_parse_message_contains_image_with_space(visitor):
39+
assert ['src="any%20image.png"', 'any image.png'] == \
40+
visitor.parse_message('<img alt="" src="any%20image.png" />')
41+
42+
43+
TIMESTAMP_TEST_CASES = [
44+
('20240920 00:00:00.000', '+3:00', '1726779600000'),
45+
('20240919 18:00:00.000', '-3:00', '1726779600000')
46+
]
47+
48+
if sys.version_info >= (3, 9):
49+
TIMESTAMP_TEST_CASES += [
50+
('20240919 23:00:00.000', 'Europe/Warsaw', '1726779600000'),
51+
('20240920 00:00:00.000', 'UTC', '1726790400000'),
52+
('20240919 19:00:00.000', 'EST', '1726790400000')
53+
]
54+
55+
56+
@pytest.mark.parametrize('time_str, time_shift, expected', TIMESTAMP_TEST_CASES)
57+
def test_time_stamp_conversion(time_str, time_shift, expected):
58+
_variables['RP_TIME_ZONE_OFFSET'] = time_shift
59+
assert to_timestamp(time_str) == expected

0 commit comments

Comments
 (0)