Monetize GingerPlay Feature#4325
Conversation
WalkthroughReworks multiple External Config UI pages into two-column layouts with right-side "About" panels and hyperlinks, adds hyperlink handlers and Ginger Play promo/banner flows, introduces new Ginger Play image assets and enum entries, and updates ImageMaker rendering and some UI icon defaults. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant UI as Config / TwoLevelMenu
participant Handler as Page Handler
participant OS as OS Shell (Process.Start)
participant Banner as GingerPlay Banner
User->>UI: Click "Learn more" or Promo button
UI->>Handler: RequestNavigate / ProFeatureButtonClick
alt Gateway URL configured
Handler->>OS: Process.Start(uri) (UseShellExecute=true)
OS-->>User: Browser opens URL
Handler-->>UI: mark event handled
else Gateway URL not configured
Handler->>Banner: ShowGingerPlayBannerWindow (modal)
Banner->>User: Display interactive banner/image
User->>Banner: Click banner image
Banner->>OS: Process.Start(externalLink)
OS-->>User: Browser opens external link
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
♻️ Duplicate comments (6)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml.cs (1)
77-81: Consolidate with other hyperlink handlers.This is a duplicate of the code duplication issue flagged in GingerPlayConfigurationpage.xaml.cs (lines 247-251). Please apply the same refactoring solution across all affected files.
Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml.cs (1)
148-152: Consolidate with other hyperlink handlers.This is a duplicate of the code duplication issue flagged in GingerPlayConfigurationpage.xaml.cs (lines 247-251). Please apply the same refactoring solution across all affected files.
Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml.cs (1)
144-148: Consolidate with other hyperlink handlers.This is a duplicate of the code duplication issue flagged in GingerPlayConfigurationpage.xaml.cs (lines 247-251). Please apply the same refactoring solution across all affected files.
Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml.cs (1)
93-97: Consolidate with other hyperlink handlers.This is a duplicate of the code duplication issue flagged in GingerPlayConfigurationpage.xaml.cs (lines 247-251). Please apply the same refactoring solution across all affected files.
Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml (2)
47-52: Remove unnecessary Grid structure.Identical to the VRT file, this Grid defines two columns but only uses
Grid.Column="0". This pattern is duplicated across multiple external configuration pages.Apply this diff to simplify the structure:
-<StackPanel Orientation="Horizontal" Grid.Row="2" > - <Grid> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="*" /> - <ColumnDefinition Width="*" /> - </Grid.ColumnDefinitions> - - <!-- Left Side --> - <Grid Grid.Column="0" > - <StackPanel Margin="0,10,0,0" > +<StackPanel Orientation="Horizontal" Grid.Row="2" Margin="0,10,0,0">And at the end (lines 75-78):
- </StackPanel> - </Grid> - </Grid> - </StackPanel> +</StackPanel>
57-61: Avoid hardcoded dimensions for responsive design.Same issue as in VRT file: hardcoded
Width="591",Width="581", andHeight="250"constrain responsiveness.Consider using
MaxWidthand removing fixed height:-<Expander x:Name="xAboutWireMock" ExpandDirection="Down" Style="{StaticResource $ExpanderStyle}" IsExpanded="True" Width="591"> +<Expander x:Name="xAboutWireMock" ExpandDirection="Down" Style="{StaticResource $ExpanderStyle}" IsExpanded="True" MaxWidth="591"> <Expander.Header> <Label Content="About WireMock" Style="{StaticResource $HorizontalExpanderLabelStyle}"/> </Expander.Header> - <TextBlock x:Name="xWireMockInfo" TextWrapping="Wrap" Width="581" Height="250" Padding="10,5,5,5" HorizontalAlignment="Left"> + <TextBlock x:Name="xWireMockInfo" TextWrapping="Wrap" MaxWidth="581" Padding="10,5,5,5" HorizontalAlignment="Left">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (4)
Ginger/Ginger/UserControlsLib/ImageMakerLib/Images/GingerPlayDetailsPopUpContent.pngis excluded by!**/*.png,!**/*.pngGinger/Ginger/UserControlsLib/ImageMakerLib/Images/GingerPlayGradiantBlack.pngis excluded by!**/*.png,!**/*.pngGinger/Ginger/UserControlsLib/ImageMakerLib/Images/GingerPlayGradiantWhite.pngis excluded by!**/*.png,!**/*.pngGinger/Ginger/UserControlsLib/ImageMakerLib/Images/GingerPlayWhiteGradiant.pngis excluded by!**/*.png,!**/*.png
📒 Files selected for processing (15)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml(2 hunks)Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml.cs(1 hunks)Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml(2 hunks)Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs(1 hunks)Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml(2 hunks)Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml.cs(1 hunks)Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml(2 hunks)Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml.cs(1 hunks)Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml(2 hunks)Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml.cs(1 hunks)Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml(1 hunks)Ginger/Ginger/Ginger.csproj(2 hunks)Ginger/Ginger/MainWindow.xaml(3 hunks)Ginger/Ginger/UserControlsLib/ImageMakerLib/ImageMakerControl.xaml.cs(2 hunks)Ginger/GingerCoreCommon/EnumsLib/eImageType.cs(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml.cs (5)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(77-81)Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (1)
Hyperlink_RequestNavigate(247-251)Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(148-152)Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(93-97)Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml.cs (1)
Hyperlink_RequestNavigate(166-170)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml.cs (4)
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (1)
Hyperlink_RequestNavigate(247-251)Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(148-152)Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(93-97)Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml.cs (1)
Hyperlink_RequestNavigate(144-148)
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (5)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(77-81)Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(148-152)Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(93-97)Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml.cs (1)
Hyperlink_RequestNavigate(144-148)Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml.cs (1)
Hyperlink_RequestNavigate(166-170)
Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml.cs (4)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(77-81)Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (1)
Hyperlink_RequestNavigate(247-251)Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(148-152)Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml.cs (1)
Hyperlink_RequestNavigate(144-148)
Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml.cs (4)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(77-81)Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (1)
Hyperlink_RequestNavigate(247-251)Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(93-97)Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml.cs (1)
Hyperlink_RequestNavigate(144-148)
🔇 Additional comments (16)
Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml (2)
67-67: LGTM! Improved discoverability of ZAP information.Expanding the About section by default helps users quickly access important information about ZAP's capabilities and integration with Ginger, which aligns well with the feature promotion objectives.
82-84: RequestNavigate handler already implemented in ZAPConfigurationPage.xaml.cs (lines 166–170) to open the URL and mark the event handled.Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml (1)
96-127: LGTM!The "About Sealights" section is well-structured and provides clear, informative content with an appropriate hyperlink. The use of
IsExpanded="True"ensures users see the information by default, which aligns with the educational intent of this feature.Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml (1)
77-114: LGTM!The "About Ginger Play" section provides comprehensive information about the platform's capabilities. The structured presentation using bullet points and line breaks makes it easy to read. The hyperlink integration is consistent with other configuration pages.
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml (1)
66-101: LGTM!The "About Applitools" section is well-crafted with clear descriptions of the platform's capabilities. Including both the official Applitools website link and the Ginger-specific documentation link is particularly helpful for users. The layout and structure are consistent with other configuration pages.
Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml (2)
19-19: LGTM!The new row definition accommodates the About section appropriately.
117-135: Hyperlink_RequestNavigate handler exists and correctly opens links in the system browser.Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml (2)
19-19: LGTM!The new row definition appropriately accommodates the About section.
62-73: LGTM! The About WireMock content and hyperlink are clear and theHyperlink_RequestNavigatehandler is implemented correctly in the code-behind.Ginger/Ginger/MainWindow.xaml (3)
27-27: Verify the new column definition purpose.A new column with
Width="*"is added but it's unclear how it integrates with the existing 4 columns. The promotional UI block at line 92 referencesGrid.Column="4", which would be this new 5th column (0-indexed as column 4).Confirm this is intentional and that the promotional UI should appear in this rightmost column that will take all remaining space.
73-73: Minor margin adjustment.Left margin increased from 0 to 10 pixels. This appears intentional to add spacing.
106-106: Verify Crown icon availability.The Crown icon is referenced here using
ImageType="Crown". Ensure this enum value and its corresponding FontAwesome icon mapping exist in the ImageMakerControl.This should be verified by the changes in eImageType.cs and ImageMakerControl.xaml.cs in this PR.
Ginger/Ginger/UserControlsLib/ImageMakerLib/ImageMakerControl.xaml.cs (2)
220-228: LGTM - Image type handlers correctly implemented.The three new Ginger Play gradient image types are properly mapped to their static image assets, following the existing pattern used for other static images in the codebase.
1037-1039: LGTM - Crown icon correctly implemented.The Crown icon case is properly implemented using FontAwesome's Solid_Crown icon, consistent with other icon implementations in this file.
Ginger/GingerCoreCommon/EnumsLib/eImageType.cs (1)
335-335: LGTM - Crown enum value correctly placed.The Crown enum value is appropriately placed in the Items Images section and follows the existing naming convention.
Ginger/Ginger/Ginger.csproj (1)
614-618: Approve: new image assets exist and are correctly declared. The five new images exist under UserControlsLib/ImageMakerLib/Images and are properly removed from None and added as embedded resources with CopyToOutputDirectory=Never.
| <Expander x:Name="xAboutVRT" ExpandDirection="Down" Style="{StaticResource $ExpanderStyle}" IsExpanded="True" Width="591"> | ||
| <Expander.Header> | ||
| <Label Content="About VRT" Style="{StaticResource $HorizontalExpanderLabelStyle}"/> | ||
| </Expander.Header> | ||
| <TextBlock x:Name="xVRTInfo" TextWrapping="Wrap" Width="581" Height="250" Padding="10,5,5,5" HorizontalAlignment="Left"> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Avoid hardcoded dimensions for responsive design.
The Width="591" and Width="581" constraints and Height="250" may not adapt well to different screen sizes or content changes.
Consider using MaxWidth instead of fixed Width, and allowing height to adjust based on content:
-<Expander x:Name="xAboutVRT" ExpandDirection="Down" Style="{StaticResource $ExpanderStyle}" IsExpanded="True" Width="591">
+<Expander x:Name="xAboutVRT" ExpandDirection="Down" Style="{StaticResource $ExpanderStyle}" IsExpanded="True" MaxWidth="591">
<Expander.Header>
<Label Content="About VRT" Style="{StaticResource $HorizontalExpanderLabelStyle}"/>
</Expander.Header>
- <TextBlock x:Name="xVRTInfo" TextWrapping="Wrap" Width="581" Height="250" Padding="10,5,5,5" HorizontalAlignment="Left">
+ <TextBlock x:Name="xVRTInfo" TextWrapping="Wrap" MaxWidth="581" Padding="10,5,5,5" HorizontalAlignment="Left">🤖 Prompt for AI Agents
In Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml
around lines 112 to 116, the Expander and TextBlock use fixed
Width="591"/Width="581" and Height="250" which prevents responsive layout;
replace fixed Widths with MaxWidth (e.g., MaxWidth="591") and remove the fixed
Height so the TextBlock can grow with content, rely on HorizontalAlignment and
VerticalAlignment (or set MinWidth if needed) and, if required for overflow,
wrap the TextBlock in a ScrollViewer or set TextWrapping to preserve usability
on smaller screens.
| <StackPanel Orientation="Horizontal" Grid.Row="2" > | ||
| <Grid> | ||
| <Grid.ColumnDefinitions> | ||
| <ColumnDefinition Width="*" /> | ||
| <ColumnDefinition Width="*" /> | ||
| </Grid.ColumnDefinitions> | ||
|
|
||
| <!-- Left Side --> | ||
| <Grid Grid.Column="0" > | ||
| <StackPanel Margin="0,10,0,0" > | ||
| <Expander x:Name="xAboutWireMock" ExpandDirection="Down" Style="{StaticResource $ExpanderStyle}" IsExpanded="True" Width="591"> | ||
| <Expander.Header> | ||
| <Label Content="About WireMock" Style="{StaticResource $HorizontalExpanderLabelStyle}"/> | ||
| </Expander.Header> | ||
| <TextBlock x:Name="xWireMockInfo" TextWrapping="Wrap" Width="581" Height="250" Padding="10,5,5,5" HorizontalAlignment="Left"> | ||
| <Run Text="WireMock is a tool to simulate (mock) APIs for testing and development."/> | ||
| <LineBreak/> | ||
| <Run Text="Instead of calling a real backend, you can create custom endpoints that return the responses you need—errors, delays, or special cases included."/> | ||
| <LineBreak/> | ||
| <Run Text="This is ideal when real APIs aren’t available, unstable, or costly to use."/> | ||
| <LineBreak/> | ||
| <Run Text="With Ginger, WireMock lets you validate app behavior even before the real APIs are ready."/> | ||
| <LineBreak/> | ||
| <Hyperlink NavigateUri="https://wiremock.org/" RequestNavigate="Hyperlink_RequestNavigate"> | ||
| <Run Text="Learn more about WireMock"/> | ||
| </Hyperlink> | ||
| </TextBlock> | ||
| </Expander> | ||
| </StackPanel> | ||
| </Grid> | ||
| </Grid> | ||
| </StackPanel> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider extracting the About section pattern into a reusable component.
This "About" section pattern (Expander with TextBlock and hyperlinks) is duplicated across multiple external configuration pages (VRT, WireMock, and according to the AI summary, also Applitools, ZAP, Sealights, and Ginger Play). This code duplication increases maintenance burden.
Consider creating a reusable UserControl for the About section that accepts properties like:
- Title (e.g., "About VRT", "About WireMock")
- Description text
- List of hyperlinks with text and URLs
- IsExpanded state
This would:
- Reduce code duplication
- Ensure consistent styling
- Simplify future updates to the About section pattern
- Make the XAML files more maintainable
Do you want me to generate a sample UserControl implementation for the About section?
🤖 Prompt for AI Agents
In Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml around
lines 47 to 78, the "About WireMock" Expander/TextBlock pattern is duplicated
across several pages; extract it into a reusable UserControl (e.g.,
AboutSection) that exposes dependency properties: Title (string), Description
(string or ObservableCollection<string>), Links (IEnumerable of {Text, Url}),
and IsExpanded (bool). Implement the control with the existing
Expander/Label/TextBlock/Hyperlink structure and styles (reusing $ExpanderStyle
and $HorizontalExpanderLabelStyle), then replace the in-file Expander with the
new AboutSection and bind its properties; update other pages to use the same
control and move any shared styles/resources to a central resource dictionary if
needed.
| <Border Grid.Column="4" Height="30" CornerRadius="6"> | ||
| <Border.Background> | ||
| <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> | ||
| <GradientStop Color="#FF6A00" Offset="0.0"/> | ||
| <GradientStop Color="#FF00FF" Offset="0.5"/> | ||
| <GradientStop Color="#824de6" Offset="1.0"/> | ||
| </LinearGradientBrush> | ||
| </Border.Background> | ||
| <Grid> | ||
| <Grid.ColumnDefinitions> | ||
| <ColumnDefinition Width="40"/> | ||
| <ColumnDefinition Width="*"/> | ||
| </Grid.ColumnDefinitions> | ||
| <!-- Premium Icon (Crown) --> | ||
| <usercontrols:ImageMakerControl ImageType="Crown" Foreground="White" SetAsFontImageWithSize="17" /> | ||
| <!-- Unlock Button --> | ||
| <Button Grid.Column="1" | ||
| Content="Unlock Pro Features with Ginger Play" | ||
| Foreground="White" | ||
| Background="Transparent" | ||
| FontWeight="Bold" | ||
| FontSize="14" | ||
| HorizontalAlignment="Right" | ||
| Padding="-10,0" | ||
| BorderThickness="0" | ||
| Cursor="Hand" | ||
| /> | ||
| </Grid> | ||
| </Border> |
There was a problem hiding this comment.
Critical: Non-functional button and missing accessibility.
The promotional UI block has several issues:
-
Non-functional button: The button (lines 108-118) has no Click event handler, making it non-interactive. This is likely a critical issue unless this is intentional placeholder UI.
-
Accessibility violations: Missing accessibility attributes:
- No
AutomationProperties.Nameon the button - No keyboard navigation support indicators
- No
-
Internationalization issue: Hard-coded text "Unlock Pro Features with Ginger Play" should use resource dictionary for localization support.
-
Unusual styling:
Padding="-10,0"(line 115) uses negative padding which may cause rendering issues or unexpected behavior across different DPI settings. -
Grid column reference: Ensure
Grid.Column="4"correctly references the new column definition added at line 27.
Apply this diff to add a click handler and improve accessibility:
<!-- Unlock Button -->
<Button Grid.Column="1"
- Content="Unlock Pro Features with Ginger Play"
+ Content="{Binding UnlockProFeaturesText, FallbackValue='Unlock Pro Features with Ginger Play'}"
Foreground="White"
Background="Transparent"
FontWeight="Bold"
FontSize="14"
HorizontalAlignment="Right"
- Padding="-10,0"
+ Padding="10,0"
BorderThickness="0"
Cursor="Hand"
+ Click="xUnlockProFeaturesButton_Click"
+ AutomationProperties.Name="Unlock Pro Features with Ginger Play"
/>You'll also need to implement the click handler in MainWindow.xaml.cs:
private void xUnlockProFeaturesButton_Click(object sender, RoutedEventArgs e)
{
// TODO: Implement Ginger Play unlock functionality
// Consider opening a URL, showing a dialog, or navigating to a features page
}🤖 Prompt for AI Agents
Ginger/Ginger/MainWindow.xaml around lines 92-120: the promo Button is
non-functional, inaccessible, not localized and uses negative padding; update
the Button to include Click="xUnlockProFeaturesButton_Click",
x:Name="xUnlockProFeaturesButton", set AutomationProperties.Name to a resource
key (e.g. {DynamicResource UnlockProFeatures_Text}), ensure IsTabStop="True" and
Focusable="True" for keyboard navigation, remove the negative Padding (use
Padding="10,0" or appropriate positive value), and verify Grid.Column="4"
matches an existing column; then implement the click handler in
MainWindow.xaml.cs with the signature private void
xUnlockProFeaturesButton_Click(object sender, RoutedEventArgs e) that performs
the unlock action (open URL/show dialog/navigation) and use a resource string in
your resources for the button Content to support localization.
There was a problem hiding this comment.
Actionable comments posted: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml (1)
45-52: Fix Grid placement for inputs (avoid margin hacks)Both inputs should be in Column="1" with normal margins; current layout can break on resize.
- <Activities:UCValueExpression x:Name="xZAPURLTextBox" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="GingerOps Account URL" Margin="139,0,0,0" Width="414" Grid.ColumnSpan="2"/> + <Activities:UCValueExpression x:Name="xZAPURLTextBox" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="ZAP URL" Margin="10,0,0,0" Width="414"/> - <Activities:UCValueExpression x:Name="xZAPAPIkeyTextBox" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="Client Secret" Margin="139,0,0,0" Width="414" LostKeyboardFocus="xZAPAPIkeyTextBox_LostKeyboardFocus" Grid.ColumnSpan="2"/> + <Activities:UCValueExpression x:Name="xZAPAPIkeyTextBox" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="ZAP API Key" Margin="10,0,0,0" Width="414" LostKeyboardFocus="xZAPAPIkeyTextBox_LostKeyboardFocus"/>Also applies to: 51-52
♻️ Duplicate comments (6)
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (1)
250-254: Centralize hyperlink handler + add URI validation and error handlingThis duplicates across pages and lacks URI validation/try-catch. Prefer a single helper in GingerUIPage or a static utility; at minimum, harden this handler.
Apply this hardening inline:
- private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) - { - System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true }); - e.Handled = true; - } + private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) + { + try + { + if (e?.Uri == null || !e.Uri.IsAbsoluteUri || (e.Uri.Scheme != Uri.UriSchemeHttp && e.Uri.Scheme != Uri.UriSchemeHttps)) + { + Reporter.ToLog(eLogLevel.WARN, $"Blocked navigation to invalid URI: {e?.Uri}"); + return; + } + Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true }); + e.Handled = true; + } + catch (System.ComponentModel.Win32Exception ex) + { + Reporter.ToLog(eLogLevel.ERROR, $"Failed to open URL: {e?.Uri}", ex); + Reporter.ToUser(eUserMsgKey.StaticErrorMessage, $"Unable to open link: {ex.Message}"); + } + catch (Exception ex) + { + Reporter.ToLog(eLogLevel.ERROR, $"Unexpected error opening URL: {e?.Uri}", ex); + } + }Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml (1)
91-93: Ensure handler exists; prefer centralized helperConfirm ZAPConfigurationPage.xaml.cs defines Hyperlink_RequestNavigate; otherwise build will fail. Also centralize this handler as suggested on other pages.
#!/bin/bash set -euo pipefail echo "XAMLs wiring RequestNavigate to Hyperlink_RequestNavigate:" rg -nP 'RequestNavigate\s*=\s*"Hyperlink_RequestNavigate"' -g '!**/bin/**' -g '!**/obj/**' echo echo "Handler definitions in code-behind:" rg -nP --type=cs '\bvoid\s+Hyperlink_RequestNavigate\s*\(' -C2 echo echo "Check if GingerUIPage already provides a shared handler:" rg -nP --type=cs '(class\s+GingerUIPage\b.*?Hyperlink_RequestNavigate\()' -U -C2Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml (1)
83-85: Deduplicate hyperlink navigation across pagesReplace per-page Hyperlink_RequestNavigate with a single base/helper implementation used by all ExternalConfigurations pages.
Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml (1)
138-140: Centralize the hyperlink handlerUse a shared handler (e.g., in GingerUIPage) rather than duplicating Hyperlink_RequestNavigate per page.
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml (1)
91-129: Extract the About panel to a reusable UserControlThis pattern repeats across multiple pages; a shared control would reduce duplication and ensure consistent styling/content structure.
Ginger/Ginger/MainWindow.xaml (1)
92-136: Fix promo button sizing and accessibility; avoid overriding the default template
- Border Width=95 vs Button Width=99 will clip; let content size naturally.
- Negative Padding causes rendering issues; use positive padding.
- Custom template strips focus and keyboard cues; keep default for accessibility.
- Add AutomationProperties.Name and use a resource for text to enable localization.
Apply this diff:
- <Border Margin="10,0,0,0" Height="28" CornerRadius="6" Width="95"> + <Border Margin="10,0,0,0" Height="28" CornerRadius="6"> @@ - <Button -Content="Upgrade" + <Button x:Name="xUpgradeProFeaturesButton" +Content="{DynamicResource UpgradeProFeatures_Text}" Foreground="White" Background="Transparent" FontWeight="Bold" FontSize="14" HorizontalAlignment="Left" - ToolTip="Unlock Pro Features with Ginger Play" -Padding="-10,0" + ToolTip="Unlock Pro Features with Ginger Play" +Padding="10,0" BorderThickness="0" Cursor="Hand" -Click="ProFeatureButtonClick" Margin="-10,0,0,0" Width="99" Grid.ColumnSpan="2" Height="28"> - <Button.Style> - <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}"> - <Setter Property="Background" Value="Transparent"/> - <Setter Property="BorderBrush" Value="Transparent"/> - <Setter Property="OverridesDefaultStyle" Value="True"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="Button"> - <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - </Button.Style> - </Button> +Click="ProFeatureButtonClick" Margin="0,0,0,0" Grid.ColumnSpan="2" Height="28" +AutomationProperties.Name="Unlock Pro Features with Ginger Play" +IsTabStop="True" Focusable="True"/>If you need the text resource:
<!-- In resources --> <string x:Key="UpgradeProFeatures_Text">Upgrade</string>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (10)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs(2 hunks)Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml(2 hunks)Ginger/Ginger/MainWindow.xaml(6 hunks)Ginger/Ginger/MainWindow.xaml.cs(1 hunks)Ginger/Ginger/Reports/ExecutionResultsConfiguration.xaml(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (2)
Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml.cs (1)
Hyperlink_RequestNavigate(144-148)Ginger/Ginger/UserControlsLib/ImageMakerLib/ImageMakerControl.xaml.cs (1)
BitmapImage(1279-1282)
🔇 Additional comments (2)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml (1)
100-106: Verify hyperlink handler presenceEnsure Hyperlink_RequestNavigate exists in ApplitoolsExternalConfigurationsPage.xaml.cs and sets e.Handled = true.
Use the same script shared for VRT page to verify handler presence.
Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml (1)
86-86: Typo: "Tolerence" → "Tolerance"Fix user-visible text.
- <Label x:Name="xDifferenceTolerenceLabel" Content="Difference Tolerance %:" Style="{StaticResource @InputFieldLabelStyle}" VerticalAlignment="Center" FontSize="12"/> + <Label x:Name="xDifferenceTolerenceLabel" Content="Difference Tolerance %:" Style="{StaticResource @InputFieldLabelStyle}" VerticalAlignment="Center" FontSize="12"/>Note: Consider renaming x:Name to xDifferenceToleranceLabel for consistency if not referenced in code-behind.
Likely an incorrect or invalid review comment.
| private void GingerPlayLearnMore_Click(object sender, RoutedEventArgs e) | ||
| { | ||
| var imageUri = new Uri("pack://application:,,,/Ginger;component/UserControlsLib/ImageMakerLib/Images/GingerPlayDetailsPopUpContent.png", UriKind.Absolute); | ||
|
|
||
| var image = new System.Windows.Controls.Image | ||
| { | ||
| Source = new System.Windows.Media.Imaging.BitmapImage(imageUri), | ||
| Stretch = Stretch.Uniform, // Maintains aspect ratio | ||
| HorizontalAlignment = HorizontalAlignment.Center, | ||
| VerticalAlignment = VerticalAlignment.Center, | ||
| Cursor = System.Windows.Input.Cursors.Hand | ||
| }; | ||
|
|
||
| // Use a Viewbox to ensure aspect ratio is maintained and image scales to fit window | ||
| var viewbox = new Viewbox | ||
| { | ||
| Stretch = Stretch.Uniform, | ||
| Child = image | ||
| }; | ||
|
|
||
| var border = new Border | ||
| { | ||
| Child = viewbox, | ||
| Background = Brushes.Transparent | ||
| }; | ||
|
|
||
| border.MouseLeftButtonUp += (s, args) => | ||
| { | ||
| try | ||
| { | ||
| Process.Start(new ProcessStartInfo | ||
| { | ||
| FileName = "https://www.amdocs.com/products-services/quality-engineering-services", | ||
| UseShellExecute = true | ||
| }); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); | ||
| } | ||
| }; | ||
|
|
||
| Window bannerWindow = new Window | ||
| { | ||
| Title = "Explore Pro Features Using Ginger Play", | ||
| Width = 900, | ||
| Height = 700, | ||
| WindowStartupLocation = WindowStartupLocation.CenterOwner, | ||
| ResizeMode = ResizeMode.NoResize, | ||
| WindowStyle = WindowStyle.ThreeDBorderWindow, | ||
| ShowInTaskbar = false, | ||
| Content = border, | ||
| SizeToContent = SizeToContent.Manual, | ||
| }; | ||
|
|
||
| bannerWindow.ShowDialog(); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Make banner modal to parent and close on click
Set Owner so CenterOwner works and close the dialog after navigation for cleaner UX.
- private void GingerPlayLearnMore_Click(object sender, RoutedEventArgs e)
- {
+ private void GingerPlayLearnMore_Click(object sender, RoutedEventArgs e)
+ {
var imageUri = new Uri("pack://application:,,,/Ginger;component/UserControlsLib/ImageMakerLib/Images/GingerPlayDetailsPopUpContent.png", UriKind.Absolute);
+ Window bannerWindow = null;
@@
- border.MouseLeftButtonUp += (s, args) =>
+ border.MouseLeftButtonUp += (s, args) =>
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = "https://www.amdocs.com/products-services/quality-engineering-services",
UseShellExecute = true
});
}
catch (Exception ex)
{
MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
+ finally
+ {
+ bannerWindow?.Close();
+ }
};
- Window bannerWindow = new Window
+ bannerWindow = new Window
{
Title = "Explore Pro Features Using Ginger Play",
Width = 900,
Height = 700,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
ResizeMode = ResizeMode.NoResize,
WindowStyle = WindowStyle.ThreeDBorderWindow,
ShowInTaskbar = false,
Content = border,
SizeToContent = SizeToContent.Manual,
};
+ bannerWindow.Owner = Window.GetWindow(this);
bannerWindow.ShowDialog();
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private void GingerPlayLearnMore_Click(object sender, RoutedEventArgs e) | |
| { | |
| var imageUri = new Uri("pack://application:,,,/Ginger;component/UserControlsLib/ImageMakerLib/Images/GingerPlayDetailsPopUpContent.png", UriKind.Absolute); | |
| var image = new System.Windows.Controls.Image | |
| { | |
| Source = new System.Windows.Media.Imaging.BitmapImage(imageUri), | |
| Stretch = Stretch.Uniform, // Maintains aspect ratio | |
| HorizontalAlignment = HorizontalAlignment.Center, | |
| VerticalAlignment = VerticalAlignment.Center, | |
| Cursor = System.Windows.Input.Cursors.Hand | |
| }; | |
| // Use a Viewbox to ensure aspect ratio is maintained and image scales to fit window | |
| var viewbox = new Viewbox | |
| { | |
| Stretch = Stretch.Uniform, | |
| Child = image | |
| }; | |
| var border = new Border | |
| { | |
| Child = viewbox, | |
| Background = Brushes.Transparent | |
| }; | |
| border.MouseLeftButtonUp += (s, args) => | |
| { | |
| try | |
| { | |
| Process.Start(new ProcessStartInfo | |
| { | |
| FileName = "https://www.amdocs.com/products-services/quality-engineering-services", | |
| UseShellExecute = true | |
| }); | |
| } | |
| catch (Exception ex) | |
| { | |
| MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); | |
| } | |
| }; | |
| Window bannerWindow = new Window | |
| { | |
| Title = "Explore Pro Features Using Ginger Play", | |
| Width = 900, | |
| Height = 700, | |
| WindowStartupLocation = WindowStartupLocation.CenterOwner, | |
| ResizeMode = ResizeMode.NoResize, | |
| WindowStyle = WindowStyle.ThreeDBorderWindow, | |
| ShowInTaskbar = false, | |
| Content = border, | |
| SizeToContent = SizeToContent.Manual, | |
| }; | |
| bannerWindow.ShowDialog(); | |
| } | |
| private void GingerPlayLearnMore_Click(object sender, RoutedEventArgs e) | |
| { | |
| var imageUri = new Uri("pack://application:,,,/Ginger;component/UserControlsLib/ImageMakerLib/Images/GingerPlayDetailsPopUpContent.png", UriKind.Absolute); | |
| Window bannerWindow = null; | |
| var image = new System.Windows.Controls.Image | |
| { | |
| Source = new System.Windows.Media.Imaging.BitmapImage(imageUri), | |
| Stretch = Stretch.Uniform, // Maintains aspect ratio | |
| HorizontalAlignment = HorizontalAlignment.Center, | |
| VerticalAlignment = VerticalAlignment.Center, | |
| Cursor = System.Windows.Input.Cursors.Hand | |
| }; | |
| // Use a Viewbox to ensure aspect ratio is maintained and image scales to fit window | |
| var viewbox = new Viewbox | |
| { | |
| Stretch = Stretch.Uniform, | |
| Child = image | |
| }; | |
| var border = new Border | |
| { | |
| Child = viewbox, | |
| Background = Brushes.Transparent | |
| }; | |
| border.MouseLeftButtonUp += (s, args) => | |
| { | |
| try | |
| { | |
| Process.Start(new ProcessStartInfo | |
| { | |
| FileName = "https://www.amdocs.com/products-services/quality-engineering-services", | |
| UseShellExecute = true | |
| }); | |
| } | |
| catch (Exception ex) | |
| { | |
| MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); | |
| } | |
| finally | |
| { | |
| bannerWindow?.Close(); | |
| } | |
| }; | |
| bannerWindow = new Window | |
| { | |
| Title = "Explore Pro Features Using Ginger Play", | |
| Width = 900, | |
| Height = 700, | |
| WindowStartupLocation = WindowStartupLocation.CenterOwner, | |
| ResizeMode = ResizeMode.NoResize, | |
| WindowStyle = WindowStyle.ThreeDBorderWindow, | |
| ShowInTaskbar = false, | |
| Content = border, | |
| SizeToContent = SizeToContent.Manual | |
| }; | |
| bannerWindow.Owner = Window.GetWindow(this); | |
| bannerWindow.ShowDialog(); | |
| } |
🤖 Prompt for AI Agents
In Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs
around lines 256-312, the banner window is not set as modal to its parent and
doesn't close after the link is opened; set bannerWindow.Owner =
Window.GetWindow(this) (or Application.Current.MainWindow if appropriate) before
showing it so CenterOwner is effective and the window is modal to the parent,
and modify the border.MouseLeftButtonUp handler so that after successfully
starting the process it calls bannerWindow.Close() (ensure bannerWindow is
captured by the handler), while still showing an error MessageBox on exception.
| <Hyperlink NavigateUri="https://github.com/Visual-Regression-Tracker/Visual-Regression-Tracker" RequestNavigate="Hyperlink_RequestNavigate"> | ||
| <Run Text="Learn more about VRT"/> | ||
| </Hyperlink></TextBlock> | ||
| <TextBlock Margin="0,10,0,0" FontSize="14"> | ||
| <Hyperlink NavigateUri="https://ginger-automation.github.io/Ginger-Web-Help/assets/Ginger_By_Amdocs/Integrations/Visual_Testing_using_VRT.htm" RequestNavigate="Hyperlink_RequestNavigate"> | ||
| <Run Text="Learn more about how to use VRT in Ginger"/> | ||
| </Hyperlink></TextBlock> |
There was a problem hiding this comment.
🧩 Analysis chain
Ensure hyperlink navigation handler exists and marks event handled
Verify Hyperlink_RequestNavigate is implemented in the code-behind and sets e.Handled = true to prevent default behavior.
Run:
🏁 Script executed:
#!/bin/bash
rg -n -C2 --type=cs 'void\s+Hyperlink_RequestNavigate\s*\('
rg -n 'GingerPlayDetailsPopUpContent\.png|VRTExternalConfigurationsPage\.xaml\.cs|ApplitoolsExternalConfigurationsPage\.xaml\.cs'Length of output: 5791
Add e.Handled = true in Hyperlink_RequestNavigate
In VRTExternalConfigurationsPage.xaml.cs’s Hyperlink_RequestNavigate, append e.Handled = true after the Process.Start(...) call to suppress default navigation.
🤖 Prompt for AI Agents
In Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml
around lines 137-143, the Hyperlink RequestNavigate handler does not suppress
default navigation; update the Hyperlink_RequestNavigate method in
VRTExternalConfigurationsPage.xaml.cs to set e.Handled = true immediately after
the Process.Start(...) call so the routed event is marked handled and the
default navigation is prevented.
| private void ProFeatureButtonClick(object sender, RoutedEventArgs e) | ||
| { | ||
| var imageUri = new Uri("pack://application:,,,/Ginger;component/UserControlsLib/ImageMakerLib/Images/GingerPlayDetailsPopUpContent.png", UriKind.Absolute); | ||
|
|
||
| var image = new System.Windows.Controls.Image | ||
| { | ||
| Source = new System.Windows.Media.Imaging.BitmapImage(imageUri), | ||
| Stretch = Stretch.Uniform, // Maintains aspect ratio | ||
| HorizontalAlignment = HorizontalAlignment.Center, | ||
| VerticalAlignment = VerticalAlignment.Center, | ||
| Cursor = System.Windows.Input.Cursors.Hand | ||
| }; | ||
|
|
||
| // Use a Viewbox to ensure aspect ratio is maintained and image scales to fit window | ||
| var viewbox = new Viewbox | ||
| { | ||
| Stretch = Stretch.Uniform, | ||
| Child = image | ||
| }; | ||
|
|
||
| var border = new Border | ||
| { | ||
| Child = viewbox, | ||
| Background = Brushes.Transparent | ||
| }; | ||
|
|
||
| border.MouseLeftButtonUp += (s, args) => | ||
| { | ||
| try | ||
| { | ||
| Process.Start(new ProcessStartInfo | ||
| { | ||
| FileName = "https://www.amdocs.com/products-services/quality-engineering-services", | ||
| UseShellExecute = true | ||
| }); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); | ||
| } | ||
| }; | ||
|
|
||
| Window bannerWindow = new Window | ||
| { | ||
| Title = "Explore Pro Features Using Ginger Play", | ||
| Width = 900, | ||
| Height = 700, | ||
| WindowStartupLocation = WindowStartupLocation.CenterOwner, | ||
| ResizeMode = ResizeMode.NoResize, | ||
| Owner = this, | ||
| WindowStyle = WindowStyle.ThreeDBorderWindow, | ||
| ShowInTaskbar = false, | ||
| Content = border, | ||
| SizeToContent = SizeToContent.Manual, | ||
| }; | ||
|
|
||
| bannerWindow.ShowDialog(); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Harden promo dialog: handle image load errors, close after click, set cursor on entire area
- BitmapImage(imageUri) can throw if resource missing; wrap in try/catch.
- Close the dialog after opening the link.
- Make the entire surface show Hand cursor.
Apply this diff:
private void ProFeatureButtonClick(object sender, RoutedEventArgs e)
{
- var imageUri = new Uri("pack://application:,,,/Ginger;component/UserControlsLib/ImageMakerLib/Images/GingerPlayDetailsPopUpContent.png", UriKind.Absolute);
-
- var image = new System.Windows.Controls.Image
- {
- Source = new System.Windows.Media.Imaging.BitmapImage(imageUri),
- Stretch = Stretch.Uniform, // Maintains aspect ratio
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center,
- Cursor = System.Windows.Input.Cursors.Hand
- };
+ var imageUri = new Uri("pack://application:,,,/Ginger;component/UserControlsLib/ImageMakerLib/Images/GingerPlayDetailsPopUpContent.png", UriKind.Absolute);
+ System.Windows.Media.Imaging.BitmapImage bitmap;
+ try
+ {
+ bitmap = new System.Windows.Media.Imaging.BitmapImage();
+ bitmap.BeginInit();
+ bitmap.UriSource = imageUri;
+ bitmap.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.OnLoad;
+ bitmap.EndInit();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Unable to load promo content: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ var image = new System.Windows.Controls.Image
+ {
+ Source = bitmap,
+ Stretch = Stretch.Uniform,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center,
+ Cursor = System.Windows.Input.Cursors.Hand
+ };
@@
var border = new Border
{
Child = viewbox,
- Background = Brushes.Transparent
+ Background = Brushes.Transparent,
+ Cursor = Cursors.Hand
};
border.MouseLeftButtonUp += (s, args) =>
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = "https://www.amdocs.com/products-services/quality-engineering-services",
UseShellExecute = true
});
+ // Close the banner window after click
+ Window.GetWindow(border)?.Close();
}
catch (Exception ex)
{
MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
};
@@
bannerWindow.ShowDialog();
}You can also verify the embedded resource exists and is included in the project:
🏁 Script executed:
#!/bin/bash
rg -n "GingerPlayDetailsPopUpContent\.png"
rg -n "GingerPlayDetailsPopUpContent\.png" Ginger/Ginger/Ginger.csprojLength of output: 902
Harden promo dialog: wrap image load in try/catch, extend clickable area, close dialog
- Wrap
BitmapImageinit (BeginInit/EndInit) in try/catch andreturnon failure. - Set
Cursor=Handon theBorder, not just theImage. - After
Process.Start(…), callWindow.GetWindow(border)?.Close()to dismiss the banner.
🤖 Prompt for AI Agents
In Ginger/Ginger/MainWindow.xaml.cs around lines 1944-2001, harden the promo
dialog by wrapping the BitmapImage creation in a try/catch (use
BitmapImage.BeginInit()/EndInit(), set UriSource, and on any exception log or
show a brief message and return to avoid showing a broken dialog), move/set
Cursor = Cursors.Hand on the Border (not just the Image) so the whole area is
clickable, and after the Process.Start succeeds call
Window.GetWindow(border)?.Close() inside the click handler to dismiss the
banner; keep the existing error handling for Process.Start but ensure the dialog
is only shown when the image load succeeds.
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml (1)
45-52: Fix textbox layout overflow in new two-column grid.The hard-coded
Width=414+Margin=139onxZAPURLTextBox/xZAPAPIkeyTextBoxassumes a full-width layout. In the new 3*:2* split, column 0 is ~60 % of the page (≈480 px at 800 px width). The controls now need 553 px (414 px + 139 px margin), so they spill into column 1 and clip beneath the About panel whenever the window is ≤900 px wide. Remove the fixed width/margin and let the grid column drive sizing.- <Activities:UCValueExpression x:Name="xZAPURLTextBox" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="GingerOps Account URL" Margin="139,0,0,0" Width="414" Grid.ColumnSpan="2"/> + <Activities:UCValueExpression x:Name="xZAPURLTextBox" Grid.Column="1" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" ToolTip="GingerOps Account URL" Margin="10,0,0,0" MinWidth="250"/> ... - <Activities:UCValueExpression x:Name="xZAPAPIkeyTextBox" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="Client Secret" Margin="139,0,0,0" Width="414" LostKeyboardFocus="xZAPAPIkeyTextBox_LostKeyboardFocus" Grid.ColumnSpan="2"/> + <Activities:UCValueExpression x:Name="xZAPAPIkeyTextBox" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" ToolTip="Client Secret" Margin="10,0,0,0" MinWidth="250" LostKeyboardFocus="xZAPAPIkeyTextBox_LostKeyboardFocus"/>
♻️ Duplicate comments (9)
Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml (6)
142-148: Hyperlink handler verification still needed.The hyperlinks use
RequestNavigate="Hyperlink_RequestNavigate"handler. A previous review requested verification that the handler implementation setse.Handled = trueto prevent default navigation behavior. This verification has not been completed.
11-11: Title mismatch remains unresolved.The page title is still "Execution Logger Configuration" instead of a VRT-specific title. This issue was flagged in a previous review but has not been addressed.
25-25: Irrelevant DockPanel.Dock attribute remains.The
DockPanel.Dock="Top"attribute on xSaveButton has no effect since it's inside a Grid. This issue was flagged in a previous review but has not been cleaned up.
32-49: Excessive zero-height rows remain.Multiple
RowDefinitionentries withHeight="0"are still present, which adds unnecessary complexity. This issue was flagged in a previous review but has not been addressed.
59-59: Fixed widths on input controls remain.The
Width="400"constraint on UCValueExpression controls prevents responsive layout. This issue was flagged in a previous review but has not been addressed.Also applies to: 65-65, 77-77, 83-83, 88-88
91-91: Negative margin remains.The
Margin="-15,0,0,0"on xEnableSoftAssertPanel can cause layout glitches. This issue was flagged in a previous review but has not been addressed.Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (2)
250-254: Consolidate duplicated hyperlink handler.This method is already flagged in previous review comments as being duplicated across multiple configuration pages. The duplication violates DRY principles and should be consolidated into a base class or static helper.
299-354: Extract duplicated banner window to shared helper.This comment echoes previous feedback and highlights additional duplication.
ShowGingerPlayBannerWindowis duplicated identically inTwoLevelMenuPage.xaml.cs(lines 287-342), and the banner window modal issues flagged in earlier reviews remain unaddressed.Extract the banner window logic to a static helper and ensure the window is properly modal:
public static class GingerPlayBannerHelper { public static void ShowBannerWindow(Window owner) { var imageUri = new Uri("pack://application:,,,/Ginger;component/UserControlsLib/ImageMakerLib/Images/GingerPlayDetailsPopUpContent.png", UriKind.Absolute); var image = new System.Windows.Controls.Image { Source = new System.Windows.Media.Imaging.BitmapImage(imageUri), Stretch = Stretch.Uniform, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Cursor = System.Windows.Input.Cursors.Hand }; var viewbox = new Viewbox { Stretch = Stretch.Uniform, Child = image }; var border = new Border { Child = viewbox, Background = Brushes.Transparent }; Window bannerWindow = new Window { Title = "Get to know Ginger Play", Width = 900, Height = 700, WindowStartupLocation = WindowStartupLocation.CenterOwner, Owner = owner, ResizeMode = ResizeMode.NoResize, WindowStyle = WindowStyle.ThreeDBorderWindow, ShowInTaskbar = false, Content = border, SizeToContent = SizeToContent.Manual, }; border.MouseLeftButtonUp += (s, args) => { try { Process.Start(new ProcessStartInfo { FileName = "https://www.amdocs.com/products-services/quality-engineering-services", UseShellExecute = true }); bannerWindow.Close(); } catch (Exception ex) { MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }; bannerWindow.ShowDialog(); } }Then replace both implementations with:
- private void ShowGingerPlayBannerWindow() - { - // ... entire method body - } + private void ShowGingerPlayBannerWindow() + { + GingerPlayBannerHelper.ShowBannerWindow(Window.GetWindow(this)); + }Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml (1)
54-65: Remove fixed 400 px widths to prevent clipping in split layout.The new 3*:2* grid leaves ~340 px for column 1 inside
xApplitoolsGridat standard window sizes. The hard-codedWidth="400"forces both value-expression controls to extend past the column, overlapping the right “About” panel (and ScrollViewer has horizontal scrolling disabled). Let the grid manage width so the inputs stay visible.- <Activities:UCValueExpression x:Name="xAPIURLTextBox" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="Applitools API URL" Margin="10,0,0,0" Width="400"/> + <Activities:UCValueExpression x:Name="xAPIURLTextBox" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Center" ToolTip="Applitools API URL" Margin="10,0,0,0" MinWidth="250"/> ... - <Activities:UCValueExpression x:Name="xAPIKeyTextBox" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="API Key" Margin="10,0,0,0" Width="400"/> + <Activities:UCValueExpression x:Name="xAPIKeyTextBox" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" ToolTip="API Key" Margin="10,0,0,0" MinWidth="250"/>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
Ginger/Ginger/UserControlsLib/ImageMakerLib/Images/GingerPlayWhiteGradiant.pngis excluded by!**/*.png,!**/*.png
📒 Files selected for processing (12)
Ginger/Ginger/ApplicationModelsLib/POMModels/POMWizardLib/LearnWizard/POMLearnConfigWizardPage.xaml.cs(1 hunks)Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs(2 hunks)Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml(2 hunks)Ginger/Ginger/MainWindow.xaml(3 hunks)Ginger/Ginger/MainWindow.xaml.cs(1 hunks)Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml(1 hunks)Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs(2 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-07-16T14:42:32.229Z
Learnt from: prashelke
PR: Ginger-Automation/Ginger#4254
File: Ginger/Ginger/ApplicationModelsLib/POMModels/POMWizardLib/LearnWizard/POMLearnConfigWizardPage.xaml.cs:70-73
Timestamp: 2025-07-16T14:42:32.229Z
Learning: In Ginger/Ginger/ApplicationModelsLib/POMModels/POMWizardLib/LearnWizard/POMLearnConfigWizardPage.xaml.cs, prashelke prefers to keep the current `!WorkSpace.Instance.BetaFeatures.ShowPOMForAI` logic for binding and showing AI POM controls, rather than changing it to positive logic.
Applied to files:
Ginger/Ginger/ApplicationModelsLib/POMModels/POMWizardLib/LearnWizard/POMLearnConfigWizardPage.xaml.cs
📚 Learning: 2025-08-28T09:27:18.847Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4286
File: Ginger/Ginger/Drivers/DriversConfigsEditPages/WebAgentConfigEditPage.xaml.cs:556-571
Timestamp: 2025-08-28T09:27:18.847Z
Learning: In Ginger's WebAgentConfigEditPage.xaml.cs ZAP configuration, when ZAP Security Testing is enabled, the manual proxy UI should remain enabled/accessible even though ZAP will override the proxy settings in the background. This allows users to see and modify their proxy configurations for transparency and future use when ZAP is disabled. Confirmed by AmanPrasad43 in PR #4286.
Applied to files:
Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml
📚 Learning: 2025-08-26T07:40:08.345Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4285
File: Ginger/Ginger/Actions/ActionEditPages/ActSecurityTestingEditPage.xaml:23-23
Timestamp: 2025-08-26T07:40:08.345Z
Learning: In the Ginger codebase ActSecurityTestingEditPage.xaml file, the large bottom margin of 530 on the "Acceptable Alerts" label (Margin="10,10,0,530") is intentional design choice, not an error.
Applied to files:
Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml
📚 Learning: 2025-03-20T11:10:33.780Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4137
File: Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs:21-21
Timestamp: 2025-03-20T11:10:33.780Z
Learning: The `Amdocs.Ginger.Common.SourceControlLib` namespace is required in files that reference the `GingerSolution` class for source control operations in the Ginger automation framework.
Applied to files:
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs
📚 Learning: 2025-04-25T13:29:45.059Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4188
File: Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs:22-23
Timestamp: 2025-04-25T13:29:45.059Z
Learning: The `using Amdocs.Ginger.Repository;` statement in Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs is necessary as it provides access to the `ObservableList<>` class which is used throughout the file for collections of RunSetConfig, AnalyzerItemBase, and ApplicationPOMModel objects.
Applied to files:
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs
🔇 Additional comments (9)
Ginger/Ginger/ApplicationModelsLib/POMModels/POMWizardLib/LearnWizard/POMLearnConfigWizardPage.xaml.cs (1)
63-63: LGTM! Icon update aligns with Ginger Play UI enhancements.The updated default icon from
GingerPlayLogotoGingerPlayWhiteGradiantis a straightforward cosmetic change that aligns with the PR's objective to enhance Ginger Play branding and UI elements.Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml (1)
16-19: New two-column layout and About panel look good.The restructured layout with a dedicated "About VRT" panel in the right column aligns well with the PR objectives. The styling with rounded border, proper spacing, and informative content enhances the user experience. The icon integration and section organization are clean and professional.
Also applies to: 107-151
Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml (4)
13-13: LGTM!Disabling horizontal scrollbar is appropriate for the new two-column fixed-width layout.
16-19: LGTM!The 3:2 column ratio provides a good balance between the configuration form and the informational panel.
20-99: LGTM!The form refactoring into a grid-based layout with explicit row/column positioning is well-structured and maintains all existing controls.
109-148: Verify ImageType enum values and hyperlink handler implementation.The About panel structure is well-designed, but please verify:
ImageType enum values: Confirm that
ImageType="Sealights"(line 124) andImageType="Link"(line 145) are defined in the ImageType enum. If these are new additions in this PR, ensure they're properly implemented.Hyperlink handler: The
Hyperlink_RequestNavigatehandler (line 143) must be implemented in the code-behind file. Based on the summary, this handler should useProcess.StartwithUseShellExecute = trueto open the link in the system browser.Run the following script to verify the ImageType enum and hyperlink handler:
Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml (1)
53-93: Add error handling for external URL navigation.The hyperlink opens an external URL via
Process.Startwithout error handling. If the URL fails to open (e.g., no default browser, restricted environment), the user receives no feedback.Verify that the
Hyperlink_RequestNavigatehandler in the code-behind includes try-catch error handling:If error handling is missing, add it to prevent silent failures:
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e) { try { Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true }); e.Handled = true; } catch (Exception ex) { // Log error or show user notification MessageBox.Show($"Failed to open URL: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml (1)
10-126: LGTM: Well-structured upgrade button UI.The layout restructuring to add a fixed upgrade button at the top-right is cleanly implemented. The gradient styling, icon integration, and event binding are all properly configured.
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml (1)
14-137: LGTM: Clean two-column layout with informative About panel.The restructuring from single-column to two-column grid effectively separates the configuration form from the informational About panel. The layout is well-organized, and the About panel provides clear feature descriptions and a learn more hyperlink.
| <TextBlock Margin="0,10,0,0" FontSize="14"> | ||
| <Hyperlink NavigateUri="https://www.sealights.io/" RequestNavigate="Hyperlink_RequestNavigate"> | ||
| <Run Text="Learn more about Sealights"/> | ||
| </Hyperlink> <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/> </TextBlock> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Fix XAML formatting for readability.
The hyperlink closing tag and image control are combined on a single line, making the markup difficult to read and maintain.
Apply this diff to improve formatting:
- </Hyperlink> <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/> </TextBlock>
+ </Hyperlink>
+ <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/>
+ </TextBlock>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| </Hyperlink> <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/> </TextBlock> | |
| </Hyperlink> | |
| <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/> | |
| </TextBlock> |
🤖 Prompt for AI Agents
In Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml
around line 145, the closing </Hyperlink> tag and the
<usercontrols:ImageMakerControl .../> are on the same line making the XAML hard
to read; split them so the </Hyperlink> is on its own line and the
ImageMakerControl is on the following line, preserving surrounding indentation
and spacing (one element per line) to improve readability and maintain
consistent formatting with adjacent XAML.
| <Border | ||
| Margin="30,0,10,0" | ||
| Background="GhostWhite" | ||
| CornerRadius="10" | ||
| BorderBrush="#B6E0FE" | ||
| BorderThickness="1" | ||
| VerticalAlignment="Top" | ||
| Height="Auto"> | ||
| <StackPanel Margin="10" | ||
| HorizontalAlignment="Left" | ||
| VerticalAlignment="Top" | ||
| Height="Auto" | ||
| > | ||
| <StackPanel Orientation="Horizontal" VerticalAlignment="Top"> | ||
| <usercontrols:ImageMakerControl ImageType="WireMockLogo" Height="20" Width="20" Margin="0,2,10,0"/> | ||
| <TextBlock Text="About WireMock" | ||
| FontWeight="Normal" | ||
| FontSize="18" | ||
| VerticalAlignment="Center"/> | ||
|
|
||
| </StackPanel> | ||
| <Separator Margin="0,10,0,10"/> | ||
| <TextBlock TextWrapping="Wrap" | ||
| Foreground="#333" | ||
| FontSize="14" | ||
| Margin="0,0,0,10"> | ||
| WireMock is a tool to simulate (mock) APIs for testing and development. | ||
| Instead of calling a real backend, you can create custom endpoints that return the responses you need—errors, delays, or special cases included. | ||
| This is ideal when real APIs aren’t available, unstable, or costly to use. | ||
|
|
||
|
|
||
| </TextBlock> | ||
|
|
||
| <TextBlock TextWrapping="Wrap" FontWeight="Bold" Text="With Ginger, WireMock lets you validate app behavior even before the real APIs are ready."/> | ||
| <TextBlock Margin="0,10,0,0" FontSize="14"> | ||
| <Hyperlink NavigateUri="https://wiremock.org/" RequestNavigate="Hyperlink_RequestNavigate"> | ||
| <Run Text="Learn more about WireMock"/> | ||
| </Hyperlink><usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/></TextBlock> | ||
|
|
||
| </StackPanel> | ||
| <Activities:UCValueExpression x:Name="xWMURLTextBox" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="WireMock Host URL" Margin="10,0,0,0" Width="400"/> | ||
| </Grid> | ||
| <Grid> | ||
| <usercontrols:ucButton x:Name="xTestConBtn" IsEnabled="True" DockPanel.Dock="Top" HorizontalAlignment="Left" Margin="10,25,0,0" ButtonType="RoundTextAndImageButton" ButtonText="Test Connection" ButtonImageType="Run" ButtonFontImageSize="12" ButtonImageWidth="12" ButtonImageHeight="12" Click="xTestConBtn_Click" ButtonStyle="{StaticResource $RoundTextAndImageButtonStyle}" ToolTip="Test WireMock Connection"/> | ||
| <usercontrols:ImageMakerControl x:Name="xProcessingImage" ImageType="Processing" Margin="187,28,0,3" HorizontalAlignment="Left" Height="25" Width="20" Visibility="Collapsed"></usercontrols:ImageMakerControl> | ||
| <usercontrols:ucButton x:Name="xViewMappingBtn" IsEnabled="True" Visibility="Collapsed" DockPanel.Dock="Top" HorizontalAlignment="Left" Margin="185,25,0,0" ButtonType="RoundTextAndImageButton" ButtonText="View Mapping" ButtonImageType="View" ButtonFontImageSize="12" ButtonImageWidth="12" ButtonImageHeight="12" Click="xViewMappingBtn_Click" ButtonStyle="{StaticResource $RoundTextAndImageButtonStyle}" ToolTip="View WireMock Mapping"/> | ||
| </Grid> | ||
| </StackPanel> | ||
| </Border> |
There was a problem hiding this comment.
Add accessibility support for screen readers.
The About panel and hyperlink lack AutomationProperties for screen reader users. This impacts users relying on assistive technologies.
Apply this diff to improve accessibility:
<Border
+ AutomationProperties.Name="About WireMock Information Panel"
Margin="30,0,10,0"
Background="GhostWhite"
...>
<StackPanel ...>
...
<TextBlock TextWrapping="Wrap" FontWeight="Bold" Text="With Ginger, WireMock lets you validate app behavior even before the real APIs are ready."/>
<TextBlock Margin="0,10,0,0" FontSize="14">
- <Hyperlink NavigateUri="https://wiremock.org/" RequestNavigate="Hyperlink_RequestNavigate">
+ <Hyperlink NavigateUri="https://wiremock.org/" RequestNavigate="Hyperlink_RequestNavigate" AutomationProperties.Name="Learn more about WireMock external link">
<Run Text="Learn more about WireMock"/>
</Hyperlink>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Border | |
| Margin="30,0,10,0" | |
| Background="GhostWhite" | |
| CornerRadius="10" | |
| BorderBrush="#B6E0FE" | |
| BorderThickness="1" | |
| VerticalAlignment="Top" | |
| Height="Auto"> | |
| <StackPanel Margin="10" | |
| HorizontalAlignment="Left" | |
| VerticalAlignment="Top" | |
| Height="Auto" | |
| > | |
| <StackPanel Orientation="Horizontal" VerticalAlignment="Top"> | |
| <usercontrols:ImageMakerControl ImageType="WireMockLogo" Height="20" Width="20" Margin="0,2,10,0"/> | |
| <TextBlock Text="About WireMock" | |
| FontWeight="Normal" | |
| FontSize="18" | |
| VerticalAlignment="Center"/> | |
| </StackPanel> | |
| <Separator Margin="0,10,0,10"/> | |
| <TextBlock TextWrapping="Wrap" | |
| Foreground="#333" | |
| FontSize="14" | |
| Margin="0,0,0,10"> | |
| WireMock is a tool to simulate (mock) APIs for testing and development. | |
| Instead of calling a real backend, you can create custom endpoints that return the responses you need—errors, delays, or special cases included. | |
| This is ideal when real APIs aren’t available, unstable, or costly to use. | |
| </TextBlock> | |
| <TextBlock TextWrapping="Wrap" FontWeight="Bold" Text="With Ginger, WireMock lets you validate app behavior even before the real APIs are ready."/> | |
| <TextBlock Margin="0,10,0,0" FontSize="14"> | |
| <Hyperlink NavigateUri="https://wiremock.org/" RequestNavigate="Hyperlink_RequestNavigate"> | |
| <Run Text="Learn more about WireMock"/> | |
| </Hyperlink><usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/></TextBlock> | |
| </StackPanel> | |
| <Activities:UCValueExpression x:Name="xWMURLTextBox" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="WireMock Host URL" Margin="10,0,0,0" Width="400"/> | |
| </Grid> | |
| <Grid> | |
| <usercontrols:ucButton x:Name="xTestConBtn" IsEnabled="True" DockPanel.Dock="Top" HorizontalAlignment="Left" Margin="10,25,0,0" ButtonType="RoundTextAndImageButton" ButtonText="Test Connection" ButtonImageType="Run" ButtonFontImageSize="12" ButtonImageWidth="12" ButtonImageHeight="12" Click="xTestConBtn_Click" ButtonStyle="{StaticResource $RoundTextAndImageButtonStyle}" ToolTip="Test WireMock Connection"/> | |
| <usercontrols:ImageMakerControl x:Name="xProcessingImage" ImageType="Processing" Margin="187,28,0,3" HorizontalAlignment="Left" Height="25" Width="20" Visibility="Collapsed"></usercontrols:ImageMakerControl> | |
| <usercontrols:ucButton x:Name="xViewMappingBtn" IsEnabled="True" Visibility="Collapsed" DockPanel.Dock="Top" HorizontalAlignment="Left" Margin="185,25,0,0" ButtonType="RoundTextAndImageButton" ButtonText="View Mapping" ButtonImageType="View" ButtonFontImageSize="12" ButtonImageWidth="12" ButtonImageHeight="12" Click="xViewMappingBtn_Click" ButtonStyle="{StaticResource $RoundTextAndImageButtonStyle}" ToolTip="View WireMock Mapping"/> | |
| </Grid> | |
| </StackPanel> | |
| </Border> | |
| <Border | |
| AutomationProperties.Name="About WireMock Information Panel" | |
| Margin="30,0,10,0" | |
| Background="GhostWhite" | |
| CornerRadius="10" | |
| BorderBrush="#B6E0FE" | |
| BorderThickness="1" | |
| VerticalAlignment="Top" | |
| Height="Auto"> | |
| <StackPanel Margin="10" | |
| HorizontalAlignment="Left" | |
| VerticalAlignment="Top" | |
| Height="Auto"> | |
| <StackPanel Orientation="Horizontal" | |
| VerticalAlignment="Top"> | |
| <usercontrols:ImageMakerControl ImageType="WireMockLogo" | |
| Height="20" | |
| Width="20" | |
| Margin="0,2,10,0"/> | |
| <TextBlock Text="About WireMock" | |
| FontWeight="Normal" | |
| FontSize="18" | |
| VerticalAlignment="Center"/> | |
| </StackPanel> | |
| <Separator Margin="0,10,0,10"/> | |
| <TextBlock TextWrapping="Wrap" | |
| Foreground="#333" | |
| FontSize="14" | |
| Margin="0,0,0,10"> | |
| WireMock is a tool to simulate (mock) APIs for testing and development. | |
| Instead of calling a real backend, you can create custom endpoints that return the responses you need—errors, delays, or special cases included. | |
| This is ideal when real APIs aren’t available, unstable, or costly to use. | |
| </TextBlock> | |
| <TextBlock TextWrapping="Wrap" | |
| FontWeight="Bold" | |
| Text="With Ginger, WireMock lets you validate app behavior even before the real APIs are ready."/> | |
| <TextBlock Margin="0,10,0,0" | |
| FontSize="14"> | |
| <Hyperlink NavigateUri="https://wiremock.org/" | |
| RequestNavigate="Hyperlink_RequestNavigate" | |
| AutomationProperties.Name="Learn more about WireMock external link"> | |
| <Run Text="Learn more about WireMock"/> | |
| </Hyperlink> | |
| <usercontrols:ImageMakerControl ImageType="Link" | |
| Height="10" | |
| Width="10" | |
| Margin="0,2,10,0"/> | |
| </TextBlock> | |
| </StackPanel> | |
| </Border> |
| Margin="30,0,10,0" | ||
| Background="GhostWhite" | ||
| CornerRadius="10" | ||
| BorderBrush="#B6E0FE" | ||
| BorderThickness="1" | ||
| VerticalAlignment="Top" | ||
| Height="Auto"> | ||
| <StackPanel Margin="10" | ||
| HorizontalAlignment="Left" | ||
| VerticalAlignment="Top" | ||
| Height="Auto" | ||
| > |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider consistent XAML formatting.
The Border and StackPanel attributes have inconsistent indentation and line breaks (some attributes on their own lines, others inline). While not a functional issue, consistent formatting improves readability.
Consider applying consistent formatting:
<Border
-Margin="30,0,10,0"
- Background="GhostWhite"
- CornerRadius="10"
- BorderBrush="#B6E0FE"
- BorderThickness="1"
- VerticalAlignment="Top"
- Height="Auto">
- <StackPanel Margin="10"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Height="Auto"
- >
+ Margin="30,0,10,0"
+ Background="GhostWhite"
+ CornerRadius="10"
+ BorderBrush="#B6E0FE"
+ BorderThickness="1"
+ VerticalAlignment="Top"
+ Height="Auto">
+ <StackPanel Margin="10"
+ HorizontalAlignment="Left"
+ VerticalAlignment="Top"
+ Height="Auto">📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Margin="30,0,10,0" | |
| Background="GhostWhite" | |
| CornerRadius="10" | |
| BorderBrush="#B6E0FE" | |
| BorderThickness="1" | |
| VerticalAlignment="Top" | |
| Height="Auto"> | |
| <StackPanel Margin="10" | |
| HorizontalAlignment="Left" | |
| VerticalAlignment="Top" | |
| Height="Auto" | |
| > | |
| <Border | |
| Margin="30,0,10,0" | |
| Background="GhostWhite" | |
| CornerRadius="10" | |
| BorderBrush="#B6E0FE" | |
| BorderThickness="1" | |
| VerticalAlignment="Top" | |
| Height="Auto"> | |
| <StackPanel Margin="10" | |
| HorizontalAlignment="Left" | |
| VerticalAlignment="Top" | |
| Height="Auto"> |
🤖 Prompt for AI Agents
In Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml around
lines 54 to 65, the Border and nested StackPanel attribute formatting is
inconsistent (some attributes inline, others each on their own line); reformat
these XAML elements so attributes follow a consistent style (either put each
attribute on its own line and aligned, or keep short attribute lists inline),
ensure indentation of child elements matches parent element indentation, and run
the project XAML formatter or your editor's auto-format to apply the chosen
style across this block.
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml (1)
45-46: Correct tooltips for ZAP fields.Tooltips reference GingerOps/Client Secret; update to ZAP-specific text.
- <Activities:UCValueExpression x:Name="xZAPURLTextBox" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="GingerOps Account URL" Margin="139,0,0,0" Width="414" Grid.ColumnSpan="2"/> + <Activities:UCValueExpression x:Name="xZAPURLTextBox" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="ZAP URL" Margin="139,0,0,0" Width="414" Grid.ColumnSpan="2"/> - <Activities:UCValueExpression x:Name="xZAPAPIkeyTextBox" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="Client Secret" Margin="139,0,0,0" Width="414" LostKeyboardFocus="xZAPAPIkeyTextBox_LostKeyboardFocus" Grid.ColumnSpan="2"/> + <Activities:UCValueExpression x:Name="xZAPAPIkeyTextBox" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="ZAP API Key" Margin="139,0,0,0" Width="414" LostKeyboardFocus="xZAPAPIkeyTextBox_LostKeyboardFocus" Grid.ColumnSpan="2"/>Also applies to: 51-52
♻️ Duplicate comments (8)
Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml (2)
100-107: Remove dead layout block.Empty StackPanel/Grid serve no purpose.
- <StackPanel Orientation="Horizontal" Grid.Row="2" > - <Grid> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="*" /> - <ColumnDefinition Width="*" /> - </Grid.ColumnDefinitions> - </Grid> - </StackPanel>
143-145: Split Hyperlink and icon onto separate lines.Improves readability; matches style used elsewhere.
- </Hyperlink> <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/> </TextBlock> + </Hyperlink> + <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/> + </TextBlock>Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml (4)
16-19: Add MinWidth to left column for responsiveness.Prevents crowding on small widths.
<Grid.ColumnDefinitions> - <ColumnDefinition Width="3*"/> + <ColumnDefinition Width="3*" MinWidth="400"/> <ColumnDefinition Width="2*"/> </Grid.ColumnDefinitions>
53-60: Use theme resources instead of hard-coded colors.Swap GhostWhite/#B6E0FE for StaticResource brushes.
53-93: Add accessibility metadata (panel/link).Provide AutomationProperties for screen readers.
- <Border + <Border + AutomationProperties.Name="About WireMock Information Panel" ... - <TextBlock Margin="0,10,0,0" FontSize="14"> - <Hyperlink NavigateUri="https://wiremock.org/" RequestNavigate="Hyperlink_RequestNavigate"> + <TextBlock Margin="0,10,0,0" FontSize="14"> + <Hyperlink NavigateUri="https://wiremock.org/" RequestNavigate="Hyperlink_RequestNavigate" + AutomationProperties.Name="Learn more about WireMock (opens in browser)"> <Run Text="Learn more about WireMock"/> </Hyperlink>
87-90: Split Hyperlink and icon onto separate lines.Improve readability.
- </Hyperlink><usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/></TextBlock> + </Hyperlink> + <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/> + </TextBlock>Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml (2)
11-11: Page title still incorrect (previously flagged).The title still says "Execution Logger Configuration" instead of a VRT-specific title. This was flagged in a previous review but remains unresolved, causing potential confusion for users navigating to this page.
Apply this diff:
- Title="Execution Logger Configuration"> + Title="Visual Regression Testing (VRT) Configuration">
91-93: Negative margin still present despite previous resolution claim.A previous review flagged the negative left margin (
Margin="-15,0,0,0") and marked it as addressed in commit bab1efc. However, the negative margin is still present in the current code. Negative margins can cause layout glitches and should be avoided in favor of proper alignment and padding.Apply this diff to remove the negative margin:
-<StackPanel x:Name="xEnableSoftAssertPanel" Margin="-15,0,0,0" Orientation="Horizontal" ToolTip="Select 'No' to ignore mismatches on checkpoint actions." VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="12" Grid.Column="1"> +<StackPanel x:Name="xEnableSoftAssertPanel" Margin="0,0,0,0" Orientation="Horizontal" ToolTip="Select 'No' to ignore mismatches on checkpoint actions." VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="12" Grid.Column="1">If the intent is to align the radio buttons with controls in other rows, adjust the Grid's ColumnDefinition padding or the parent column's margin instead.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/SealightsExternalConfigurationsPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/WireMockConfigurationPage.xaml(1 hunks)Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml(2 hunks)Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-26T07:40:08.345Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4285
File: Ginger/Ginger/Actions/ActionEditPages/ActSecurityTestingEditPage.xaml:23-23
Timestamp: 2025-08-26T07:40:08.345Z
Learning: In the Ginger codebase ActSecurityTestingEditPage.xaml file, the large bottom margin of 530 on the "Acceptable Alerts" label (Margin="10,10,0,530") is intentional design choice, not an error.
Applied to files:
Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xamlGinger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml
🔇 Additional comments (5)
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml (3)
65-74: Check overlay/z-order and hit testing.The fixed top-right promo can overlap nav/content. Validate it doesn’t block interactions at common window sizes; add Panel.ZIndex if needed.
Also applies to: 96-109
96-106: Verify Click handler exists and is wired correctly.Ensure TwoLevelMenuPage.xaml.cs defines ProFeatureButtonClick and handles feature gating.
90-95: Confirm ImageType enum and spelling."Gradiant" looks misspelled. Verify eImageType contains the exact value used, and align naming (…Gradient).
Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml (1)
96-98: Verify RequestNavigate handler exists.Ensure ZAPConfigurationPage.xaml.cs defines Hyperlink_RequestNavigate.
Ginger/Ginger/ExternalConfigurations/VRTExternalConfigurationsPage.xaml (1)
28-28: Verify icon choice for enterprise feature indicator.The "Building" icon with "Enterprise Feature" tooltip may not be the most intuitive visual indicator. Typically, enterprise features use icons like briefcase, star, crown, or lock to convey premium/enterprise status.
Verify that the "Building" icon is the intended design choice for indicating enterprise features throughout the application. If not, consider using a more conventional icon:
-<usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Enterprise Feature" ImageType="Building" Width="20" Height="16" Foreground="{StaticResource $BackgroundColor_Black}" /> +<usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Enterprise Feature" ImageType="Star" Width="20" Height="16" Foreground="{StaticResource $BackgroundColor_Black}" />
| <Border | ||
| Margin="20,0,10,0" | ||
| Background="GhostWhite" | ||
| CornerRadius="10" | ||
| BorderBrush="#B6E0FE" | ||
| BorderThickness="1" | ||
| VerticalAlignment="Top" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Avoid hard-coded colors; use theme resources.
Replace GhostWhite/#B6E0FE with StaticResource brushes.
| <Border | ||
| Margin="20,20,10,0" | ||
| Background="GhostWhite" | ||
| CornerRadius="10" | ||
| BorderBrush="#B6E0FE" | ||
| BorderThickness="1" | ||
| VerticalAlignment="Top" | ||
| Height="Auto"> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Replace hard-coded colors with theme resources.
Use StaticResource brushes for Background/BorderBrush to maintain theme consistency.
🤖 Prompt for AI Agents
In Ginger/Ginger/ExternalConfigurations/ZAPConfigurationPage.xaml around lines
61 to 68, the Border element uses hard-coded color values for Background
("GhostWhite") and BorderBrush ("#B6E0FE"); replace these with the appropriate
StaticResource brush keys from the app theme (e.g., Background="{StaticResource
WindowBackgroundBrush}" and BorderBrush="{StaticResource AccentBorderBrush}" or
other project-standard brush names). Update the XAML to reference the theme
resources, ensure the resource keys exist in App.xaml or the theme dictionaries,
and if necessary add or map new brushes there so the control follows the
application theme.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs (2)
243-260: Duplication and syntax error already flagged.These issues have been identified in previous reviews:
- The entire method is duplicated from
GingerPlayConfigurationpage.xaml.cs(see existing comment)- Line 253 contains a double semicolon syntax error (see existing comment)
Please address the previous review comments.
287-342: Duplication already flagged; consider setting window owner.The duplication issue has been identified in a previous review comment.
Additionally, the banner window should be modal to a specific owner window for proper behavior:
+ bannerWindow.Owner = Window.GetWindow(this); bannerWindow.ShowDialog();This ensures the banner centers over the parent window and prevents interaction with it until closed.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml(1 hunks)Ginger/Ginger/RunSetLib/CreateAutoRunWizardLib/AutoRunWizardCLITypePage.xaml(1 hunks)Ginger/Ginger/RunSetLib/CreateAutoRunWizardLib/AutoRunWizardOptionsPage.xaml(2 hunks)Ginger/Ginger/RunSetLib/CreateAutoRunWizardLib/AutoRunWizardShortcutPage.xaml(1 hunks)Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-03-20T11:10:33.780Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4137
File: Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs:21-21
Timestamp: 2025-03-20T11:10:33.780Z
Learning: The `Amdocs.Ginger.Common.SourceControlLib` namespace is required in files that reference the `GingerSolution` class for source control operations in the Ginger automation framework.
Applied to files:
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs
📚 Learning: 2025-04-25T13:29:45.059Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4188
File: Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs:22-23
Timestamp: 2025-04-25T13:29:45.059Z
Learning: The `using Amdocs.Ginger.Repository;` statement in Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs is necessary as it provides access to the `ObservableList<>` class which is used throughout the file for collections of RunSetConfig, AnalyzerItemBase, and ApplicationPOMModel objects.
Applied to files:
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs
🧬 Code graph analysis (1)
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs (3)
Ginger/GingerCoreCommon/External/Configurations/GingerPlayConfiguration.cs (1)
GingerPlayConfiguration(23-246)Ginger/GingerCoreNET/WorkSpaceLib/WorkSpace.cs (1)
WorkSpace(61-1006)Ginger/GingerCoreCommon/ReporterLib/Reporter.cs (1)
Reporter(28-357)
🔇 Additional comments (8)
Ginger/Ginger/RunSetLib/CreateAutoRunWizardLib/AutoRunWizardOptionsPage.xaml (1)
35-35: LGTM!Both ImageMakerControl instances are consistently updated with the new Ginger Play branding, matching tooltip text, image type, and dimensions.
Also applies to: 44-44
Ginger/Ginger/RunSetLib/CreateAutoRunWizardLib/AutoRunWizardCLITypePage.xaml (1)
38-38: LGTM!The ImageMakerControl addition correctly introduces Ginger Play branding with consistent dimensions, tooltip, and image type matching the other updated wizard pages.
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs (2)
21-21: LGTM!The new imports are necessary and appropriate for the Ginger Play gateway URL configuration and browser launch functionality.
Also applies to: 25-25
261-284: LGTM!The implementation correctly handles both configured and unconfigured gateway URL scenarios:
- Opens the configured URL with proper error handling when available
- Falls back to the banner window when not configured
The URL concatenation is safe because
GingerPlayConfiguration.GingerPlayGatewayUrlnormalizes URLs to end with '/'.Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml (4)
14-19: LGTM!The two-column grid layout with 3*:2* proportions provides a clean separation between the configuration controls and the informational About panel.
20-89: LGTM!The left column restructuring provides a well-organized grid layout for configuration controls:
- Clear row/column definitions for consistent spacing
- Proper use of the new
GingerPlayWhiteGradiantimage type- Test Connection button and processing indicator appropriately placed
129-132: Verify ImageMakerControl placement inside TextBlock.The
ImageMakerControl(line 131) is placed inside aTextBlockafter theHyperlink. This structure may not render as intended, as WPF TextBlock inline content has restrictions on UIElement children.If the icon should appear inline with the hyperlink, consider using a
StackPanelwith horizontal orientation instead:- <TextBlock Margin="0,10,0,0" FontSize="14"> - <Hyperlink Click="GingerPlayLearnMore_Click">Learn more about Ginger Play</Hyperlink> - <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="0,2,10,0"/> - </TextBlock> + <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> + <TextBlock FontSize="14"> + <Hyperlink Click="GingerPlayLearnMore_Click">Learn more about Ginger Play</Hyperlink> + </TextBlock> + <usercontrols:ImageMakerControl ImageType="Link" Height="10" Width="10" Margin="5,0,0,0" VerticalAlignment="Center"/> + </StackPanel>Test the current rendering to confirm whether the icon displays correctly.
90-135: About panel design is well-structured.The right-column About panel provides:
- Clear visual hierarchy with header, separator, and content sections
- Informative description of Ginger Play features
- Appropriate styling with GhostWhite background and rounded border
- Useful "Learn more" link for additional information
The overall design enhances user understanding of Ginger Play integration.
|
|
||
| <!--<RadioButton x:Name="xExcelRadioButton" Checked="XExcelRadioButton_Checked" Margin="5">Dynamic Excel with Data</RadioButton>--> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Remove extraneous blank lines and commented code.
Lines 40-41 contain blank lines followed by a commented-out RadioButton for Excel. Per the PR checklist requirement to "remove unwanted/commented/junk code," consider removing this commented block unless there's a specific reason to keep it for future reference.
Apply this diff to clean up:
<usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Ginger Play Feature" ImageType="GingerPlayWhiteGradiant" Width="20" Height="15" Foreground="{StaticResource $BackgroundColor_Black}" HorizontalAlignment="Left"/>
-
-
- <!--<RadioButton x:Name="xExcelRadioButton" Checked="XExcelRadioButton_Checked" Margin="5">Dynamic Excel with Data</RadioButton>-->
</DockPanel>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <!--<RadioButton x:Name="xExcelRadioButton" Checked="XExcelRadioButton_Checked" Margin="5">Dynamic Excel with Data</RadioButton>--> | |
| <usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Ginger Play Feature" ImageType="GingerPlayWhiteGradiant" Width="20" Height="15" Foreground="{StaticResource $BackgroundColor_Black}" HorizontalAlignment="Left"/> | |
| </DockPanel> |
🤖 Prompt for AI Agents
In Ginger/Ginger/RunSetLib/CreateAutoRunWizardLib/AutoRunWizardCLITypePage.xaml
around lines 40-41, remove the extraneous blank lines and the commented-out
RadioButton line ("<!--<RadioButton x:Name="xExcelRadioButton"
Checked="XExcelRadioButton_Checked" Margin="5">Dynamic Excel with
Data</RadioButton>-->") as it is dead/commented code; if this element is needed
in the future, restore it from source control rather than keeping it commented
in the XAML. Ensure no extra blank lines remain where the comment was removed
and run a quick XAML build to verify formatting/whitespace changes introduce no
layout issues.
|
|
||
| <Label Style="{StaticResource $LabelStyle}" DockPanel.Dock="Left" Margin="-5,0,0,0">Execute Now</Label> | ||
| <usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Enterprise Feature" ImageType="Building" Width="20" Height="16" Foreground="{StaticResource $BackgroundColor_Black}" /> | ||
| <usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Enterprise Feature" ImageType="GingerPlayWhiteGradiant" Width="20" Height="16" Foreground="{StaticResource $BackgroundColor_Black}" /> |
There was a problem hiding this comment.
Fix tooltip and height inconsistencies.
The tooltip still references "Enterprise Feature" but should say "Ginger Play Feature" to align with the updated branding used in AutoRunWizardOptionsPage.xaml and AutoRunWizardCLITypePage.xaml. Additionally, the Height="16" differs from the Height="15" used consistently in those files.
Apply this diff to fix both inconsistencies:
- <usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Enterprise Feature" ImageType="GingerPlayWhiteGradiant" Width="20" Height="16" Foreground="{StaticResource $BackgroundColor_Black}" />
+ <usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Ginger Play Feature" ImageType="GingerPlayWhiteGradiant" Width="20" Height="15" Foreground="{StaticResource $BackgroundColor_Black}" />📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Enterprise Feature" ImageType="GingerPlayWhiteGradiant" Width="20" Height="16" Foreground="{StaticResource $BackgroundColor_Black}" /> | |
| <usercontrols:ImageMakerControl SetAsFontImageWithSize="16" ToolTip="Ginger Play Feature" ImageType="GingerPlayWhiteGradiant" Width="20" Height="15" Foreground="{StaticResource $BackgroundColor_Black}" /> |
🤖 Prompt for AI Agents
In Ginger/Ginger/RunSetLib/CreateAutoRunWizardLib/AutoRunWizardShortcutPage.xaml
around line 45, the ImageMakerControl has an incorrect ToolTip value and a
non-matching Height; change ToolTip="Enterprise Feature" to ToolTip="Ginger Play
Feature" and adjust Height="16" to Height="15" so it matches the branding and
height used in AutoRunWizardOptionsPage.xaml and AutoRunWizardCLITypePage.xaml.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (5)
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs (2)
243-260: Fix return value inconsistency and extract to shared helper.This method is duplicated from
GingerPlayConfigurationpage.xaml.cs(lines 255-272), but with a critical inconsistency: line 253 returnsstring.Emptywhen configuration is not found, whereas the original returnsnull(line 266 of GingerPlayConfigurationpage.xaml.cs). This inconsistency can cause bugs if different callers expect different return values for the "not configured" case.Standardize the return value (prefer
string.Emptyfor both paths) and extract to a shared helper as previously recommended.Apply this diff to standardize the return value:
private string IsGingerPlayGatewayURLConfigured() { try { GingerPlayConfiguration gingerPlayConfiguration = WorkSpace.Instance.SolutionRepository.GetFirstRepositoryItem<GingerPlayConfiguration>(); if (gingerPlayConfiguration != null && !string.IsNullOrEmpty(gingerPlayConfiguration.GingerPlayGatewayUrl)) { return gingerPlayConfiguration.GingerPlayGatewayUrl; } - return string.Empty; + return string.Empty; // Standardized: always return string.Empty when not configured } catch (Exception ex) { Reporter.ToLog(eLogLevel.ERROR, "Gateway URL is null or no configuration found", ex); return string.Empty; } }Then extract both implementations to a shared helper class (see previous review comment on GingerPlayConfigurationpage.xaml.cs).
287-342: Set window Owner for proper modal behavior and extract to shared helper.This method is duplicated from
GingerPlayConfigurationpage.xaml.cs(lines 298-354). Additionally, line 333 specifiesWindowStartupLocation.CenterOwnerbut theOwnerproperty is never set, causing the window to fail to center properly on the parent window.Apply this diff to fix the Owner property:
Window bannerWindow = new Window { Title = "Get to know Ginger Play", Width = 900, Height = 700, + Owner = Window.GetWindow(this), WindowStartupLocation = WindowStartupLocation.CenterOwner, ResizeMode = ResizeMode.NoResize, WindowStyle = WindowStyle.ThreeDBorderWindow, ShowInTaskbar = false, Content = border, SizeToContent = SizeToContent.Manual, };Then extract both implementations to a shared helper as previously recommended (see previous review comment on GingerPlayConfigurationpage.xaml.cs lines 299-354).
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (3)
250-254: Consolidate duplicated hyperlink handler into a base class.This method is duplicated identically across multiple configuration pages. As previously discussed, this will be addressed in the next release.
299-354: Make banner modal to parent and close on click.As previously suggested, the banner window should set the
Ownerproperty soCenterOwnerworks correctly and the window is modal to the parent. Additionally, the window should close after the user clicks the link for a cleaner UX.
256-273: Extract duplicated gateway URL check to shared helper and fix inconsistent return values.As previously discussed, this method will be moved to a utility class in the next release.
However, there's a new inconsistency: Line 266 returns
nullwhile the catch block at line 271 returnsstring.Empty. For consistency and to avoid potential null-reference issues in other code paths, both should return the same default value.Apply this diff to make the return values consistent:
- return null; + return string.Empty;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs(2 hunks)Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-03-20T11:10:33.780Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4137
File: Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs:21-21
Timestamp: 2025-03-20T11:10:33.780Z
Learning: The `Amdocs.Ginger.Common.SourceControlLib` namespace is required in files that reference the `GingerSolution` class for source control operations in the Ginger automation framework.
Applied to files:
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs
📚 Learning: 2025-04-25T13:29:45.059Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4188
File: Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs:22-23
Timestamp: 2025-04-25T13:29:45.059Z
Learning: The `using Amdocs.Ginger.Repository;` statement in Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs is necessary as it provides access to the `ObservableList<>` class which is used throughout the file for collections of RunSetConfig, AnalyzerItemBase, and ApplicationPOMModel objects.
Applied to files:
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs
🧬 Code graph analysis (2)
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs (4)
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (2)
IsGingerPlayGatewayURLConfigured(256-273)ShowGingerPlayBannerWindow(299-354)Ginger/GingerCoreCommon/External/Configurations/GingerPlayConfiguration.cs (1)
GingerPlayConfiguration(23-246)Ginger/GingerCoreNET/WorkSpaceLib/WorkSpace.cs (1)
WorkSpace(61-1006)Ginger/GingerCoreCommon/ReporterLib/Reporter.cs (1)
Reporter(28-357)
Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (4)
Ginger/Ginger/ExternalConfigurations/ApplitoolsExternalConfigurationsPage.xaml.cs (1)
Hyperlink_RequestNavigate(77-81)Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs (2)
IsGingerPlayGatewayURLConfigured(243-260)ShowGingerPlayBannerWindow(287-342)Ginger/GingerCoreCommon/External/Configurations/GingerPlayConfiguration.cs (1)
GingerPlayConfiguration(23-246)Ginger/GingerCoreCommon/Repository/GingerSolutionRepository.cs (1)
SolutionRepository(37-78)
🔇 Additional comments (2)
Ginger/Ginger/UserControlsLib/TwoLevelMenuLib/TwoLevelMenuPage.xaml.cs (1)
261-284: Verify gateway URL format guarantees.The logic correctly routes to either the Ginger Play portal or the promotional banner. However, line 270 concatenates
gatewayUrl + "gingerplay/#/playHome"assuming the gateway URL always ends with "/".While
GingerPlayConfiguration.GingerPlayGatewayUrlsetter ensures this (see GingerPlayConfiguration.cs lines 37-40), verify that the URL cannot be modified or loaded in a format that bypasses this validation (e.g., direct deserialization, manual file edits).Consider adding defensive concatenation:
- FileName = gatewayUrl + "gingerplay/#/playHome", + FileName = gatewayUrl.TrimEnd('/') + "/gingerplay/#/playHome",Ginger/Ginger/ExternalConfigurations/GingerPlayConfigurationpage.xaml.cs (1)
27-27: LGTM!The new using statements are necessary for the added functionality (Process.Start, URI navigation, and WPF visual elements).
Also applies to: 29-29, 33-33
| private void GingerPlayLearnMore_Click(object sender, RoutedEventArgs e) | ||
| { | ||
| string gatewayUrl = IsGingerPlayGatewayURLConfigured(); | ||
| if (!string.IsNullOrEmpty(gatewayUrl)) | ||
| { | ||
| try | ||
| { | ||
| Process.Start(new ProcessStartInfo | ||
| { | ||
| FileName = gatewayUrl + "gingerplay/#/playHome", | ||
| UseShellExecute = true | ||
| }); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| // Show the banner window if the gateway URL is not configured | ||
| ShowGingerPlayBannerWindow(); | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Validate the constructed URL before opening.
The method constructs a URL by concatenating the gateway URL with "gingerplay/#/playHome". While GingerPlayConfiguration.GingerPlayGatewayUrl ensures a trailing slash, there's no validation that the final constructed URL is well-formed before attempting to open it.
If the gateway URL is malformed or the concatenated result is invalid, the user will encounter an OS-level error rather than a friendly application message.
Consider adding URL validation:
private void GingerPlayLearnMore_Click(object sender, RoutedEventArgs e)
{
string gatewayUrl = IsGingerPlayGatewayURLConfigured();
if (!string.IsNullOrEmpty(gatewayUrl))
{
try
{
+ string targetUrl = gatewayUrl + "gingerplay/#/playHome";
+ if (!Uri.TryCreate(targetUrl, UriKind.Absolute, out Uri validatedUri) ||
+ (validatedUri.Scheme != "http" && validatedUri.Scheme != "https"))
+ {
+ MessageBox.Show("The configured Gateway URL is invalid.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
Process.Start(new ProcessStartInfo
{
- FileName = gatewayUrl + "gingerplay/#/playHome",
+ FileName = targetUrl,
UseShellExecute = true
});
}
catch (Exception ex)
{
MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private void GingerPlayLearnMore_Click(object sender, RoutedEventArgs e) | |
| { | |
| string gatewayUrl = IsGingerPlayGatewayURLConfigured(); | |
| if (!string.IsNullOrEmpty(gatewayUrl)) | |
| { | |
| try | |
| { | |
| Process.Start(new ProcessStartInfo | |
| { | |
| FileName = gatewayUrl + "gingerplay/#/playHome", | |
| UseShellExecute = true | |
| }); | |
| } | |
| catch (Exception ex) | |
| { | |
| MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); | |
| } | |
| } | |
| else | |
| { | |
| // Show the banner window if the gateway URL is not configured | |
| ShowGingerPlayBannerWindow(); | |
| } | |
| } | |
| private void GingerPlayLearnMore_Click(object sender, RoutedEventArgs e) | |
| { | |
| string gatewayUrl = IsGingerPlayGatewayURLConfigured(); | |
| if (!string.IsNullOrEmpty(gatewayUrl)) | |
| { | |
| try | |
| { | |
| // Validate the constructed URL before opening | |
| string targetUrl = gatewayUrl + "gingerplay/#/playHome"; | |
| if (!Uri.TryCreate(targetUrl, UriKind.Absolute, out Uri validatedUri) || | |
| (validatedUri.Scheme != "http" && validatedUri.Scheme != "https")) | |
| { | |
| MessageBox.Show("The configured Gateway URL is invalid.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); | |
| return; | |
| } | |
| Process.Start(new ProcessStartInfo | |
| { | |
| FileName = targetUrl, | |
| UseShellExecute = true | |
| }); | |
| } | |
| catch (Exception ex) | |
| { | |
| MessageBox.Show("Unable to open the link: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); | |
| } | |
| } | |
| else | |
| { | |
| // Show the banner window if the gateway URL is not configured | |
| ShowGingerPlayBannerWindow(); | |
| } | |
| } |
751d9d5
into
Releases/Official-Release
Thank you for your contribution.
Before submitting this PR, please make sure:
Summary by CodeRabbit
New Features
UI/Style
Usability
Chores