Skip to content

Commit

Permalink
Redesigned test cases for Issue damies13#37 and Issue damies13#38 to …
Browse files Browse the repository at this point in the history
…make them more readable and resistant to changes.

They are now written in the same style as Issue damies13#36 Test Case.
  • Loading branch information
ArekKuczynski committed Nov 30, 2024
1 parent 7f09b19 commit 5f98016
Show file tree
Hide file tree
Showing 101 changed files with 796 additions and 980 deletions.
349 changes: 347 additions & 2 deletions Tests/Regression/Reporter/GUI_Common.robot

Large diffs are not rendered by default.

1,219 changes: 266 additions & 953 deletions Tests/Regression/Reporter/GUI_Features.robot

Large diffs are not rendered by default.

138 changes: 121 additions & 17 deletions Tests/Regression/Reporter/read_docx.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import subprocess

from docx import Document
import docx
from docx.oxml.shared import OxmlElement, qn


Expand All @@ -22,7 +23,7 @@ def read_paragraphs_docx_file(docx_path: str) -> dict:
if current_heading:
doc_sections[current_heading].append(paragraph.text.strip())
else:
doc_sections.setdefault('No Heading', []).append(paragraph.text.strip())
doc_sections.setdefault('Cover', []).append(paragraph.text.strip())

return doc_sections

Expand Down Expand Up @@ -53,6 +54,73 @@ def update_table_of_contents(docx_path: str):
doc.save(docx_path)


def extract_docx_images_under_heading(heading:str, docx_path:str, output_folder:str, debug=False) -> list:
"""
Extract images from a DOCX file, including images inside tables,
and associate them to the provided heading.
"""
doc = Document(docx_path)
if not os.path.exists(output_folder):
os.makedirs(output_folder)

image_counter = 1
current_heading_name = None
image_list = []

def extract_images_from_run(run, heading, output_folder):
"""Extract images from a run and save them to the given output folder."""
nonlocal image_counter

if run.element.xpath('.//w:drawing'):
for rel in run.element.xpath('.//a:blip/@r:embed'):
part = doc.part.related_parts[rel]

image_name = f"{heading.replace(" ", "_")}_{image_counter}_image.png"
image_path = os.path.join(output_folder, image_name)

with open(image_path, 'wb') as img_file:
img_file.write(part.blob)

print(f"DOCX RFSwarm report image saved as: {image_name}") if debug else 0
image_list.append(image_name)
image_counter += 1

for inner_obj in doc.iter_inner_content():
image_counter = 1

if isinstance(inner_obj, docx.text.paragraph.Paragraph):
paragraph = inner_obj
if paragraph.style.name.startswith("Heading"):
heading_name = paragraph.text.strip()
heading_name_splitted = heading_name.split(" ", maxsplit=1)
current_heading_name = heading_name_splitted[1]

if current_heading_name == heading:
for run in paragraph.runs:
extract_images_from_run(run, current_heading_name, output_folder)

elif isinstance(inner_obj, docx.table.Table):
if current_heading_name == heading:
table = inner_obj
def iter_unique_row_cells(row):
"""Generate cells in given row skipping empty grid cells."""
last_cell_tc = None
for cell in row.cells:
this_cell_tc = cell._tc
if this_cell_tc is last_cell_tc:
continue
last_cell_tc = this_cell_tc
yield cell

for row in table.rows:
for cell in iter_unique_row_cells(row):
for paragraph in cell.paragraphs:
for run in paragraph.runs:
extract_images_from_run(run, current_heading_name, output_folder)

return image_list


