diff --git a/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs b/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs index 80dd6925..fc907351 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs @@ -24,6 +24,6 @@ public interface IWebBrowser Task EvaluateScript(string contextId, string script); Task CloseBrowser(string contextId); Task CloseCurrentPage(string contextId); - Task SendHttpRequest(string contextId, HttpRequestParams actionParams); + Task SendHttpRequest(MessageInfo message, HttpRequestParams actionParams); Task GetAttributeValue(MessageInfo message, ElementLocatingArgs location); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/ElementActionArgs.cs b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/ElementActionArgs.cs index 8b644b31..0d44066a 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/ElementActionArgs.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/ElementActionArgs.cs @@ -10,6 +10,8 @@ public class ElementActionArgs public ElementPosition? Position { get; set; } + public string? PressKey { get; set; } + /// /// Required for deserialization /// diff --git a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/HttpRequestParams.cs b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/HttpRequestParams.cs index 2b8cc052..e6d24a8e 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/HttpRequestParams.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/HttpRequestParams.cs @@ -18,7 +18,7 @@ public class HttpRequestParams public HttpRequestParams(string url, HttpMethod method, string? payload = null) { - Method = HttpMethod.Get; + Method = method; Url = url; Payload = payload; } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs index a801400b..e7fd5908 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs @@ -40,11 +40,12 @@ public class PlaywrightInstance : IDisposable Channel = "chrome", IgnoreDefaultArgs = new[] { - "--disable-infobars" + "--enable-automation", }, Args = new[] { "--disable-infobars", + "--no-sandbox", // "--start-maximized" } }); @@ -104,6 +105,6 @@ public class PlaywrightInstance : IDisposable public void Dispose() { _contexts.Clear(); - _playwright.Dispose(); + _playwright?.Dispose(); } } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.DoAction.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.DoAction.cs index dd4600c9..91a99aa8 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.DoAction.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.DoAction.cs @@ -28,6 +28,11 @@ public partial class PlaywrightWebDriver else if (action.Action == BroswerActionEnum.InputText) { await locator.FillAsync(action.Content); + + if (action.PressKey != null) + { + await locator.PressAsync(action.PressKey); + } } } } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.HttpRequest.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.HttpRequest.cs index a5a59334..4a0177a0 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.HttpRequest.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.HttpRequest.cs @@ -4,7 +4,7 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; public partial class PlaywrightWebDriver { - public async Task SendHttpRequest(string contextId, HttpRequestParams args) + public async Task SendHttpRequest(MessageInfo message, HttpRequestParams args) { var result = new BrowserActionResult(); @@ -27,7 +27,7 @@ public partial class PlaywrightWebDriver try { - var response = await EvaluateScript(contextId, script); + var response = await EvaluateScript(message.ContextId, script); result.IsSuccess = true; result.Body = JsonSerializer.Serialize(response); } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LocateElement.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LocateElement.cs index 78fa00a3..13b0464c 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LocateElement.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LocateElement.cs @@ -1,3 +1,5 @@ +using System.Xml.Linq; + namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; public partial class PlaywrightWebDriver @@ -18,12 +20,12 @@ public partial class PlaywrightWebDriver // check if selector is specified if (location.Selector != null) { - locator = page.Locator(location.Selector); + locator = locator.Locator(location.Selector); count = await locator.CountAsync(); } // try attribute - if (count == 0 && !string.IsNullOrEmpty(location.AttributeName)) + if (!string.IsNullOrEmpty(location.AttributeName)) { locator = locator.Locator($"[{location.AttributeName}='{location.AttributeValue}']"); count = await locator.CountAsync(); @@ -65,12 +67,29 @@ public partial class PlaywrightWebDriver else if (count == 1) { result.Selector = locator.ToString().Split('@').Last(); + + // Make sure the element is visible + await locator.EvaluateAsync("element => element.style.height = ''"); + await locator.EvaluateAsync("element => element.style.width = ''"); + await locator.EvaluateAsync("element => element.style.opacity = ''"); + var text = await locator.InnerTextAsync(); result.Body = text; result.IsSuccess = true; } else if (count > 1) { + // Make sure the element is visible + foreach (var element in await locator.AllAsync()) + { + if (!await element.IsVisibleAsync()) + { + await element.EvaluateAsync("element => element.style.height = '10px'"); + await element.EvaluateAsync("element => element.style.width = '10px'"); + await element.EvaluateAsync("element => element.style.opacity = '1.0'"); + } + } + if (location.FailIfMultiple) { result.Message = $"Multiple elements are found by {locator}"; diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/SeleniumDriver/SeleniumWebDriver.HttpRequest.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/SeleniumDriver/SeleniumWebDriver.HttpRequest.cs index b88a5d96..c9940318 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/SeleniumDriver/SeleniumWebDriver.HttpRequest.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/SeleniumDriver/SeleniumWebDriver.HttpRequest.cs @@ -4,7 +4,7 @@ namespace BotSharp.Plugin.WebDriver.Drivers.SeleniumDriver; public partial class SeleniumWebDriver { - public async Task SendHttpRequest(string contextId, HttpRequestParams args) + public async Task SendHttpRequest(MessageInfo message, HttpRequestParams args) { var result = new BrowserActionResult(); @@ -27,7 +27,7 @@ public partial class SeleniumWebDriver try { - var response = await EvaluateScript(contextId, script); + var response = await EvaluateScript(message.ContextId, script); result.IsSuccess = true; result.Body = JsonSerializer.Serialize(response); } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs index c16da29c..fff2c240 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs @@ -21,7 +21,12 @@ public class HttpRequestFn : IFunctionCallback var agentService = _services.GetRequiredService(); var agent = await agentService.LoadAgent(message.CurrentAgentId); - var result = await _browser.SendHttpRequest(convService.ConversationId, args); + var result = await _browser.SendHttpRequest(new MessageInfo + { + AgentId = agent.Id, + MessageId = message.MessageId, + ContextId = convService.ConversationId + }, args); message.Content = result.IsSuccess ? result.Body :