Skip to content

Add extended failure message for visual testing#6445

Merged
valfirst merged 1 commit intomasterfrom
visual-message
Feb 18, 2026
Merged

Add extended failure message for visual testing#6445
valfirst merged 1 commit intomasterfrom
visual-message

Conversation

@uarlouski
Copy link
Member

@uarlouski uarlouski commented Feb 17, 2026

Summary by CodeRabbit

  • New Features

    • Visual test assertions can optionally include the baseline name in assertion messages via a new extended assertion format. Configurable via ui.visual.extended-assertion-format-enabled (false by default).
  • Documentation

    • Added docs entry for the new configuration property.
  • Tests

    • Added tests validating the extended assertion message format for pass and fail cases.

@uarlouski uarlouski requested a review from a team as a code owner February 17, 2026 09:08
@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2026

📝 Walkthrough

Walkthrough

Introduces a new configurable property ui.visual.extended-assertion-format-enabled (default false), a backing boolean field and setter in AbstractVisualSteps, conditional assertion formatting in verifyResult, Spring bean parent/prop wiring to an abstractVisualSteps bean, updated plugin bean parents, tests for extended messages, and docs update.

Changes

Cohort / File(s) Summary
Visual Steps Core Implementation
vividus-extension-visual-testing/src/main/java/org/vividus/visual/steps/AbstractVisualSteps.java
Added private extendedAssertionFormatEnabled field and public setter setExtendedAssertionFormatEnabled(boolean). Modified verifyResult() to emit extended assertion messages ("Visual check for '%s' baseline is %s") when the flag is true; preserved previous behavior otherwise.
Spring Configuration
vividus-extension-visual-testing/src/main/resources/vividus-extension/spring.xml, vividus-plugin-applitools/src/main/resources/vividus-plugin/spring.xml, vividus-plugin-visual/src/main/resources/vividus-plugin/spring.xml
Added an abstract bean abstractVisualSteps with property extendedAssertionFormatEnabled bound to ${ui.visual.extended-assertion-format-enabled}. Updated concrete visual step beans to declare parent="abstractVisualSteps".
Default Configuration
vividus-extension-visual-testing/src/main/resources/properties/defaults/default.properties
Added property ui.visual.extended-assertion-format-enabled=false to defaults.
Tests
vividus-extension-visual-testing/src/test/java/org/vividus/visual/steps/VisualStepsTests.java
Added tests verifying extended assertion format: shouldUseExtendedAssertionFormatPassed() and shouldUseExtendedAssertionFormatFailed(), plus a new EXTENDED_MESSAGE_FORMAT constant.
Documentation
docs/modules/plugins/pages/plugin-visual.adoc
Added documentation entry for new property ui.visual.extended-assertion-format-enabled with acceptable values true/false and description of extended assertion message behavior (includes baseline name).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add extended failure message for visual testing' accurately describes the main change: adding support for an extended assertion format that includes baseline names in visual testing messages.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch visual-message

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@vividus-extension-visual-testing/src/main/java/org/vividus/visual/steps/AbstractVisualSteps.java`:
- Line 40: The field and accessor are misspelled using "Assertation" instead of
"Assertion": rename the boolean field enableExtendedAssertationFormat to
enableExtendedAssertionFormat and rename the setter
setEnableExtendedAssertationFormat(...) to
setEnableExtendedAssertionFormat(...); update all usages including the Spring
XML property name (enable-extended-assertion-format /
enableExtendedAssertionFormat) and the test method
shouldUseExtendedAssertationFormat → shouldUseExtendedAssertionFormat to keep
the bean property API consistent.

In
`@vividus-extension-visual-testing/src/test/java/org/vividus/visual/steps/VisualStepsTests.java`:
- Around line 153-164: Convert this single-case test into a `@ParameterizedTest`
using `@CsvSource` to iterate over VisualActionType values (COMPARE_AGAINST,
CHECK_INEQUALITY_AGAINST) and passed flag (true/false); for each combination
create the AbstractVisualCheck with BASELINE_NAME, set
visualCheckResult.setPassed(passed), call
visualSteps.setEnableExtendedAssertionFormat(true) and
visualSteps.verifyResult(visualCheckResult), then compute the expected assertion
outcome using the XOR rule from AbstractVisualSteps (i.e., expected = passed ^
(action == CHECK_INEQUALITY_AGAINST)) and verify the softAssert with
softAssert.assertTrue/assertFalse("Visual check for '%s'
baseline".formatted(BASELINE_NAME), expected) so the test covers both action
types and pass/fail states.

---

Duplicate comments:
In
`@vividus-extension-visual-testing/src/main/resources/vividus-extension/spring.xml`:
- Around line 9-11: The XML bean property name enableExtendedAssertionFormat in
the abstractVisualSteps bean does not match the corrected Java field/setter name
in org.vividus.visual.steps.AbstractVisualSteps (you indicated a typo in
AbstractVisualSteps.java); update this property name to the exact corrected Java
property/setter identifier (after you fix the field/setter name in
AbstractVisualSteps) so Spring property wiring uses the new name and remove the
mismatched "Assertion" variant; reference bean name "abstractVisualSteps" and
class "org.vividus.visual.steps.AbstractVisualSteps" when making the change.

private final IAttachmentPublisher attachmentPublisher;
private final ISoftAssert softAssert;

private boolean enableExtendedAssertionFormat;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typo: "Assertion" → "Assertion" in field and setter names.

enableExtendedAssertionFormat / setEnableExtendedAssertionFormat — "Assertion" is not a valid English word. This typo will be baked into the bean property API surface. Since the external property name (enable-extended-assertion-format) is already spelled correctly, fixing the Java identifiers now avoids a breaking rename later.

Proposed fix
-    private boolean enableExtendedAssertionFormat;
+    private boolean enableExtendedAssertionFormat;

Rename throughout:

  • Field: enableExtendedAssertionFormatenableExtendedAssertionFormat … wait, let me be precise:
  • enableExtendedAssertionFormatenableExtendedAssertionFormat
-    private boolean enableExtendedAssertionFormat;
+    private boolean enableExtendedAssertionFormat;

Apologies — corrected diff:

-    private boolean enableExtendedAssertionFormat;
+    private boolean enableExtendedAssertionFormat;

Rename AssertionAssertion in:

  • Field enableExtendedAssertionFormat (line 40)
  • Setter setEnableExtendedAssertionFormat (line 112)
  • Spring XML property name enableExtendedAssertionFormat in spring.xml
  • Test method shouldUseExtendedAssertionFormat in VisualStepsTests.java

Also applies to: 112-115

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@vividus-extension-visual-testing/src/main/java/org/vividus/visual/steps/AbstractVisualSteps.java`
at line 40, The field and accessor are misspelled using "Assertation" instead of
"Assertion": rename the boolean field enableExtendedAssertationFormat to
enableExtendedAssertionFormat and rename the setter
setEnableExtendedAssertationFormat(...) to
setEnableExtendedAssertionFormat(...); update all usages including the Spring
XML property name (enable-extended-assertion-format /
enableExtendedAssertionFormat) and the test method
shouldUseExtendedAssertationFormat → shouldUseExtendedAssertionFormat to keep
the bean property API consistent.