def extract_images_from_docx(docx_path: str, output_folder: str) -> list:
"""
Extract all images from DOCX one by one.
Expand All @@ -71,20 +139,16 @@ def extract_images_from_docx(docx_path: str, output_folder: str) -> list:

with open(os.path.join(output_folder, img_name), "wb") as img_file:
img_file.write(img_data)
print(f"DOCX RFSwarm raport image saved as: {img_name}")
print(f"DOCX RFSwarm report image saved as: {img_name}")
saved_images.append(img_name)

return saved_images


def extract_tables_from_docx(docx_path: str) -> list:
def extract_table_from_docx(docx_table_obj: docx.table.Table) -> list:
"""
Extract all tables from DOCX one by one.
Returns nested lists of tables.
Note: For RFSwarm DOCX raport the first value of each row will be empty.
Extract table from docx.table.Table object as nested list.
"""
doc = Document(docx_path)
tables = []

def iter_unique_row_cells(row):
"""Generate cells in given row skipping empty grid cells."""
Expand All @@ -96,16 +160,14 @@ def iter_unique_row_cells(row):
last_cell_tc = this_cell_tc
yield cell

for table in doc.tables:
table_data = []
for row in table.rows:
row_data = []
for cell in iter_unique_row_cells(row):
row_data.append(cell.text)
table_data.append(row_data)
tables.append(table_data)
table_data = []
for row in docx_table_obj.rows:
row_data = []
for cell in iter_unique_row_cells(row):
row_data.append(cell.text)
table_data.append(row_data)

return tables
return table_data


def sort_docx_images(docx_images: list) -> list:
Expand All @@ -114,3 +176,45 @@ def natural_sort_key(filename):
return [int(text) if text.isdigit() else text for text in re.split(r'(\d+)', filename)]

return sorted(docx_images, key=natural_sort_key)


def read_docx_file(docx_path: str, debug=False) -> dict:
"""
Read the docx file in terms of text and table content.
Saved data is saved as:
dict = {"Heading 1" = {"text" = ["line 1", "line 2", ...], "table" = [[row 1], [row 2], ...] }, ...}
"""
doc = Document(docx_path)
doc_data = dict()

current_heading_name = None

for inner_obj in doc.iter_inner_content():
if isinstance(inner_obj, docx.text.paragraph.Paragraph):
paragraph = inner_obj
if paragraph.style.name.startswith('Heading'):
heading_name = paragraph.text.strip()
heading_name_splitted = heading_name.split(" ", maxsplit=1)
current_heading_name = heading_name_splitted[1]
doc_data.setdefault(current_heading_name, {"text":[], "table":[]})

elif paragraph.text.strip():
if current_heading_name:
print(paragraph.text.strip())
doc_data[current_heading_name]["text"].append(paragraph.text.strip())
else:
print(paragraph.text.strip())
doc_data.setdefault("Cover", {"text":[]})
doc_data["Cover"]["text"].append(paragraph.text.strip())

elif isinstance(inner_obj, docx.table.Table):
table = inner_obj
table_list = extract_table_from_docx(table)
doc_data[current_heading_name]["table"] = table_list

if debug:
for k in doc_data:
print(" -",k,":")
print(doc_data[k], end="\n\n\n")

return doc_data
44 changes: 36 additions & 8 deletions Tests/Regression/Reporter/read_xlsx.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,28 @@ def read_all_xlsx_text_data(xlsx_path: str) -> list:
return xlsx_tables


def read_xlsx_text_data_from_sheet(xlsx_path: str, sheet_name: str) -> list:
def get_xlsx_sheet_by_name(xlsx_path: str, sheet_name: str) -> list:
"""
Read xlsx text data from given xlsx sheet.
Find the full name of the xlsx sheet by its name.
For example: given: "Contents tables" output: "4 Contents tables".
"""
all_excel_data_frame = read_excel(xlsx_path, sheet_name, keep_default_na=False, na_values=['NaN'])
xlsx_sheets = load_workbook(xlsx_path, keep_links=False).sheetnames
for sheet in xlsx_sheets:
if " " in list(sheet):
sheet_fragmented = sheet.split(" ", maxsplit=1)
if sheet_fragmented[1] == sheet_name:
return sheet

return 0


def read_xlsx_text_data_from_sheet(xlsx_path: str, sheet: str, start_at=None, stop_at=None) -> list:
"""
Read xlsx text data from the given xlsx sheet.
start_at - start from the specified string, but do not include it.
stop_at - end at specified string, and don't include it.
"""
all_excel_data_frame = read_excel(xlsx_path, sheet, keep_default_na=False, na_values=['NaN'])
excel_data_list = all_excel_data_frame.values.tolist()

for row_n in range(len(excel_data_list) - 1, -1, -1):
Expand All @@ -39,18 +56,29 @@ def read_xlsx_text_data_from_sheet(xlsx_path: str, sheet_name: str) -> list:
if len(excel_data_list[row_n]) == 0:
excel_data_list.pop(row_n)

return excel_data_list
start_index = 0
end_index = len(excel_data_list)
if start_at is not None:
for row_n in range(0, len(excel_data_list)):
if start_at in excel_data_list[row_n]:
start_index = row_n + 1
if stop_at is not None:
for row_n in range(0, len(excel_data_list)):
if stop_at in excel_data_list[row_n]:
end_index = row_n

return excel_data_list[start_index : end_index]


def extract_image_from_xlsx_sheet(xlsx_path: str, xlsx_sheet: str, cell_id: str, output_folder: str, show_image: bool = False):
def extract_image_from_xlsx_sheet(xlsx_path: str, sheet: str, cell_id: str, output_folder: str, show_image: bool = False):
"""
Extract an image from XLSX file from a given cell in specified sheet.
Returns name of the saved image.
"""
wb = load_workbook(xlsx_path, keep_links=False)
sheet = wb[xlsx_sheet]
sheet_obj = wb[sheet]
try:
image_loader = SheetImageLoader(sheet)
image_loader = SheetImageLoader(sheet_obj)
except Exception as e:
raise AssertionError("Error in SheetImageLoader:", e)
try:
Expand All @@ -60,7 +88,7 @@ def extract_image_from_xlsx_sheet(xlsx_path: str, xlsx_sheet: str, cell_id: str,
return 0
if show_image:
image.show()
img_name = (xlsx_sheet + "_" + cell_id + "_image.png").replace(" ", "_")
img_name = (sheet + "_" + cell_id + "_image.png").replace(" ", "_")

if not os.path.exists(output_folder):
os.makedirs(output_folder)
Expand Down
26 changes: 26 additions & 0 deletions Tests/Regression/Reporter/report_expected_data.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Cover:
text: ['quickdemo', '2023-07-28 07:42 - 07:50']

Contents contents:
text: ['This is Heading', 'Contents contents', 'Contents graphs', 'Contents tables', 'Note', 'Second Note', 'Third Note',
'Data Graph Left Metric', 'Data Graph Left Result', 'Data Graph Left Result FAIL', 'Data Graph Left Result TPS',
Expand All @@ -17,6 +20,9 @@ Contents tables:
Note:
text: ['Hello i am a simple and obvious note :-)', 'This is just second line.', ' - first line', ' - second line', ' - third line', ""]

Note DOCX:
text: ['Hello i am a simple and obvious note :-)', 'This is just second line.', '- first line', '- second line', '- third line']

Second Note:
text: ['This is my second note.']

Expand Down Expand Up @@ -73,6 +79,26 @@ Data Table ResultSummary:
mid_row: ['_', 'Odoo Open Receipt', 'None', 'None', 'None', 'None', 'None', '0', '0', '1']
upper_mid_row: ['_', 'Returns the number of elements matching ``locator``.', '0.012', '0.012', 'None', '0.012', 'None', '1', '0', '2']

Data Table ResultSummary XLSX: # special version for XLSX
length: 42
header: ['Result Name', 'Minimum', 'Average', '90%ile', 'Maximum', 'Std. Dev.', 'Pass', 'Fail', 'Other']
rows_numbers: [1, -1, 11, 21, 31]
first_row: [':example: ''John Doe''', '0.001', '0.001', 'None', '0.001', '0.0', '4', '0', '0']
last_row: ['Waits until the element ``locator`` is visible.', '0.045', '0.115', 'None', '0.204', '0.078', '5', '0', '0']
quater_row: ['Odoo Confirm RFQ', 'None', 'None', 'None', 'None', 'None', '0', '1', '1']
mid_row: ['Odoo Open Receipt', 'None', 'None', 'None', 'None', 'None', '0', '0', '1']
upper_mid_row: ['Returns the number of elements matching ``locator``.', '0.012', '0.012', 'None', '0.012', 'None', '1', '0', '2']

Data Table ResultSummary DOCX: # special version for DOCX
length: 42
header: ["", 'Result Name', 'Minimum', 'Average', '90%ile', 'Maximum', 'Std. Dev.', 'Pass', 'Fail', 'Other']
rows_numbers: [1, -1, 11, 21, 31]
first_row: ["", ':example: ''John Doe''', '0.001', '0.001', 'None', '0.001', '0.0', '4', '0', '0']
last_row: ["", 'Waits until the element ``locator`` is visible.', '0.045', '0.115', 'None', '0.204', '0.078', '5', '0', '0']
quater_row: ["", 'Odoo Confirm RFQ', 'None', 'None', 'None', 'None', 'None', '0', '1', '1']
mid_row: ["", 'Odoo Open Receipt', 'None', 'None', 'None', 'None', 'None', '0', '0', '1']
upper_mid_row: ["", 'Returns the number of elements matching ``locator``.', '0.012', '0.012', 'None', '0.012', 'None', '1', '0', '2']

Data Table Polish Lang:
length: 42
header: ['Nazwa Wyniku', 'Minimum', 'Średnia', '90%yl', 'Maksimum', 'Odchylenie Standardowe', 'Pomyślnie', 'Niepowodzenie', 'Inne']
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.

0 comments on commit 5f98016

Please sign in to comment.