Skip to content

Commit 4516f34

Browse files
committed
Added workaround for custom checkboxes and radio buttons
1 parent 264c0c8 commit 4516f34

File tree

8 files changed

+99
-33
lines changed

8 files changed

+99
-33
lines changed

src/Bellatrix.Playwright/components/common/CheckBox.cs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,31 @@ public class CheckBox : Component, IComponentDisabled, IComponentChecked, ICompo
3535
/// <param name="options"></param>
3636
public virtual void Check(LocatorCheckOptions options = default)
3737
{
38-
DefaultCheck(Checking, Checked, options);
38+
var tempOptions = options ?? new LocatorCheckOptions();
39+
tempOptions.Timeout = 1;
40+
41+
Checking?.Invoke(this, new ComponentActionEventArgs(this));
42+
43+
try
44+
{
45+
DefaultCheck(null, null, tempOptions);
46+
}
47+
catch
48+
{
49+
// Fallback to JsClick, checkbox may be custom element with hidden input
50+
51+
if (!IsChecked)
52+
{
53+
var clickOptions = new LocatorClickOptions
54+
{
55+
Force = true,
56+
Timeout = options?.Timeout,
57+
};
58+
DefaultClick(null, null, clickOptions);
59+
}
60+
}
61+
62+
Checked?.Invoke(this, new ComponentActionEventArgs(this));
3963
}
4064

4165
/// <summary>
@@ -44,7 +68,32 @@ public virtual void Check(LocatorCheckOptions options = default)
4468
/// <param name="options"></param>
4569
public virtual void Uncheck(LocatorUncheckOptions options = default)
4670
{
47-
DefaultUncheck(Unchecking, Unchecked, options);
71+
var tempOptions = options ?? new LocatorUncheckOptions();
72+
tempOptions.Timeout = 1;
73+
74+
Unchecking?.Invoke(this, new ComponentActionEventArgs(this));
75+
76+
try
77+
{
78+
DefaultUncheck(null, null, tempOptions);
79+
}
80+
catch
81+
{
82+
// Fallback to JsClick, checkbox may be custom element with hidden input
83+
84+
if (IsChecked)
85+
{
86+
var clickOptions = new LocatorClickOptions
87+
{
88+
Force = true,
89+
Timeout = options?.Timeout,
90+
};
91+
DefaultClick(null, null, clickOptions);
92+
}
93+
94+
}
95+
96+
Unchecked?.Invoke(this, new ComponentActionEventArgs(this));
4897
}
4998

5099
public virtual void Hover()

src/Bellatrix.Playwright/components/common/RadioButton.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,27 @@ public virtual void Hover()
4747
/// <param name="options"></param>
4848
public virtual void Click(LocatorCheckOptions options = default)
4949
{
50-
DefaultCheck(Clicking, Clicked, options);
50+
var tempOptions = options ?? new LocatorCheckOptions();
51+
tempOptions.Timeout = 1;
52+
53+
Clicking?.Invoke(this, new ComponentActionEventArgs(this));
54+
55+
try
56+
{
57+
DefaultCheck(null, null, tempOptions);
58+
}
59+
catch
60+
{
61+
// Fallback to JsClick, radio button may be custom element with hidden input
62+
var clickOptions = new LocatorClickOptions
63+
{
64+
Force = true,
65+
Timeout = options?.Timeout,
66+
};
67+
68+
DefaultClick(null, null, clickOptions);
69+
}
70+
71+
Clicked?.Invoke(this, new ComponentActionEventArgs(this));
5172
}
5273
}

src/Bellatrix.Playwright/components/core/Component.DefaultActions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ internal void DefaultClick(EventHandler<ComponentActionEventArgs> clicking, Even
5050
if (options.Force != null && (bool)options.Force) PerformJsClick();
5151
else WrappedElement.Click(options);
5252
}
53-
53+
5454
else WrappedElement.Click();
5555

