Untitled
#!/usr/bin/env python3 import os import re import sys import xml.etree.ElementTree as ET def extract_special_msgs(log_xml_path): """ Parse the given Robot Framework log XML file and return a list of tuples: [(keyword_name, special_message), ... ] where `special_message` is the content from <msg> that contained '--- SPECIAL ---'. """ tree = ET.parse(log_xml_path) root = tree.getroot() # Robot Framework log.xml for version 7.1.1 typically has a top-level <robot> element # containing <suite> / <test> / <kw> trees, etc. namespace = '' # For simplicity, we assume no XML namespace is used. special_entries = [] # We can iterate all 'kw' nodes. Each <kw> can have <msg> children for kw in root.iter('kw'): # Attempt to get the "name" attribute of the keyword # or fallback to type if name is missing. keyword_name = kw.get('name') or kw.get('type', 'UNKNOWN_KEYWORD') # For each msg in this kw, check if it contains '--- SPECIAL ---' for msg in kw.findall('msg'): msg_text = (msg.text or "").strip() if '--- SPECIAL ---' in msg_text: # Store the entire <msg> text along with the parent kw name special_entries.append((keyword_name, msg_text)) return special_entries def insert_msgs_into_robot(robot_file_path, special_entries): """ Open the .robot file, locate lines that define the keywords in `special_entries`, and insert the messages right after the keyword definition line. `special_entries` is a list of (keyword_name, special_message). """ # Read .robot file as list of lines: with open(robot_file_path, 'r', encoding='utf-8') as f: lines = f.readlines() # We’ll keep a new list of lines to write out. new_lines = [] # Regex that might match a keyword definition in the *** Keywords *** section, # e.g. a line like: "My Keyword Name" # This is simplistic. In real usage, you might account for indentation, resource usage, etc. keyword_header_pattern = re.compile(r'^\s*([\w\s]+?)\s{2,}|\s*([\w\s]+?):$') # Explanation: # - Robot typically has two or more spaces or a colon after the keyword name. # - This pattern might not cover all variations, so adjust as needed. # Convert special_entries into a dict of keyword -> list of messages # so we can handle multiple messages for the same keyword. from collections import defaultdict keyword_msgs = defaultdict(list) for kw_name, msg in special_entries: keyword_msgs[kw_name].append(msg) in_keywords_section = False for line in lines: stripped_line = line.strip() # Are we entering the Keywords section? if stripped_line.upper().startswith('*** KEYWORDS ***'): in_keywords_section = True new_lines.append(line) continue if in_keywords_section: # If we see another *** Section *** or *** Test Cases ***, # that means we've exited the Keywords section. if re.match(r'^\*{3}\s*\w+\s*\*{3}$', stripped_line): # We are leaving the Keywords section in_keywords_section = False new_lines.append(line) continue # Check if this line starts a new keyword definition match = keyword_header_pattern.match(stripped_line) if match: # The "keyword_name" could appear in group(1) or group(2) possible_kw_name = match.group(1) or match.group(2) if possible_kw_name: # Clean up multiple spaces or trailing spaces possible_kw_name = re.sub(r'\s+', ' ', possible_kw_name).strip() new_lines.append(line) # If this line's keyword name matches something in our dict, insert the messages if possible_kw_name in keyword_msgs: for msg_text in keyword_msgs[possible_kw_name]: # Insert as a comment or a new line # E.g., we can do something like a Robot comment line: inserted_line = f" # Inserted from log.xml: {msg_text}\n" new_lines.append(inserted_line) # Once inserted, you might choose to remove them from the dict # (to avoid re-inserting) if you only do so once per file: del keyword_msgs[possible_kw_name] continue # Default case: just keep the original line new_lines.append(line) # Write the updated lines back to the file # (Optionally rename the original and create a new file, or back up first) with open(robot_file_path, 'w', encoding='utf-8') as f: f.writelines(new_lines) def main(): if len(sys.argv) < 3: print(f"Usage: {os.path.basename(sys.argv[0])} <path_to_log_xml> <path_to_robot_file>") sys.exit(1) log_xml = sys.argv[1] robot_file = sys.argv[2] # 1) Extract the special messages from the log.xml special_entries = extract_special_msgs(log_xml) if not special_entries: print("No '--- SPECIAL ---' messages found in the XML.") sys.exit(0) # 2) Insert the extracted messages into the .robot file insert_msgs_into_robot(robot_file, special_entries) print("Messages have been inserted into the .robot file.") if __name__ == "__main__": main()
Leave a Comment