Untitled
unknown
plain_text
9 months ago
5.5 kB
5
Indexable
#!/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()Editor is loading...
Leave a Comment