Comment on lines 153 to 164
@Test
void shouldUseExtendedAssertionFormat()
{
var visualCheck = new AbstractVisualCheck(BASELINE_NAME, VisualActionType.COMPARE_AGAINST) { };
var visualCheckResult = new VisualCheckResult(visualCheck);
visualCheckResult.setPassed(false);

visualSteps.setEnableExtendedAssertionFormat(true);
visualSteps.verifyResult(visualCheckResult);

verify(softAssert).assertTrue("Visual check for '%s' baseline".formatted(BASELINE_NAME), false);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider parameterizing this test to cover both action types and pass/fail states.

Currently only tests COMPARE_AGAINST with passed=false. The extended format interacts with the XOR logic on line 94 of AbstractVisualSteps, so covering CHECK_INEQUALITY_AGAINST and passed=true would strengthen confidence.

Suggested approach

Convert to a @ParameterizedTest with @CsvSource similar to the existing shouldPublishAttachment test:

-    `@Test`
-    void shouldUseExtendedAssertionFormat()
-    {
-        var visualCheck = new AbstractVisualCheck(BASELINE_NAME, VisualActionType.COMPARE_AGAINST) { };
-        var visualCheckResult = new VisualCheckResult(visualCheck);
-        visualCheckResult.setPassed(false);
-
-        visualSteps.setEnableExtendedAssertionFormat(true);
-        visualSteps.verifyResult(visualCheckResult);
-
-        verify(softAssert).assertTrue("Visual check for '%s' baseline".formatted(BASELINE_NAME), false);
-    }
+    `@ParameterizedTest`
+    `@CsvSource`({ COMPARE_AGAINST, CHECK_INEQUALITY_AGAINST })
+    void shouldUseExtendedAssertionFormat(boolean passed, VisualActionType action)
+    {
+        var visualCheck = new AbstractVisualCheck(BASELINE_NAME, action) { };
+        var visualCheckResult = new VisualCheckResult(visualCheck);
+        visualCheckResult.setPassed(passed);
+
+        visualSteps.setEnableExtendedAssertionFormat(true);
+        visualSteps.verifyResult(visualCheckResult);
+
+        verify(softAssert).assertTrue("Visual check for '%s' baseline".formatted(BASELINE_NAME), true);
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@vividus-extension-visual-testing/src/test/java/org/vividus/visual/steps/VisualStepsTests.java`
around lines 153 - 164, Convert this single-case test into a `@ParameterizedTest`
using `@CsvSource` to iterate over VisualActionType values (COMPARE_AGAINST,
CHECK_INEQUALITY_AGAINST) and passed flag (true/false); for each combination
create the AbstractVisualCheck with BASELINE_NAME, set
visualCheckResult.setPassed(passed), call
visualSteps.setEnableExtendedAssertionFormat(true) and
visualSteps.verifyResult(visualCheckResult), then compute the expected assertion
outcome using the XOR rule from AbstractVisualSteps (i.e., expected = passed ^
(action == CHECK_INEQUALITY_AGAINST)) and verify the softAssert with
softAssert.assertTrue/assertFalse("Visual check for '%s'
baseline".formatted(BASELINE_NAME), expected) so the test covers both action
types and pass/fail states.

@codecov
Copy link

codecov bot commented Feb 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.77%. Comparing base (d914df4) to head (8deb4ad).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##             master    #6445   +/-   ##
=========================================
  Coverage     97.77%   97.77%           
- Complexity     7397     7400    +3     
=========================================
  Files          1014     1014           
  Lines         21405    21413    +8     
  Branches       1403     1405    +2     
=========================================
+ Hits          20928    20936    +8     
  Misses          361      361           
  Partials        116      116           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link

github-actions bot commented Feb 17, 2026

Qodana for JVM

7 new problems were found

Inspection name Severity Problems
Incorrect Spring Core XML-based application context 🔴 Failure 3
Incorrect constructor injection in XML Spring bean 🔴 Failure 2
Incorrect autowiring in Spring bean components 🔴 Failure 1
Unresolved placeholders configured in the Spring XML application context 🔶 Warning 1

💡 Qodana analysis was run in the pull request mode: only the changed files were checked
☁️ View the detailed Qodana report

Contact Qodana team

Contact us at [email protected]

<bean class="org.vividus.visual.eyes.converter.StringToAccessibilitySettingsConverter" />

<bean id="visualTestingSteps" class="org.vividus.visual.eyes.VisualTestingSteps" >
<bean id="visualTestingSteps" class="org.vividus.visual.eyes.VisualTestingSteps" parent="abstractVisualSteps">

Check failure

Code scanning / QDJVM

Incorrect constructor injection in XML Spring bean Error

No matching constructor found in class 'VisualTestingSteps'#treeend |------------------------------------------------------------------------------------|---|---------------------------------------------------------------------------|
| VisualTestingSteps(...): | | Bean: |
| VisualTestingService<ApplitoolsVisualCheckResult> visualTestingService | | Autowired: null(ImageVisualTestingService); null(UfgVisualTestingService) |
| ApplitoolsVisualCheckFactory applitoolsVisualCheckFactory | | Autowired: null(ExamplesTableToApplitoolsVisualChecksConverter) |
| ScreenshotParametersFactory<ScreenshotConfiguration> screenshotParametersFactory | | <constructor-arg index="2" ref="screenshotParametersFactory" /> |
| IUiContext uiContext | | ??? |
| IAttachmentPublisher attachmentPublisher | | ??? |
| ISoftAssert softAssert | | ??? |
<bean class="org.vividus.visual.eyes.converter.StringToAccessibilitySettingsConverter" />

<bean id="visualTestingSteps" class="org.vividus.visual.eyes.VisualTestingSteps" >
<bean id="visualTestingSteps" class="org.vividus.visual.eyes.VisualTestingSteps" parent="abstractVisualSteps">

Check failure

Code scanning / QDJVM

Incorrect Spring Core XML-based application context Error

Cannot resolve bean 'abstractVisualSteps'
</bean>

<bean id="ufgSteps" class="org.vividus.visual.eyes.UfgSteps" />
<bean id="ufgSteps" class="org.vividus.visual.eyes.UfgSteps" parent="abstractVisualSteps"/>

Check failure

Code scanning / QDJVM

Incorrect constructor injection in XML Spring bean Error

No matching constructor found in class 'UfgSteps'#treeend |-----------------------------------------------------------------------------|---|---------------------------------------------------------------------------|
| UfgSteps(...): | | Bean: |
| VisualTestingService<UfgApplitoolsVisualCheckResult> visualTestingService | | Autowired: null(ImageVisualTestingService); null(UfgVisualTestingService) |
| ApplitoolsVisualCheckFactory applitoolsVisualCheckFactory | | Autowired: null(ExamplesTableToApplitoolsVisualChecksConverter) |
| IUiContext uiContext | | ??? |
| IAttachmentPublisher attachmentPublisher | | ??? |
| ISoftAssert softAssert | | ??? |
</bean>

<bean id="ufgSteps" class="org.vividus.visual.eyes.UfgSteps" />
<bean id="ufgSteps" class="org.vividus.visual.eyes.UfgSteps" parent="abstractVisualSteps"/>

Check failure

Code scanning / QDJVM

Incorrect Spring Core XML-based application context Error

Cannot resolve bean 'abstractVisualSteps'
<context:component-scan base-package="org.vividus.visual.storage" />

<bean id="visualSteps" class="org.vividus.visual.VisualSteps">
<bean id="visualSteps" class="org.vividus.visual.VisualSteps" parent="abstractVisualSteps">

Check failure

Code scanning / QDJVM

Incorrect Spring Core XML-based application context Error

Cannot resolve bean 'abstractVisualSteps'
|`<empty>`
|Used to append scenario based index to a baseline name

|`ui.visual.enable-extended-assertion-format`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
|`ui.visual.enable-extended-assertion-format`
|`ui.visual.extended-assertion-format-enabled`

softAssert.assertTrue("Visual check passed", passed);
if (enableExtendedAssertionFormat)
{
softAssert.assertTrue("Visual check for '%s' baseline".formatted(result.getBaselineName()), passed);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use recordPassedAssertion/recordFailedAssertion

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@vividus-extension-visual-testing/src/main/java/org/vividus/visual/steps/AbstractVisualSteps.java`:
- Around line 40-41: The field and accessor use a misspelling of "Assertion"
(single-s vs double-s); rename the boolean field extendedAsertionFormatEnabled
to extendedAssertionFormatEnabled and rename the setter
setExtendedAsertionFormatEnabled to setExtendedAssertionFormatEnabled (and any
getter if present), and update all references including Spring XML property
names and test method names to the corrected extendedAssertionFormatEnabled
spelling while leaving the external property key unchanged.

In
`@vividus-extension-visual-testing/src/main/resources/vividus-extension/spring.xml`:
- Around line 9-11: The bean property name extendedAssertionFormatEnabled in the
abstractVisualSteps bean is misspelled and must be corrected to
extendedAssertionFormatEnabled -> extendedAssertionFormatEnabled (fix the Java
identifier to match the correctly spelled "Assertion"); update the property name
in the spring.xml bean declaration to the corrected identifier and then rename
the corresponding field and its setter (and getter if present) in the
AbstractVisualSteps class (e.g., field extendedAssertionFormatEnabled and
setExtendedAssertionFormatEnabled) so they match the corrected property name;
keep the external property key ui.visual.extended-assertion-format-enabled
unchanged and ensure Spring injection still maps to the renamed Java property.

default-lazy-init="true">

<bean name="abstractVisualSteps" class="org.vividus.visual.steps.AbstractVisualSteps" abstract="true">
<property name="extendedAssertionFormatEnabled" value="${ui.visual.extended-assertion-format-enabled}" />

Check warning

Code scanning / QDJVM

Unresolved placeholders configured in the Spring XML application context Warning

Cannot resolve property key
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds an optional extended assertion message format for visual testing that includes the baseline name in assertion messages. The feature is disabled by default to maintain backward compatibility.

Changes:

  • Added a new configuration property ui.visual.extended-assertion-format-enabled (default: false) to enable extended assertion messages
  • Implemented extended assertion format in AbstractVisualSteps that displays "Visual check for '' baseline is passed/failed"
  • Created an abstract Spring bean to propagate the configuration property to all visual testing step classes

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
vividus-extension-visual-testing/src/main/java/org/vividus/visual/steps/AbstractVisualSteps.java Implements the extended assertion format logic with conditional branching based on the enabled flag
vividus-extension-visual-testing/src/main/resources/vividus-extension/spring.xml Defines abstract parent bean to configure the extended assertion format property
vividus-extension-visual-testing/src/main/resources/properties/defaults/default.properties Sets the default value to false for backward compatibility
vividus-extension-visual-testing/src/test/java/org/vividus/visual/steps/VisualStepsTests.java Adds test coverage for passed and failed scenarios with extended format
vividus-plugin-visual/src/main/resources/vividus-plugin/spring.xml Updates VisualSteps bean to inherit from abstractVisualSteps parent
vividus-plugin-applitools/src/main/resources/vividus-plugin/spring.xml Updates VisualTestingSteps and UfgSteps beans to inherit from abstractVisualSteps parent
docs/modules/plugins/pages/plugin-visual.adoc Documents the new configuration property with acceptable values and description

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


verify(softAssert).recordFailedAssertion(EXTENDED_MESSAGE_FORMAT.formatted(BASELINE_NAME, "failed"));
}

Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new test methods shouldUseExtendedAssertionFormatPassed and shouldUseExtendedAssertionFormatFailed only test the COMPARE_AGAINST action type. However, the verifyResult method has special logic for CHECK_INEQUALITY_AGAINST (line 94: XOR operation that inverts the result). The extended format should also be tested with CHECK_INEQUALITY_AGAINST to ensure the message correctly reflects "passed" or "failed" when the inequality check logic is applied. Consider adding tests for CHECK_INEQUALITY_AGAINST with both isPassed true and false scenarios.

Suggested change
@Test
void shouldUseExtendedAssertionFormatPassedForInequalityCheck()
{
var visualCheck = new AbstractVisualCheck(BASELINE_NAME, VisualActionType.CHECK_INEQUALITY_AGAINST) { };
var visualCheckResult = new VisualCheckResult(visualCheck);
// For CHECK_INEQUALITY_AGAINST the verifyResult logic inverts the result,
// so isPassed(false) should be treated as a passed assertion.
visualCheckResult.setPassed(false);
visualSteps.setExtendedAssertionFormatEnabled(true);
visualSteps.verifyResult(visualCheckResult);
verify(softAssert).recordPassedAssertion(EXTENDED_MESSAGE_FORMAT.formatted(BASELINE_NAME, "passed"));
}
@Test
void shouldUseExtendedAssertionFormatFailedForInequalityCheck()
{
var visualCheck = new AbstractVisualCheck(BASELINE_NAME, VisualActionType.CHECK_INEQUALITY_AGAINST) { };
var visualCheckResult = new VisualCheckResult(visualCheck);
// For CHECK_INEQUALITY_AGAINST the verifyResult logic inverts the result,
// so isPassed(true) should be treated as a failed assertion.
visualCheckResult.setPassed(true);
visualSteps.setExtendedAssertionFormatEnabled(true);
visualSteps.verifyResult(visualCheckResult);
verify(softAssert).recordFailedAssertion(EXTENDED_MESSAGE_FORMAT.formatted(BASELINE_NAME, "failed"));
}

Copilot uses AI. Check for mistakes.
@sonarqubecloud
Copy link

@valfirst valfirst merged commit 165f789 into master Feb 18, 2026
33 of 37 checks passed
@valfirst valfirst deleted the visual-message branch February 18, 2026 09:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments