22
33import os
44from collections import OrderedDict
5- import allure_commons
65
7- from allure_commons .model2 import TestResultContainer , TestResult , TestStepResult , TestAfterResult , TestBeforeResult , \
8- StatusDetails , Label , Link
9- from allure_commons .reporter import AllureReporter
10- from allure_commons .utils import now , uuid4 , md5 , host_tag
6+ import allure_commons
117from allure_commons .logger import AllureFileLogger
8+ from allure_commons .model2 import Label , Link , Status , StatusDetails , TestAfterResult , TestBeforeResult , TestResult , \
9+ TestResultContainer , TestStepResult
10+ from allure_commons .reporter import AllureReporter
1211from allure_commons .types import AttachmentType , LabelType , LinkType
1312from allure_commons .types import Severity
13+ from allure_commons .utils import host_tag , md5 , now , uuid4
1414from allure_commons .utils import platform_label
15- from robot .libraries .BuiltIn import BuiltIn
16- from allure_robotframework .types import RobotKeywordType , RobotLogLevel
1715from allure_robotframework import utils
1816from allure_robotframework .allure_listener import AllureListener
19-
20- from allure_robotframework .utils import allure_tags , allure_labels , allure_links
17+ from allure_robotframework .types import RobotKeywordType , RobotLogLevel
18+ from allure_robotframework .utils import allure_labels , allure_links , allure_tags
19+ from robot .libraries .BuiltIn import BuiltIn
2120
2221
2322# noinspection PyPep8Naming
2423class allure_robotframework (object ):
2524 ROBOT_LISTENER_API_VERSION = 2
2625 DEFAULT_OUTPUT_PATH = os .path .join ('output' , 'allure' )
27- LOG_MESSAGE_FORMAT = '{full_message}<p><b>[{level}]</b> {message}</p>'
28- FAIL_MESSAGE_FORMAT = '{full_message}<p style="color: red"><b>[{level}]</b> {message}</p>'
26+ LOG_MESSAGE_FORMAT = '<p><b>[{level}]</b> {message}</p>'
27+ FAIL_MESSAGE_FORMAT = '<p style="color: red"><b>[{level}]</b> {message}</p>'
28+ MAX_STEP_MESSAGE_COUNT = int (os .getenv ('ALLURE_MAX_STEP_MESSAGE_COUNT' , 0 ))
2929
3030 def __init__ (self , logger_path = DEFAULT_OUTPUT_PATH ):
3131 self .stack = []
@@ -66,14 +66,23 @@ def end_keyword(self, name, attributes):
6666 self .end_current_keyword (name , attributes )
6767
6868 def log_message (self , message ):
69+ message_item = {
70+ 'name' : message .get ('message' ),
71+ 'start' : now (),
72+ 'status' : Status .FAILED if message .get ('level' ) in RobotLogLevel .CRITICAL_LEVELS else Status .PASSED ,
73+ 'stop' : now ()
74+ }
75+
6976 level = message .get ('level' )
7077 if self ._previous_keyword_failed :
7178 self ._traceback_message = message .get ('message' )
7279 self ._previous_keyword_failed = False
7380 if level == RobotLogLevel .FAIL :
7481 self ._previous_keyword_failed = True
7582 self .reporter .get_item (self .stack [- 1 ]).statusDetails = StatusDetails (message = message .get ('message' ))
76- self .append_message_to_last_item_log (message , level )
83+ if not self .items_log .get (self .stack [- 1 ]):
84+ self .items_log [self .stack [- 1 ]] = []
85+ self .items_log [self .stack [- 1 ]].append ((message_item , level ))
7786
7887 def start_new_group (self , name , attributes ):
7988 uuid = uuid4 ()
@@ -135,9 +144,9 @@ def start_new_keyword(self, name, attributes):
135144 step_name = '{} = {}' .format (attributes .get ('assign' )[0 ], name ) if attributes .get ('assign' ) else name
136145 args = {
137146 'name' : step_name ,
138- 'description' : attributes .get ('doc' ),
139147 'parameters' : utils .get_allure_parameters (attributes .get ('args' )),
140- 'start' : now ()
148+ 'start' : now (),
149+ 'stop' : now ()
141150 }
142151 keyword_type = attributes .get ('type' )
143152 last_item = self .reporter .get_last_item ()
@@ -158,10 +167,14 @@ def start_new_keyword(self, name, attributes):
158167 def end_current_keyword (self , name , attributes ):
159168 uuid = self .stack .pop ()
160169 if uuid in self .items_log :
161- self .reporter .attach_data (uuid = uuid4 (),
162- body = self .items_log .pop (uuid ).replace ('\n ' , '<br>' ),
163- name = 'Keyword Log' ,
164- attachment_type = AttachmentType .HTML )
170+ keyword_logs = self .items_log .pop (uuid )
171+ if len (keyword_logs ) < self .MAX_STEP_MESSAGE_COUNT :
172+ self .create_message_steps (uuid , * keyword_logs )
173+ else :
174+ self .reporter .attach_data (uuid = uuid4 (),
175+ body = self .format_keyword_logs_to_attachment (* keyword_logs ),
176+ name = 'Keyword Log' ,
177+ attachment_type = AttachmentType .HTML )
165178 args = {
166179 'uuid' : uuid ,
167180 'status' : utils .get_allure_status (attributes .get ('status' )),
@@ -178,12 +191,22 @@ def end_current_keyword(self, name, attributes):
178191 return
179192 self .reporter .stop_step (** args )
180193
181- def append_message_to_last_item_log (self , message , level ):
182- full_message = self .items_log [self .stack [- 1 ]] if self .stack [- 1 ] in self .items_log else ''
183- message_format = self .FAIL_MESSAGE_FORMAT if level in RobotLogLevel .CRITICAL_LEVELS else self .LOG_MESSAGE_FORMAT
184- self .items_log [self .stack [- 1 ]] = message_format .format (full_message = full_message ,
185- level = message .get ('level' ),
186- message = message .get ('message' ))
194+ def format_keyword_logs_to_attachment (self , * steps ):
195+ full_message = ''
196+ for step , level in steps :
197+ message_format = self .FAIL_MESSAGE_FORMAT if level in RobotLogLevel .CRITICAL_LEVELS \
198+ else self .LOG_MESSAGE_FORMAT
199+ full_message += message_format .format (level = level ,
200+ message = step .get ('name' ).replace ('\n ' , '<br>' ))
201+ return full_message
202+
203+ def create_message_steps (self , parent_uuid , * steps ):
204+ for step , level in steps :
205+ uuid = uuid4 ()
206+ self .reporter .start_step (parent_uuid = parent_uuid ,
207+ uuid = uuid ,
208+ step = TestStepResult (** step ))
209+ self .reporter .stop_step (uuid = uuid )
187210
188211 def set_suite_link (self , metadata , uuid ):
189212 if metadata :
0 commit comments