From e99d5b93520eef4d638308da1d0cd9e7024b84a8 Mon Sep 17 00:00:00 2001 From: Connor Young Date: Thu, 1 Aug 2024 19:24:31 +1000 Subject: [PATCH 1/8] Testing outputting an image #47 --- .github/workflows/multi-platform-test.yml | 5 +- .gitignore | 11 ++- scripts/OutPutResultsToJsons.py | 101 ++++++++++++++++++++++ 3 files changed, 114 insertions(+), 3 deletions(-) diff --git a/.github/workflows/multi-platform-test.yml b/.github/workflows/multi-platform-test.yml index 0158f5b..7b2bbb1 100644 --- a/.github/workflows/multi-platform-test.yml +++ b/.github/workflows/multi-platform-test.yml @@ -111,7 +111,8 @@ jobs: shell: bash run: | pip install defusedxml - python "${{ github.workspace }}/scripts/OutPutResultsToJsons.py" "${{ github.workspace }}/scripts/junitout.xml" "Real Test" --json_output "${{ github.workspace }}/scripts/finalresult.json" --discord_json_output "${{ github.workspace }}/scripts/discordJson_output.json" --os "${{ runner.os }}" --compiler "${{ matrix.c_compiler }}" --event "${{ github.event_name }}" --author "${{ github.actor }}" --branch "${{ github.ref_name }}" + pip install pillow + python "${{ github.workspace }}/scripts/OutPutResultsToJsons.py" "${{ github.workspace }}/scripts/junitout.xml" "Real Test" --json_output "${{ github.workspace }}/scripts/finalresult.json" --discord_json_output "${{ github.workspace }}/scripts/discordJson_output.json" --out_image "${{ github.workspace }}/scripts/discrod_image.png" --os "${{ runner.os }}" --compiler "${{ matrix.c_compiler }}" --event "${{ github.event_name }}" --author "${{ github.actor }}" --branch "${{ github.ref_name }}" - name: Post results if: success() @@ -124,4 +125,4 @@ jobs: uses: tsickert/discord-webhook@v6.0.0 with: webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} - raw-data: ${{ github.workspace }}/scripts/discordJson_output.json \ No newline at end of file + filename: "${{ github.workspace }}/scripts/discrod_image.png" \ No newline at end of file diff --git a/.gitignore b/.gitignore index a2f4c78..f5e66c4 100644 --- a/.gitignore +++ b/.gitignore @@ -84,4 +84,13 @@ CMakeCache.txt bin/ obj/ *.spv -_deps/ \ No newline at end of file +_deps/ +scripts/ctestOutput.xml + +scripts/discord.json + +scripts/output.json + +scripts/testimage.png + +Testing/Temporary/ diff --git a/scripts/OutPutResultsToJsons.py b/scripts/OutPutResultsToJsons.py index 31964ab..6e29b9a 100644 --- a/scripts/OutPutResultsToJsons.py +++ b/scripts/OutPutResultsToJsons.py @@ -3,7 +3,9 @@ import time import argparse import os +from PIL import Image, ImageDraw, ImageFont from datetime import datetime, timezone +import re def xml_to_json(xml_file, tool_name): # Check if the file exists @@ -158,6 +160,97 @@ def json_to_discord_json(json_data, os_name, compiler, event, author, branch): return discord_json +def remove_markdown(text): + # Remove bold (**) and italic (*) formatting + text = re.sub(r'\*\*(.*?)\*\*', r'\1', text) + text = re.sub(r'\*(.*?)\*', r'\1', text) + + # Remove code blocks (```) + text = re.sub(r'```[\s\S]*?```', '', text) + + # Remove inline code (`) + text = re.sub(r'`(.*?)`', r'\1', text) + + # Remove emoji shortcuts + text = re.sub(r':([\w+-]+):', '', text) + + return text.strip() + +def create_dark_theme_test_results_image(json_data): + # Parse JSON data + data = json.loads(json_data) if isinstance(json_data, str) else json_data + content = remove_markdown(data['content']) + embeds = data['embeds'] + + # Set up image + width, height = 500, 600 + background_color = (45, 47, 49) # Dark gray + image = Image.new('RGB', (width, height), color=background_color) + draw = ImageDraw.Draw(image) + + # Load fonts (ensure you have these fonts or replace with available ones) + try: + title_font = ImageFont.truetype("arial.ttf", 24) + header_font = ImageFont.truetype("arial.ttf", 18) + body_font = ImageFont.truetype("arial.ttf", 14) + except IOError: + # Fallback to default font if Arial is not available + title_font = ImageFont.load_default() + header_font = ImageFont.load_default() + body_font = ImageFont.load_default() + + # Colors + white = (255, 255, 255) + light_gray = (200, 200, 200) + green = (0, 255, 0) + red = (255, 0, 0) + + # Draw title + draw.text((20, 20), "Test Results", font=title_font, fill=white) + + # Draw content + y = 60 + for line in content.split('\n'): + if ':' in line: + key, value = line.split(':', 1) + draw.text((20, y), key.strip() + ':', font=body_font, fill=white) + draw.text((150, y), value.strip(), font=body_font, fill=light_gray) + else: + draw.text((20, y), line, font=body_font, fill=white) + y += 25 + + # Draw embeds + for embed in embeds: + y += 10 + draw.text((20, y), embed['title'], font=header_font, fill=white) + y += 30 + + if embed['title'] == 'Test Summary': + for line in embed['description'].split('\n'): + if ':' in line: + key, value = line.split(':', 1) + draw.text((20, y), key.strip() + ':', font=body_font, fill=white) + color = green if 'Passed' in key else red if 'Failed' in key else light_gray + draw.text((150, y), value.strip(), font=body_font, fill=color) + else: + draw.text((20, y), line, font=body_font, fill=light_gray) + y += 25 + elif embed['title'] == 'Detailed Test Results': + lines = embed['description'].strip('```').split('\n')[1:] # Skip the first line + for line in lines: + parts = line.split() + if len(parts) >= 3: + draw.text((20, y), parts[0], font=body_font, fill=white) + status_color = green if parts[1] == 'passed' else red + draw.text((200, y), parts[1], font=body_font, fill=status_color) + draw.text((280, y), parts[2], font=body_font, fill=light_gray) + y += 25 + else: + for line in embed['description'].split('\n'): + draw.text((20, y), line, font=body_font, fill=light_gray) + y += 25 + + return image if __name__ == "__main__": @@ -166,6 +259,7 @@ def json_to_discord_json(json_data, os_name, compiler, event, author, branch): parser.add_argument('tool_name', help='Name of the testing tool.') parser.add_argument('--json_output', help='Path to the output JSON file.') parser.add_argument('--discord_json_output', help='Path to the output Discord JSON file.') + parser.add_argument('--image_out', help="Image to post to discord") parser.add_argument('--os', help="Runners operating system") parser.add_argument('--compiler', help="Runners compiler") parser.add_argument('--event', help="The event triggering the action") @@ -199,6 +293,13 @@ def json_to_discord_json(json_data, os_name, compiler, event, author, branch): json.dump(discord_json, discord_json_file, indent=2) print(f"Discord JSON output has been written to {discord_json_output_file}") + # Generate data + image = create_dark_theme_test_results_image(discord_json) + + # Create the image + os.makedirs(os.path.dirname(args.image_out), exist_ok=True) + image.save(args.image_out) + except FileNotFoundError as e: print(e) except Exception as e: From ca693aa483581f7864d1341ed6cd3e8221dc7be6 Mon Sep 17 00:00:00 2001 From: Connor Young Date: Thu, 1 Aug 2024 19:35:37 +1000 Subject: [PATCH 2/8] out_image I got the name the wrong way round #47 --- .github/workflows/multi-platform-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/multi-platform-test.yml b/.github/workflows/multi-platform-test.yml index 7b2bbb1..135a1ce 100644 --- a/.github/workflows/multi-platform-test.yml +++ b/.github/workflows/multi-platform-test.yml @@ -112,7 +112,7 @@ jobs: run: | pip install defusedxml pip install pillow - python "${{ github.workspace }}/scripts/OutPutResultsToJsons.py" "${{ github.workspace }}/scripts/junitout.xml" "Real Test" --json_output "${{ github.workspace }}/scripts/finalresult.json" --discord_json_output "${{ github.workspace }}/scripts/discordJson_output.json" --out_image "${{ github.workspace }}/scripts/discrod_image.png" --os "${{ runner.os }}" --compiler "${{ matrix.c_compiler }}" --event "${{ github.event_name }}" --author "${{ github.actor }}" --branch "${{ github.ref_name }}" + python "${{ github.workspace }}/scripts/OutPutResultsToJsons.py" "${{ github.workspace }}/scripts/junitout.xml" "Real Test" --json_output "${{ github.workspace }}/scripts/finalresult.json" --discord_json_output "${{ github.workspace }}/scripts/discordJson_output.json" --image_out "${{ github.workspace }}/scripts/discrod_image.png" --os "${{ runner.os }}" --compiler "${{ matrix.c_compiler }}" --event "${{ github.event_name }}" --author "${{ github.actor }}" --branch "${{ github.ref_name }}" - name: Post results if: success() From 97720b936dec7356e5ddc1b2e38af11313d4d30d Mon Sep 17 00:00:00 2001 From: Connor Young Date: Thu, 1 Aug 2024 19:50:32 +1000 Subject: [PATCH 3/8] Continue clean up #47 --- scripts/OutPutResultsToJsons.py | 37 +++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/scripts/OutPutResultsToJsons.py b/scripts/OutPutResultsToJsons.py index 6e29b9a..0b9bf60 100644 --- a/scripts/OutPutResultsToJsons.py +++ b/scripts/OutPutResultsToJsons.py @@ -161,18 +161,14 @@ def json_to_discord_json(json_data, os_name, compiler, event, author, branch): return discord_json def remove_markdown(text): - # Remove bold (**) and italic (*) formatting - text = re.sub(r'\*\*(.*?)\*\*', r'\1', text) - text = re.sub(r'\*(.*?)\*', r'\1', text) - - # Remove code blocks (```) - text = re.sub(r'```[\s\S]*?```', '', text) - - # Remove inline code (`) - text = re.sub(r'`(.*?)`', r'\1', text) - - # Remove emoji shortcuts - text = re.sub(r':([\w+-]+):', '', text) + # Remove markdown characters + text = re.sub(r'\*\*(.*?)\*\*', r'\1', text) # Bold + text = re.sub(r'\*(.*?)\*', r'\1', text) # Italics + text = re.sub(r'```[\s\S]*?```', '', text) # Code blocks + text = re.sub(r'`(.*?)`', r'\1', text) # Inline code + text = re.sub(r':([\w+-]+):', '', text) # Emoji shortcuts + text = re.sub(r'#', '', text) # Remove hash symbols + text = re.sub(r'[\u2600-\u26FF\u2700-\u27BF]', '', text) # Remove ASCII emojis return text.strip() @@ -180,6 +176,12 @@ def create_dark_theme_test_results_image(json_data): # Parse JSON data data = json.loads(json_data) if isinstance(json_data, str) else json_data content = remove_markdown(data['content']) + + # Apply markdown removal to each embed description + for embed in data['embeds']: + embed['title'] = remove_markdown(embed['title']) + embed['description'] = remove_markdown(embed['description']) + embeds = data['embeds'] # Set up image @@ -205,8 +207,8 @@ def create_dark_theme_test_results_image(json_data): green = (0, 255, 0) red = (255, 0, 0) - # Draw title - draw.text((20, 20), "Test Results", font=title_font, fill=white) + # # Draw title + # draw.text((20, 20), "Test Results", font=title_font, fill=white) # Draw content y = 60 @@ -216,13 +218,16 @@ def create_dark_theme_test_results_image(json_data): draw.text((20, y), key.strip() + ':', font=body_font, fill=white) draw.text((150, y), value.strip(), font=body_font, fill=light_gray) else: - draw.text((20, y), line, font=body_font, fill=white) + if 'Test Result' in line: + draw.text((20, 20), "Test Results", font=title_font, fill=white) + else: + draw.text((20, y), line, font=body_font, fill=white) y += 25 # Draw embeds for embed in embeds: y += 10 - draw.text((20, y), embed['title'], font=header_font, fill=white) + draw.text((20, y), remove_markdown(embed['title']), font=header_font, fill=white) y += 30 if embed['title'] == 'Test Summary': From e81f889988ffd701aec83176708cce26a68d14fd Mon Sep 17 00:00:00 2001 From: Connor Young Date: Thu, 1 Aug 2024 20:14:49 +1000 Subject: [PATCH 4/8] Getting there #47 --- scripts/OutPutResultsToJsons.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/OutPutResultsToJsons.py b/scripts/OutPutResultsToJsons.py index 0b9bf60..f7b8aa0 100644 --- a/scripts/OutPutResultsToJsons.py +++ b/scripts/OutPutResultsToJsons.py @@ -164,7 +164,7 @@ def remove_markdown(text): # Remove markdown characters text = re.sub(r'\*\*(.*?)\*\*', r'\1', text) # Bold text = re.sub(r'\*(.*?)\*', r'\1', text) # Italics - text = re.sub(r'```[\s\S]*?```', '', text) # Code blocks + #text = re.sub(r'```[\s\S]*?```', '', text) # Code blocks text = re.sub(r'`(.*?)`', r'\1', text) # Inline code text = re.sub(r':([\w+-]+):', '', text) # Emoji shortcuts text = re.sub(r'#', '', text) # Remove hash symbols @@ -185,7 +185,7 @@ def create_dark_theme_test_results_image(json_data): embeds = data['embeds'] # Set up image - width, height = 500, 600 + width, height = 500, 650 background_color = (45, 47, 49) # Dark gray image = Image.new('RGB', (width, height), color=background_color) draw = ImageDraw.Draw(image) From bdeb70c2bc9b2cd430d077fb3e63fa2a11bc66a2 Mon Sep 17 00:00:00 2001 From: Connor Young Date: Fri, 2 Aug 2024 09:26:19 +1000 Subject: [PATCH 5/8] Using the XML data rather than Json #47 --- scripts/OutPutResultsToJsons.py | 123 ++++++++++++++------------------ 1 file changed, 54 insertions(+), 69 deletions(-) diff --git a/scripts/OutPutResultsToJsons.py b/scripts/OutPutResultsToJsons.py index f7b8aa0..f158b04 100644 --- a/scripts/OutPutResultsToJsons.py +++ b/scripts/OutPutResultsToJsons.py @@ -160,32 +160,37 @@ def json_to_discord_json(json_data, os_name, compiler, event, author, branch): return discord_json -def remove_markdown(text): - # Remove markdown characters - text = re.sub(r'\*\*(.*?)\*\*', r'\1', text) # Bold - text = re.sub(r'\*(.*?)\*', r'\1', text) # Italics - #text = re.sub(r'```[\s\S]*?```', '', text) # Code blocks - text = re.sub(r'`(.*?)`', r'\1', text) # Inline code - text = re.sub(r':([\w+-]+):', '', text) # Emoji shortcuts - text = re.sub(r'#', '', text) # Remove hash symbols - text = re.sub(r'[\u2600-\u26FF\u2700-\u27BF]', '', text) # Remove ASCII emojis - - return text.strip() - -def create_dark_theme_test_results_image(json_data): - # Parse JSON data - data = json.loads(json_data) if isinstance(json_data, str) else json_data - content = remove_markdown(data['content']) - - # Apply markdown removal to each embed description - for embed in data['embeds']: - embed['title'] = remove_markdown(embed['title']) - embed['description'] = remove_markdown(embed['description']) - - embeds = data['embeds'] +def parse_test_results_from_file(file_path): + # Read the XML data from the file + with open(file_path, 'r', encoding='utf-8') as file: + xml_data = file.read() + + # Parse the XML data + root = ET.fromstring(xml_data) + + # Extract test suite information + test_suite_name = root.attrib.get('name', 'Test Suite') + tests = root.attrib.get('tests', '0') + failures = root.attrib.get('failures', '0') + skipped = root.attrib.get('skipped', '0') + time = root.attrib.get('time', '0') + + # Extract test case information + test_cases = [] + for testcase in root.findall('testcase'): + name = testcase.attrib.get('name') + time = testcase.attrib.get('time') + status = 'passed' if float(time) > 0 else 'failed' # Simplified logic + test_cases.append((name, status, time)) + + return test_suite_name, tests, failures, skipped, time, test_cases + +def create_dark_theme_test_results_image(file_path, os, compiler): + # Parse the XML data from the file + test_suite_name, tests, failures, skipped, time, test_cases = parse_test_results_from_file(file_path) # Set up image - width, height = 500, 650 + width, height = 500, 300 background_color = (45, 47, 49) # Dark gray image = Image.new('RGB', (width, height), color=background_color) draw = ImageDraw.Draw(image) @@ -207,54 +212,34 @@ def create_dark_theme_test_results_image(json_data): green = (0, 255, 0) red = (255, 0, 0) - # # Draw title - # draw.text((20, 20), "Test Results", font=title_font, fill=white) + # Draw title + draw.text((20, 20), "Test Results", font=title_font, fill=white) - # Draw content + # Set the test suite as the os and compiler + test_suite_name = f"{os}-{compiler}" + # Draw test suite information y = 60 - for line in content.split('\n'): - if ':' in line: - key, value = line.split(':', 1) - draw.text((20, y), key.strip() + ':', font=body_font, fill=white) - draw.text((150, y), value.strip(), font=body_font, fill=light_gray) - else: - if 'Test Result' in line: - draw.text((20, 20), "Test Results", font=title_font, fill=white) - else: - draw.text((20, y), line, font=body_font, fill=white) + draw.text((20, y), f"Test Suite: {test_suite_name}", font=body_font, fill=white) + y += 25 + draw.text((20, y), f"Total Tests: {tests}", font=body_font, fill=white) + y += 25 + draw.text((20, y), f"Failures: {failures}", font=body_font, fill=red if int(failures) > 0 else green) + y += 25 + draw.text((20, y), f"Skipped: {skipped}", font=body_font, fill=light_gray) + y += 25 + draw.text((20, y), f"Duration: {time}", font=body_font, fill=light_gray) + y += 40 + + # Draw test cases + draw.text((20, y), "Detailed Test Results", font=header_font, fill=white) + y += 30 + for name, status, duration in test_cases: + draw.text((20, y), name, font=body_font, fill=white) + status_color = green if status == 'passed' else red + draw.text((200, y), status, font=body_font, fill=status_color) + draw.text((280, y), duration, font=body_font, fill=light_gray) y += 25 - # Draw embeds - for embed in embeds: - y += 10 - draw.text((20, y), remove_markdown(embed['title']), font=header_font, fill=white) - y += 30 - - if embed['title'] == 'Test Summary': - for line in embed['description'].split('\n'): - if ':' in line: - key, value = line.split(':', 1) - draw.text((20, y), key.strip() + ':', font=body_font, fill=white) - color = green if 'Passed' in key else red if 'Failed' in key else light_gray - draw.text((150, y), value.strip(), font=body_font, fill=color) - else: - draw.text((20, y), line, font=body_font, fill=light_gray) - y += 25 - elif embed['title'] == 'Detailed Test Results': - lines = embed['description'].strip('```').split('\n')[1:] # Skip the first line - for line in lines: - parts = line.split() - if len(parts) >= 3: - draw.text((20, y), parts[0], font=body_font, fill=white) - status_color = green if parts[1] == 'passed' else red - draw.text((200, y), parts[1], font=body_font, fill=status_color) - draw.text((280, y), parts[2], font=body_font, fill=light_gray) - y += 25 - else: - for line in embed['description'].split('\n'): - draw.text((20, y), line, font=body_font, fill=light_gray) - y += 25 - return image @@ -299,7 +284,7 @@ def create_dark_theme_test_results_image(json_data): print(f"Discord JSON output has been written to {discord_json_output_file}") # Generate data - image = create_dark_theme_test_results_image(discord_json) + image = create_dark_theme_test_results_image(args.xml_file, args.os, args.compiler) # Create the image os.makedirs(os.path.dirname(args.image_out), exist_ok=True) From 3f522f5f02ca0c6bdcff53101de5257c5116d9b3 Mon Sep 17 00:00:00 2001 From: Connor Young Date: Fri, 2 Aug 2024 09:35:45 +1000 Subject: [PATCH 6/8] Improve image for Linux #47 --- scripts/OutPutResultsToJsons.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/OutPutResultsToJsons.py b/scripts/OutPutResultsToJsons.py index f158b04..3211b38 100644 --- a/scripts/OutPutResultsToJsons.py +++ b/scripts/OutPutResultsToJsons.py @@ -190,18 +190,19 @@ def create_dark_theme_test_results_image(file_path, os, compiler): test_suite_name, tests, failures, skipped, time, test_cases = parse_test_results_from_file(file_path) # Set up image - width, height = 500, 300 + width, height = 500, 350 background_color = (45, 47, 49) # Dark gray image = Image.new('RGB', (width, height), color=background_color) draw = ImageDraw.Draw(image) - # Load fonts (ensure you have these fonts or replace with available ones) + # Load fonts try: - title_font = ImageFont.truetype("arial.ttf", 24) - header_font = ImageFont.truetype("arial.ttf", 18) - body_font = ImageFont.truetype("arial.ttf", 14) + # Use DejaVuSans as it is commonly available across platforms + title_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 24) + header_font = ImageFont.truetype("DejaVuSans.ttf", 18) + body_font = ImageFont.truetype("DejaVuSans.ttf", 14) except IOError: - # Fallback to default font if Arial is not available + # Fallback to default font if not available title_font = ImageFont.load_default() header_font = ImageFont.load_default() body_font = ImageFont.load_default() @@ -215,8 +216,9 @@ def create_dark_theme_test_results_image(file_path, os, compiler): # Draw title draw.text((20, 20), "Test Results", font=title_font, fill=white) - # Set the test suite as the os and compiler + # Hard set the suite name test_suite_name = f"{os}-{compiler}" + # Draw test suite information y = 60 draw.text((20, y), f"Test Suite: {test_suite_name}", font=body_font, fill=white) From 57d99eb878b7b1dac027fff6ac884e05e40e16fa Mon Sep 17 00:00:00 2001 From: Connor Young Date: Fri, 2 Aug 2024 09:41:30 +1000 Subject: [PATCH 7/8] Handling for both OS's #47 --- scripts/OutPutResultsToJsons.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/scripts/OutPutResultsToJsons.py b/scripts/OutPutResultsToJsons.py index 3211b38..88124f0 100644 --- a/scripts/OutPutResultsToJsons.py +++ b/scripts/OutPutResultsToJsons.py @@ -197,10 +197,15 @@ def create_dark_theme_test_results_image(file_path, os, compiler): # Load fonts try: - # Use DejaVuSans as it is commonly available across platforms - title_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 24) - header_font = ImageFont.truetype("DejaVuSans.ttf", 18) - body_font = ImageFont.truetype("DejaVuSans.ttf", 14) + if os == "Windows": + title_font = ImageFont.truetype("arial.ttf", 24) + header_font = ImageFont.truetype("arial.ttf", 18) + body_font = ImageFont.truetype("arial.ttf", 14) + else: + # Use DejaVuSans as it is commonly available across platforms + title_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 24) + header_font = ImageFont.truetype("DejaVuSans.ttf", 18) + body_font = ImageFont.truetype("DejaVuSans.ttf", 14) except IOError: # Fallback to default font if not available title_font = ImageFont.load_default() From 54aff64c5bfbc1fe1e9507fa41c323372ec94315 Mon Sep 17 00:00:00 2001 From: Connor Young Date: Fri, 2 Aug 2024 09:56:32 +1000 Subject: [PATCH 8/8] Fixed incorrect time Closes #47 --- scripts/OutPutResultsToJsons.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/scripts/OutPutResultsToJsons.py b/scripts/OutPutResultsToJsons.py index 88124f0..1c9170f 100644 --- a/scripts/OutPutResultsToJsons.py +++ b/scripts/OutPutResultsToJsons.py @@ -173,21 +173,27 @@ def parse_test_results_from_file(file_path): tests = root.attrib.get('tests', '0') failures = root.attrib.get('failures', '0') skipped = root.attrib.get('skipped', '0') - time = root.attrib.get('time', '0') + + # Initialize the total time + total_time = 0.0 # Extract test case information test_cases = [] for testcase in root.findall('testcase'): name = testcase.attrib.get('name') - time = testcase.attrib.get('time') - status = 'passed' if float(time) > 0 else 'failed' # Simplified logic + time = float(testcase.attrib.get('time', '0')) + status = 'passed' if testcase.find('failure') is None else 'failed' test_cases.append((name, status, time)) - return test_suite_name, tests, failures, skipped, time, test_cases + # Accumulate total time + total_time += time + + return test_suite_name, tests, failures, skipped, total_time, test_cases + def create_dark_theme_test_results_image(file_path, os, compiler): # Parse the XML data from the file - test_suite_name, tests, failures, skipped, time, test_cases = parse_test_results_from_file(file_path) + test_suite_name, tests, failures, skipped, total_time, test_cases = parse_test_results_from_file(file_path) # Set up image width, height = 500, 350 @@ -234,7 +240,7 @@ def create_dark_theme_test_results_image(file_path, os, compiler): y += 25 draw.text((20, y), f"Skipped: {skipped}", font=body_font, fill=light_gray) y += 25 - draw.text((20, y), f"Duration: {time}", font=body_font, fill=light_gray) + draw.text((20, y), f"Duration: {total_time:.6f}", font=body_font, fill=light_gray) y += 40 # Draw test cases @@ -244,12 +250,11 @@ def create_dark_theme_test_results_image(file_path, os, compiler): draw.text((20, y), name, font=body_font, fill=white) status_color = green if status == 'passed' else red draw.text((200, y), status, font=body_font, fill=status_color) - draw.text((280, y), duration, font=body_font, fill=light_gray) + draw.text((280, y), f"{duration:.6f}", font=body_font, fill=light_gray) # Corrected here y += 25 return image - if __name__ == "__main__": parser = argparse.ArgumentParser(description='Convert XML test results to JSON and Discord markdown.') parser.add_argument('xml_file', help='Path to the XML file.')