5656
clicked?.Invoke(this, new ComponentActionEventArgs(this));
@@ -73,7 +73,6 @@ internal void DefaultUncheck(EventHandler<ComponentActionEventArgs> unchecking,
7373

7474
WrappedElement.Uncheck(options);
7575

76-
7776
@unchecked?.Invoke(this, new ComponentActionEventArgs(this));
7877
}
7978

src/Bellatrix.Playwright/components/core/Component.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ public bool IsPresent
321321
{
322322
try
323323
{
324-
return WrappedElement.ElementHandle(new LocatorElementHandleOptions { Timeout = ConfigurationService.GetSection<WebSettings>().TimeoutSettings.InMilliseconds().ElementToExistTimeout }) != null;
324+
return WrappedElement.IsPresent;
325325
}
326326
catch
327327
{

src/Bellatrix.Playwright/components/eventhandlers/RadioButtonEventHandlers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ public override void UnsubscribeToAll()
3333
RadioButton.Hovering -= HoveringEventHandler;
3434
RadioButton.Hovered -= HoveredEventHandler;
3535
}
36-
}
36+
}

src/Bellatrix.Playwright/llm/FindByPrompt.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717
using Bellatrix.LLM;
1818
using Bellatrix.LLM.Plugins;
1919
using Bellatrix.Playwright.LLM.Plugins;
20-
using Bellatrix.Playwright.Locators;
21-
using Microsoft.Identity.Client;
2220
using Microsoft.SemanticKernel;
23-
using Pipelines.Sockets.Unofficial.Arenas;
2421
using System.Text.RegularExpressions;
2522
using System.Threading;
2623

