diff --git a/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs b/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs index f732b801a..850833cd2 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs @@ -4,8 +4,8 @@ namespace BotSharp.Abstraction.Browsing; public interface IWebBrowser { - Task LaunchBrowser(string conversationId, string? url); - Task ScreenshotAsync(string conversationId, string path); + Task LaunchBrowser(string contextId, string? url, bool openIfNotExist = true); + Task ScreenshotAsync(string contextId, string path); Task ScrollPageAsync(BrowserActionParams actionParams); Task ActionOnElement(MessageInfo message, ElementLocatingArgs location, ElementActionArgs action); @@ -19,10 +19,11 @@ public interface IWebBrowser Task ChangeListValue(BrowserActionParams actionParams); Task CheckRadioButton(BrowserActionParams actionParams); Task ChangeCheckbox(BrowserActionParams actionParams); - Task GoToPage(string conversationId, string url); + Task GoToPage(string contextId, string url, bool openNewTab = false); Task ExtractData(BrowserActionParams actionParams); - Task EvaluateScript(string conversationId, string script); - Task CloseBrowser(string conversationId); - Task SendHttpRequest(HttpRequestParams actionParams); + Task EvaluateScript(string contextId, string script); + Task CloseBrowser(string contextId); + Task CloseCurrentPage(string contextId); + Task SendHttpRequest(string contextId, HttpRequestParams actionParams); Task GetAttributeValue(MessageInfo message, ElementLocatingArgs location, BrowserActionResult result); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/BrowserActionParams.cs b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/BrowserActionParams.cs index 37c820a2d..04ba82b25 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/BrowserActionParams.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/BrowserActionParams.cs @@ -4,14 +4,14 @@ public class BrowserActionParams { public Agent Agent { get; set; } public BrowsingContextIn Context { get; set; } - public string ConversationId { get; set; } + public string ContextId { get; set; } public string MessageId { get; set; } - public BrowserActionParams(Agent agent, BrowsingContextIn context, string conversationId, string messageId) + public BrowserActionParams(Agent agent, BrowsingContextIn context, string contextId, string messageId) { Agent = agent; Context = context; - ConversationId = conversationId; + ContextId = contextId; MessageId = messageId; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/MessageInfo.cs b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/MessageInfo.cs index dc530e6db..336d255c7 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/MessageInfo.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/MessageInfo.cs @@ -3,6 +3,6 @@ namespace BotSharp.Abstraction.Browsing.Models; public class MessageInfo { public string AgentId { get; set; } - public string ConversationId { get; set; } + public string ContextId { get; set; } public string MessageId { get; set; } } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs index fdbc29cb7..9786ab934 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs @@ -6,6 +6,7 @@ public class PlaywrightInstance : IDisposable { IPlaywright _playwright; Dictionary _contexts = new Dictionary(); + public Dictionary Contexts => _contexts; public IPage GetPage(string id) { @@ -13,24 +14,22 @@ public IPage GetPage(string id) return _contexts[id].Pages.LastOrDefault(); } - public async Task InitInstance(string id) + public async Task InitInstance(string id) { if (_playwright == null) { _playwright = await Playwright.CreateAsync(); } - await InitContext(id); + return await InitContext(id); } - public async Task InitContext(string id) + public async Task InitContext(string id) { if (_contexts.ContainsKey(id)) - return; -#if DEBUG - string tempFolderPath = $"{Path.GetTempPath()}\\playwright"; -#else + return _contexts[id]; + string tempFolderPath = $"{Path.GetTempPath()}\\playwright\\{id}"; -#endif + _contexts[id] = await _playwright.Chromium.LaunchPersistentContextAsync(tempFolderPath, new BrowserTypeLaunchPersistentContextOptions { #if DEBUG @@ -65,6 +64,8 @@ public async Task InitContext(string id) Serilog.Log.Warning($"Playwright browser context is closed"); _contexts.Remove(id); }; + + return _contexts[id]; } public async Task NewPage(string id) @@ -92,6 +93,14 @@ public async Task Close(string id) } } + public async Task CloseCurrentPage(string id) + { + if (_contexts.ContainsKey(id)) + { + await GetPage(id).CloseAsync(); + } + } + public void Dispose() { _contexts.Clear(); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ActionOnElement.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ActionOnElement.cs index f8d4d1d90..67a46f03f 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ActionOnElement.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ActionOnElement.cs @@ -4,7 +4,7 @@ public partial class PlaywrightWebDriver { public async Task ActionOnElement(MessageInfo message, ElementLocatingArgs location, ElementActionArgs action) { - await _instance.Wait(message.ConversationId); + await _instance.Wait(message.ContextId); var result = await LocateElement(message, location); if (result.IsSuccess) { diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeCheckbox.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeCheckbox.cs index 2bac92dd1..d15597bc3 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeCheckbox.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeCheckbox.cs @@ -1,5 +1,3 @@ -using System.Text.RegularExpressions; - namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; public partial class PlaywrightWebDriver @@ -8,7 +6,7 @@ public async Task ChangeCheckbox(BrowserActionParams action { var result = new BrowserActionResult(); - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); // Retrieve the page raw html and infer the element path var regexExpression = actionParams.Context.MatchRule.ToLower() switch @@ -19,7 +17,7 @@ public async Task ChangeCheckbox(BrowserActionParams action _ => $"^{actionParams.Context.ElementText}$" }; var regex = new Regex(regexExpression, RegexOptions.IgnoreCase); - var elements = _instance.GetPage(actionParams.ConversationId).GetByText(regex); + var elements = _instance.GetPage(actionParams.ContextId).GetByText(regex); var count = await elements.CountAsync(); var errorMessage = $"Can't locate element by keyword {actionParams.Context.ElementText}"; @@ -55,7 +53,7 @@ public async Task ChangeCheckbox(BrowserActionParams action } else { - elements = _instance.GetPage(actionParams.ConversationId).Locator($"#{id}"); + elements = _instance.GetPage(actionParams.ContextId).Locator($"#{id}"); } count = await elements.CountAsync(); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeListValue.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeListValue.cs index 119064a9a..f3d58f979 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeListValue.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeListValue.cs @@ -5,10 +5,10 @@ public partial class PlaywrightWebDriver public async Task ChangeListValue(BrowserActionParams actionParams) { var result = new BrowserActionResult(); - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); // Retrieve the page raw html and infer the element path - var body = await _instance.GetPage(actionParams.ConversationId).QuerySelectorAsync("body"); + var body = await _instance.GetPage(actionParams.ContextId).QuerySelectorAsync("body"); var str = new List(); var inputs = await body.QuerySelectorAllAsync("select"); @@ -61,7 +61,7 @@ public async Task ChangeListValue(BrowserActionParams actio string.Join("", str), actionParams.Context.ElementName, actionParams.MessageId); - ILocator element = Locator(actionParams.ConversationId, htmlElementContextOut); + ILocator? element = Locator(actionParams.ContextId, htmlElementContextOut); try { @@ -70,11 +70,11 @@ public async Task ChangeListValue(BrowserActionParams actio if (!isVisible) { // Select the element you want to make visible (replace with your own selector) - var control = await _instance.GetPage(actionParams.ConversationId) + var control = await _instance.GetPage(actionParams.ContextId) .QuerySelectorAsync($"#{htmlElementContextOut.ElementId}"); // Show the element by modifying its CSS styles - await _instance.GetPage(actionParams.ConversationId) + await _instance.GetPage(actionParams.ContextId) .EvaluateAsync(@"(element) => { element.style.display = 'block'; element.style.visibility = 'visible'; @@ -92,11 +92,11 @@ await element.SelectOptionAsync(new SelectOptionValue if (!isVisible) { // Select the element you want to make visible (replace with your own selector) - var control = await _instance.GetPage(actionParams.ConversationId) + var control = await _instance.GetPage(actionParams.ContextId) .QuerySelectorAsync($"#{htmlElementContextOut.ElementId}"); // Show the element by modifying its CSS styles - await _instance.GetPage(actionParams.ConversationId).EvaluateAsync(@"(element) => { + await _instance.GetPage(actionParams.ContextId).EvaluateAsync(@"(element) => { element.style.display = 'none'; element.style.visibility = 'hidden'; }", control); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CheckRadioButton.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CheckRadioButton.cs index 9d28f8c44..9df8d3bc8 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CheckRadioButton.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CheckRadioButton.cs @@ -5,7 +5,7 @@ public partial class PlaywrightWebDriver public async Task CheckRadioButton(BrowserActionParams actionParams) { var result = new BrowserActionResult(); - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); // Retrieve the page raw html and infer the element path var regexExpression = actionParams.Context.MatchRule.ToLower() switch @@ -16,7 +16,7 @@ public async Task CheckRadioButton(BrowserActionParams acti _ => $"^{actionParams.Context.ElementText}$" }; var regex = new Regex(regexExpression, RegexOptions.IgnoreCase); - var elements = _instance.GetPage(actionParams.ConversationId).GetByText(regex); + var elements = _instance.GetPage(actionParams.ContextId).GetByText(regex); var count = await elements.CountAsync(); var errorMessage = $"Can't locate element by keyword {actionParams.Context.ElementText}"; diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ClickButton.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ClickButton.cs index f1678db59..db0aad605 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ClickButton.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ClickButton.cs @@ -5,10 +5,10 @@ public partial class PlaywrightWebDriver public async Task ClickButton(BrowserActionParams actionParams) { var result = new BrowserActionResult(); - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); // Find by text exactly match - var elements = _instance.GetPage(actionParams.ConversationId) + var elements = _instance.GetPage(actionParams.ContextId) .GetByRole(AriaRole.Button, new PageGetByRoleOptions { Name = actionParams.Context.ElementName @@ -17,7 +17,7 @@ public async Task ClickButton(BrowserActionParams actionPar if (count == 0) { - elements = _instance.GetPage(actionParams.ConversationId) + elements = _instance.GetPage(actionParams.ContextId) .GetByRole(AriaRole.Link, new PageGetByRoleOptions { Name = actionParams.Context.ElementName @@ -27,7 +27,7 @@ public async Task ClickButton(BrowserActionParams actionPar if (count == 0) { - elements = _instance.GetPage(actionParams.ConversationId) + elements = _instance.GetPage(actionParams.ContextId) .GetByText(actionParams.Context.ElementName); count = await elements.CountAsync(); } @@ -36,12 +36,12 @@ public async Task ClickButton(BrowserActionParams actionPar { // Infer element if not found var driverService = _services.GetRequiredService(); - var html = await FilteredButtonHtml(actionParams.ConversationId); + var html = await FilteredButtonHtml(actionParams.ContextId); var htmlElementContextOut = await driverService.InferElement(actionParams.Agent, html, actionParams.Context.ElementName, actionParams.MessageId); - elements = Locator(actionParams.ConversationId, htmlElementContextOut); + elements = Locator(actionParams.ContextId, htmlElementContextOut); if (elements == null) { @@ -54,7 +54,7 @@ public async Task ClickButton(BrowserActionParams actionPar try { await elements.ClickAsync(); - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); result.IsSuccess = true; } @@ -67,12 +67,12 @@ public async Task ClickButton(BrowserActionParams actionPar return result; } - private async Task FilteredButtonHtml(string conversationId) + private async Task FilteredButtonHtml(string contextId) { var driverService = _services.GetRequiredService(); // Retrieve the page raw html and infer the element path - var body = await _instance.GetPage(conversationId).QuerySelectorAsync("body"); + var body = await _instance.GetPage(contextId).QuerySelectorAsync("body"); var str = new List(); /*var anchors = await body.QuerySelectorAllAsync("a"); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ClickElement.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ClickElement.cs index 3d12ed2c8..c477f805a 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ClickElement.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ClickElement.cs @@ -5,9 +5,9 @@ public partial class PlaywrightWebDriver public async Task ClickElement(BrowserActionParams actionParams) { var result = new BrowserActionResult(); - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); - var page = _instance.GetPage(actionParams.ConversationId); + var page = _instance.GetPage(actionParams.ContextId); ILocator locator = default; int count = 0; @@ -51,7 +51,7 @@ public async Task ClickElement(BrowserActionParams actionPa await locator.ClickAsync(); // Triggered ajax - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); result.IsSuccess = true; } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CloseBrowser.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CloseBrowser.cs index 8ab948802..1e3240ea1 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CloseBrowser.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CloseBrowser.cs @@ -2,8 +2,8 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; public partial class PlaywrightWebDriver { - public async Task CloseBrowser(string conversationId) + public async Task CloseBrowser(string contextId) { - await _instance.Close(conversationId); + await _instance.Close(contextId); } } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CloseCurrentPage.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CloseCurrentPage.cs new file mode 100644 index 000000000..c5ed1700c --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.CloseCurrentPage.cs @@ -0,0 +1,9 @@ +namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; + +public partial class PlaywrightWebDriver +{ + public async Task CloseCurrentPage(string contextId) + { + await _instance.CloseCurrentPage(contextId); + } +} 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 5e0bcf8b4..93f714d23 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.DoAction.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.DoAction.cs @@ -1,12 +1,10 @@ -using BotSharp.Abstraction.Browsing.Enums; - namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; public partial class PlaywrightWebDriver { public async Task DoAction(MessageInfo message, ElementActionArgs action, BrowserActionResult result) { - var page = _instance.GetPage(message.ConversationId); + var page = _instance.GetPage(message.ContextId); ILocator locator = page.Locator(result.Selector); if (action.Action == BroswerActionEnum.Click) diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.EvaluateScript.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.EvaluateScript.cs index 8a72c311c..a8a7eda40 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.EvaluateScript.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.EvaluateScript.cs @@ -2,10 +2,10 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; public partial class PlaywrightWebDriver { - public async Task EvaluateScript(string conversationId, string script) + public async Task EvaluateScript(string contextId, string script) { - await _instance.Wait(conversationId); + await _instance.Wait(contextId); - return await _instance.GetPage(conversationId).EvaluateAsync(script); + return await _instance.GetPage(contextId).EvaluateAsync(script); } } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ExtractData.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ExtractData.cs index 86fae9e49..b716b7bae 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ExtractData.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ExtractData.cs @@ -4,12 +4,12 @@ public partial class PlaywrightWebDriver { public async Task ExtractData(BrowserActionParams actionParams) { - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); await Task.Delay(3000); // Retrieve the page raw html and infer the element path - var body = await _instance.GetPage(actionParams.ConversationId).QuerySelectorAsync("body"); + var body = await _instance.GetPage(actionParams.ContextId).QuerySelectorAsync("body"); var content = await body.InnerTextAsync(); var driverService = _services.GetRequiredService(); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GetAttributeValue.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GetAttributeValue.cs index 8b87c2c89..cf172d31b 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GetAttributeValue.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GetAttributeValue.cs @@ -4,7 +4,7 @@ public partial class PlaywrightWebDriver { public async Task GetAttributeValue(MessageInfo message, ElementLocatingArgs location, BrowserActionResult result) { - var page = _instance.GetPage(message.ConversationId); + var page = _instance.GetPage(message.ContextId); ILocator locator = page.Locator(result.Selector); var value = string.Empty; diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GoToPage.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GoToPage.cs index e3c9a52d3..5513e89f7 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GoToPage.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GoToPage.cs @@ -2,18 +2,19 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; public partial class PlaywrightWebDriver { - public async Task GoToPage(string conversationId, string url) + public async Task GoToPage(string contextId, string url, bool openNewTab = false) { var result = new BrowserActionResult(); try { - var response = await _instance.GetPage(conversationId).GotoAsync(url); - await _instance.GetPage(conversationId).WaitForLoadStateAsync(LoadState.DOMContentLoaded); - await _instance.GetPage(conversationId).WaitForLoadStateAsync(LoadState.NetworkIdle); + var page = openNewTab ? await _instance.NewPage(contextId) : + _instance.GetPage(contextId); + var response = await page.GotoAsync(url); + await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); if (response.Status == 200) { - var page = _instance.GetPage(conversationId); result.Body = await page.ContentAsync(); result.IsSuccess = true; } 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 6f03ca8d8..a5a593341 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(HttpRequestParams args) + public async Task SendHttpRequest(string contextId, HttpRequestParams args) { var result = new BrowserActionResult(); @@ -25,10 +25,9 @@ public async Task SendHttpRequest(HttpRequestParams args) }})(); "; - var conv = _services.GetRequiredService(); try { - var response = await EvaluateScript(conv.ConversationId, script); + var response = await EvaluateScript(contextId, script); result.IsSuccess = true; result.Body = JsonSerializer.Serialize(response); } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.InputUserPassword.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.InputUserPassword.cs index 3d0f2419a..9f3027012 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.InputUserPassword.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.InputUserPassword.cs @@ -5,10 +5,10 @@ public partial class PlaywrightWebDriver public async Task InputUserPassword(BrowserActionParams actionParams) { var result = new BrowserActionResult(); - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); // Retrieve the page raw html and infer the element path - var body = await _instance.GetPage(actionParams.ConversationId) + var body = await _instance.GetPage(actionParams.ContextId) .QuerySelectorAsync("body"); var inputs = await body.QuerySelectorAllAsync("input"); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.InputUserText.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.InputUserText.cs index 01eb107f7..dded5f9a5 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.InputUserText.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.InputUserText.cs @@ -5,9 +5,9 @@ public partial class PlaywrightWebDriver public async Task InputUserText(BrowserActionParams actionParams) { var result = new BrowserActionResult(); - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); - var page = _instance.GetPage(actionParams.ConversationId); + var page = _instance.GetPage(actionParams.ContextId); ILocator locator = default; int count = 0; @@ -37,12 +37,12 @@ public async Task InputUserText(BrowserActionParams actionP if (count == 0) { var driverService = _services.GetRequiredService(); - var html = await FilteredInputHtml(actionParams.ConversationId); + var html = await FilteredInputHtml(actionParams.ContextId); var htmlElementContextOut = await driverService.InferElement(actionParams.Agent, html, actionParams.Context.ElementText, actionParams.MessageId); - locator = Locator(actionParams.ConversationId, htmlElementContextOut); + locator = Locator(actionParams.ContextId, htmlElementContextOut); count = await locator.CountAsync(); } else if (count > 0) @@ -56,7 +56,7 @@ public async Task InputUserText(BrowserActionParams actionP } // Triggered ajax - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); result.IsSuccess = true; } catch (Exception ex) diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LaunchBrowser.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LaunchBrowser.cs index 323dd89c9..e415df8cf 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LaunchBrowser.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LaunchBrowser.cs @@ -2,17 +2,27 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; public partial class PlaywrightWebDriver { - public async Task LaunchBrowser(string conversationId, string? url) + public async Task LaunchBrowser(string contextId, string? url, bool openIfNotExist = true) { var result = new BrowserActionResult() { IsSuccess = true }; - await _instance.InitInstance(conversationId); + var context = await _instance.InitInstance(contextId); if (!string.IsNullOrEmpty(url)) { - var page = await _instance.NewPage(conversationId); + // Check if the page is already open + foreach (var p in context.Pages) + { + if (p.Url == url) + { + await p.BringToFrontAsync(); + return result; + } + } + + var page = await _instance.NewPage(contextId); if (!string.IsNullOrEmpty(url)) { 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 3edba4bd6..78fa00a3b 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LocateElement.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.LocateElement.cs @@ -11,7 +11,7 @@ public partial class PlaywrightWebDriver public async Task LocateElement(MessageInfo message, ElementLocatingArgs location) { var result = new BrowserActionResult(); - var page = _instance.GetPage(message.ConversationId); + var page = _instance.GetPage(message.ContextId); ILocator locator = page.Locator("body"); int count = 0; diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.Screenshot.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.Screenshot.cs index f0c1fffaa..07fea1458 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.Screenshot.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.Screenshot.cs @@ -2,12 +2,12 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; public partial class PlaywrightWebDriver { - public async Task ScreenshotAsync(string conversationId, string path) + public async Task ScreenshotAsync(string contextId, string path) { var result = new BrowserActionResult(); - await _instance.Wait(conversationId); - var page = _instance.GetPage(conversationId); + await _instance.Wait(contextId); + var page = _instance.GetPage(contextId); await Task.Delay(500); var bytes = await page.ScreenshotAsync(new PageScreenshotOptions diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ScrollPage.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ScrollPage.cs index 2d9cabdfc..5c76c6e74 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ScrollPage.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ScrollPage.cs @@ -5,9 +5,9 @@ public partial class PlaywrightWebDriver public async Task ScrollPageAsync(BrowserActionParams actionParams) { var result = new BrowserActionResult(); - await _instance.Wait(actionParams.ConversationId); + await _instance.Wait(actionParams.ContextId); - var page = _instance.GetPage(actionParams.ConversationId); + var page = _instance.GetPage(actionParams.ContextId); if(actionParams.Context.Direction == "down") await page.EvaluateAsync("window.scrollBy(0, window.innerHeight - 200)"); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs index 779bbb4c4..dab45548b 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs @@ -22,12 +22,12 @@ public void SetAgent(Agent agent) _agent = agent; } - private ILocator? Locator(string conversationId, HtmlElementContextOut context) + private ILocator? Locator(string contextId, HtmlElementContextOut context) { ILocator element = default; if (!string.IsNullOrEmpty(context.ElementId)) { - element = _instance.GetPage(conversationId).Locator($"#{context.ElementId}"); + element = _instance.GetPage(contextId).Locator($"#{context.ElementId}"); } else if (!string.IsNullOrEmpty(context.ElementName)) { @@ -38,7 +38,7 @@ public void SetAgent(Agent agent) "button" => AriaRole.Button, _ => AriaRole.Generic }; - element = _instance.GetPage(conversationId).Locator($"[name='{context.ElementName}']"); + element = _instance.GetPage(contextId).Locator($"[name='{context.ElementName}']"); var count = element.CountAsync().Result; if (count == 0) { @@ -58,7 +58,7 @@ public void SetAgent(Agent agent) _logger.LogError($"Can't locate the web element {context.Index}."); return null; } - element = _instance.GetPage(conversationId).Locator(context.TagName).Nth(context.Index); + element = _instance.GetPage(contextId).Locator(context.TagName).Nth(context.Index); } return element; diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs index 76b9a9265..c16da29cc 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs @@ -21,7 +21,7 @@ public async Task Execute(RoleDialogModel message) var agentService = _services.GetRequiredService(); var agent = await agentService.LoadAgent(message.CurrentAgentId); - var result = await _browser.SendHttpRequest(args); + var result = await _browser.SendHttpRequest(convService.ConversationId, args); message.Content = result.IsSuccess ? result.Body : diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Using.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Using.cs index 3c8c8c948..161e150a9 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Using.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Using.cs @@ -9,6 +9,7 @@ global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; +global using BotSharp.Abstraction.Browsing.Enums; global using BotSharp.Abstraction.Conversations; global using BotSharp.Abstraction.Plugins; global using BotSharp.Abstraction.Conversations.Models;