Skip to content
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ jobs:

# Run tests with multiple output formats
python -m pytest unittests/ \
--cov=epg_grabber \
--cov=AIVision \
--cov-report=xml \
--cov-report=html \
--cov-report=term-missing \
Expand Down
57 changes: 51 additions & 6 deletions AIVision/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,57 @@ def verify_screenshot_matches_look_and_feel_template(self, screenshot_path, temp
except Exception as e:
logger.warn(f"Could not create combined image: {e}")

instructions = """First image is showing actual application view.
Second image is reference design template.
Verify screenshot matches look and feel template. Pay attention to details, design is important.
Make sure to check also all the visible logos, titles, labels, spelling, texts, links, menus, banners
and any available graphics. Always doublecheck the reference image in case you think some
text, label, logo or element is overlapping or containing typo.
instructions = """
First image is the actual application screenshot.
Second image is the reference design/template screenshot.

Compare the actual screenshot against the reference screenshot as a visual UI/template validation.

Primary goal:
Verify that the actual page matches the reference page in layout, visual structure, branding, and look-and-feel.

Check carefully:
- Overall page structure and visual hierarchy
- Header, navigation, menu icons, logos, brand marks, and banners
- Sections, cards, panels, containers, borders, backgrounds, shadows, and spacing
- Buttons, links, icons, badges, dropdowns, input fields, and other interactive elements
- Element positions, alignment, relative sizing, padding, margins, and grouping
- Font style, font weight, approximate font size, text alignment, and color usage
- Overlapping, clipped, truncated, hidden, misplaced, or visually broken elements
- Unexpected wrapping, excessive spacing, missing spacing, or layout shifts
- Whether all expected visible UI elements are present

Important text comparison rules:
Do not compare dynamic text values literally. Values such as phone numbers, account numbers, names, balances, prices, dates, times, counts, statuses, identifiers, and user-specific data may be different and must not cause failure.

Treat dynamic text as visual text blocks:
- The exact value may differ.
- The text block should still appear in the expected location.
- It should have similar styling, size, alignment, color, and visual weight.
- It should not break the layout, overlap other elements, be clipped, or cause unexpected wrapping.

Static/template text rules:
Static labels, headings, menu names, fixed links, fixed button labels, fixed section names, and fixed instructional texts should be checked only when they are clearly part of the template.
However, do not fail only because the actual text content differs if the difference appears to be dynamic or user-specific.

Ignore:
- Browser chrome, OS status bars, emulator/device frames, address bars, scroll bars, timestamps, debug overlays, and comparison labels such as "Actual" or "Expected", unless they are part of the application UI.
- Minor anti-aliasing differences, screenshot compression artifacts, tiny pixel-level shifts, and insignificant rendering differences.
- Small differences caused by platform/browser font rendering if the layout and visual hierarchy remain correct.

Fail the comparison when:
- A required UI element is missing or an unexpected major UI element is present.
- Logo, header, menu, navigation, main section, card, button, link, or icon is visually incorrect or misplaced.
- Layout structure differs significantly from the reference.
- Elements overlap, are clipped, truncated, hidden, or visually broken.
- Text blocks are present but their placement, style, size, color, or wrapping materially differs from the reference.
- Spacing, alignment, sizing, or visual hierarchy is noticeably inconsistent with the reference.
- The page looks like a different template, broken responsive layout, or incorrect design version.

Pass the comparison when:
- The actual screenshot preserves the same layout, structure, visual hierarchy, branding, and front-end appearance as the reference.
- Differences are limited to dynamic text values or insignificant rendering variations.
- All expected elements are present and visually usable.
"""
if override_instructions:
instructions = override_instructions
Expand Down
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
1.3.0, 2026-05-25 -- Look and Feel layout comparison assertion strategy improved and made more robust
1.2.0, 2026-02-24 -- Image size optimizations, additional_instructions can now be passed to look and feel check keyword
1.1.2, 2026-02-09 -- Improved debug logging
1.1.1, 2026-02-09 -- Pass/Fail AI response optimized
Expand Down
6 changes: 6 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ def readme():
long_description=readme(),
long_description_content_type='text/markdown',
url='https://github.com/robco/robotframework-aivision.git',
project_urls={
"Homepage": "https://robo-corp.malovec.sk",
"Repository": "https://github.com/robco/robotframework-aivision",
"Documentation": "https://robco.github.io/robotframework-aivision/",
"Issues": "https://github.com/robco/robotframework-aivision/issues",
},
author='Róbert Malovec',
author_email='robert@malovec.sk',
license=license(),
Expand Down
2 changes: 1 addition & 1 deletion unittests/test_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_verify_screenshot_matches_look_and_feel_template_with_additional_instru
additional_instructions="Ignore status badge."
)
instructions = aivison_library.genai.generate_ai_response.call_args[1]["instructions"]
assert "First image is showing actual application view" in instructions
assert "First image is the actual application screenshot" in instructions
assert instructions.endswith("Ignore status badge.")
aivison_library._assert_result.assert_called_once_with("response")

Expand Down
4 changes: 2 additions & 2 deletions unittests/test_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def test_verify_screenshot_matches_look_and_feel_template(self, library, mock_ge
)

mock_genai.generate_ai_response.assert_called_once()
assert "First image is showing actual application view" in mock_genai.generate_ai_response.call_args[1][
assert "First image is the actual application screenshot" in mock_genai.generate_ai_response.call_args[1][
'instructions']
assert mock_genai.generate_ai_response.call_args[1]['image_paths'] == ["/path/to/screenshot.png",
"/path/to/template.png"]
Expand Down Expand Up @@ -213,7 +213,7 @@ def test_verify_screenshot_matches_look_and_feel_template_with_additional_instru

mock_genai.generate_ai_response.assert_called_once()
instructions = mock_genai.generate_ai_response.call_args[1]["instructions"]
assert "First image is showing actual application view" in instructions
assert "First image is the actual application screenshot" in instructions
assert instructions.endswith("Ignore clock in header.")
assert mock_genai.generate_ai_response.call_args[1]["image_paths"] == [
"/path/to/screenshot.png",
Expand Down
Loading