@@ -59,7 +56,7 @@ private FindStrategy TryResolveLocator(string location, IViewSnapshotProvider sn
5956
if (_tryResolveFromPages)
6057
{
6158
var ragLocator = TryResolveFromPageObjectMemory(Value);
62-
if (ragLocator != null && ragLocator.Resolve(WrappedBrowser.CurrentPage).All().Any())
59+
if (ragLocator != null && ragLocator.Resolve(WrappedBrowser.CurrentPage).IsPresent)
6360
{
6461
Logger.LogInformation($"✅ Using RAG-located element '{ragLocator}' For '${Value}'");
6562
return ragLocator;
@@ -71,7 +68,7 @@ private FindStrategy TryResolveLocator(string location, IViewSnapshotProvider sn
7168
var cached = LocatorCacheService.TryGetCached(WrappedBrowser.CurrentPage.Url, Value);
7269

7370
var strategy = new FindXpathStrategy(cached);
74-
if (!string.IsNullOrEmpty(cached) && strategy.Resolve(WrappedBrowser.CurrentPage).All().Any())
71+
if (!string.IsNullOrEmpty(cached) && strategy.Resolve(WrappedBrowser.CurrentPage).IsPresent)
7572
{
7673
Logger.LogInformation("✅ Using cached selector.");
7774
return strategy;
@@ -145,7 +142,7 @@ private FindStrategy ResolveViaPromptFallback(string location, IViewSnapshotProv
145142
var rawSelector = result?.GetValue<string>()?.Trim();
146143

147144
var strategy = new FindXpathStrategy(rawSelector);
148-
if (!string.IsNullOrWhiteSpace(rawSelector) && strategy.Resolve(WrappedBrowser.CurrentPage).All().Any())
145+
if (!string.IsNullOrWhiteSpace(rawSelector) && strategy.Resolve(WrappedBrowser.CurrentPage).IsPresent)
149146
{
150147
LocatorCacheService.Update(location, Value, strategy.Value);
151148
return strategy;

templates/Bellatrix.Playwright.GettingStarted/testFrameworkSettings.Debug.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"waitUntilReadyOnElementFound": "false",
1111
"waitForAngular": "false",
1212
"shouldHighlightElements": "true",
13-
"shouldCaptureHttpTraffic": "true",
13+
"shouldCaptureHttpTraffic": "false",
1414
"pathToSslCertificate": "path",
1515
"shouldCheckForJavaScriptErrors": "false",
1616
"timeoutSettings": {
@@ -238,13 +238,13 @@
238238
}
239239
],
240240
"qdrantMemoryDbEndpoint": "http://localhost:6333",
241-
"localCacheConnectionString": "env_LocalCacheConnectionString",
241+
"localCacheConnectionString": "Host=localhost;Port=5433;Database=LocatorCacheDb;Username=postgres;Password=devpassword",
242242
"localCacheProjectName": "playwright_getting_started",
243243
"shouldIndexPageObjects": false,
244244
"pageObjectFilesPath": "40. Prompts Support\\Pages",
245245
"memoryIndex": "PageObjects",
246246
"resetIndexEverytime": false,
247-
"locatorRetryAttempts": 3,
247+
"locatorRetryAttempts": 5,
248248
"validationsTimeout": 15,
249249
"sleepInterval": 1,
250250
"enableSelfHealing": true,

templates/Bellatrix.Web.GettingStarted/testFrameworkSettings.Debug.json

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,22 @@
1515
"shouldCheckForJavaScriptErrors": "false",
1616
"fullPageScreenshotsEnabled": "true",
1717
"timeoutSettings": {
18-
"elementWaitTimeout": "5",
19-
"pageLoadTimeout": "5",
20-
"scriptTimeout": "1",
21-
"waitForAjaxTimeout": "5",
18+
"elementWaitTimeout": "10",
19+
"pageLoadTimeout": "10",
20+
"scriptTimeout": "5",
21+
"waitForAjaxTimeout": "10",
2222
"sleepInterval": "1",
23-
"waitUntilReadyTimeout": "5",
24-
"waitForJavaScriptAnimationsTimeout": "5",
25-
"waitForAngularTimeout": "5",
26-
"waitForPartialUrl": "5",
27-
"validationsTimeout": "5",
28-
"elementToBeVisibleTimeout": "5",
29-
"elementToExistTimeout": "5",
30-
"elementToNotExistTimeout": "5",
31-
"elementToBeClickableTimeout": "5",
32-
"elementNotToBeVisibleTimeout": "5",
33-
"elementToHaveContentTimeout": "5"
23+
"waitUntilReadyTimeout": "10",
24+
"waitForJavaScriptAnimationsTimeout": "10",
25+
"waitForAngularTimeout": "10",
26+
"waitForPartialUrl": "10",
27+
"validationsTimeout": "10",
28+
"elementToBeVisibleTimeout": "10",
29+
"elementToExistTimeout": "10",
30+
"elementToNotExistTimeout": "10",
31+
"elementToBeClickableTimeout": "10",
32+
"elementNotToBeVisibleTimeout": "10",
33+
"elementToHaveContentTimeout": "10"
3434
},
3535
"executionSettings": {
3636
"executionType": "regular",
@@ -220,7 +220,7 @@
220220
"modelSettings": [
221221
{
222222
"endpoint": "env_AZURE_OPENAI_ENDPOINT",
223-
"key": "env_AZURE_OPENAI_KEY",
223+
"key": "env_AZURE_OPENAI_API_KEY",
224224
"deployment": "gpt-4o"
225225
},
226226
{
@@ -231,7 +231,7 @@
231231
}
232232
],
233233
"qdrantMemoryDbEndpoint": "http://localhost:6333",
234-
"localCacheConnectionString": "env_LocalCacheConnectionString",
234+
"localCacheConnectionString": "Host=localhost;Port=5433;Database=LocatorCacheDb;Username=postgres;Password=devpassword",
235235
"localCacheProjectName": "web_getting_started",
236236
"shouldIndexPageObjects": false,
237237
"pageObjectFilesPath": "40. Prompts Support\\Pages",

0 commit comments

Comments
 (0)