Merge pull request #411 from Qtoss-Alpha/master

Optimize WebDriver with context id.
This commit is contained in:
C. Oceania 2024-04-12 13:56:47 -05:00 committed by GitHub
commit 1992a70cab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 111 additions and 85 deletions

View file

@ -4,8 +4,8 @@ namespace BotSharp.Abstraction.Browsing;
public interface IWebBrowser public interface IWebBrowser
{ {
Task<BrowserActionResult> LaunchBrowser(string conversationId, string? url); Task<BrowserActionResult> LaunchBrowser(string contextId, string? url, bool openIfNotExist = true);
Task<BrowserActionResult> ScreenshotAsync(string conversationId, string path); Task<BrowserActionResult> ScreenshotAsync(string contextId, string path);
Task<BrowserActionResult> ScrollPageAsync(BrowserActionParams actionParams); Task<BrowserActionResult> ScrollPageAsync(BrowserActionParams actionParams);
Task<BrowserActionResult> ActionOnElement(MessageInfo message, ElementLocatingArgs location, ElementActionArgs action); Task<BrowserActionResult> ActionOnElement(MessageInfo message, ElementLocatingArgs location, ElementActionArgs action);
@ -19,10 +19,11 @@ public interface IWebBrowser
Task<BrowserActionResult> ChangeListValue(BrowserActionParams actionParams); Task<BrowserActionResult> ChangeListValue(BrowserActionParams actionParams);
Task<BrowserActionResult> CheckRadioButton(BrowserActionParams actionParams); Task<BrowserActionResult> CheckRadioButton(BrowserActionParams actionParams);
Task<BrowserActionResult> ChangeCheckbox(BrowserActionParams actionParams); Task<BrowserActionResult> ChangeCheckbox(BrowserActionParams actionParams);
Task<BrowserActionResult> GoToPage(string conversationId, string url); Task<BrowserActionResult> GoToPage(string contextId, string url, bool openNewTab = false);
Task<string> ExtractData(BrowserActionParams actionParams); Task<string> ExtractData(BrowserActionParams actionParams);
Task<T> EvaluateScript<T>(string conversationId, string script); Task<T> EvaluateScript<T>(string contextId, string script);
Task CloseBrowser(string conversationId); Task CloseBrowser(string contextId);
Task<BrowserActionResult> SendHttpRequest(HttpRequestParams actionParams); Task CloseCurrentPage(string contextId);
Task<BrowserActionResult> SendHttpRequest(string contextId, HttpRequestParams actionParams);
Task<string> GetAttributeValue(MessageInfo message, ElementLocatingArgs location, BrowserActionResult result); Task<string> GetAttributeValue(MessageInfo message, ElementLocatingArgs location, BrowserActionResult result);
} }

View file

@ -4,14 +4,14 @@ public class BrowserActionParams
{ {
public Agent Agent { get; set; } public Agent Agent { get; set; }
public BrowsingContextIn Context { get; set; } public BrowsingContextIn Context { get; set; }
public string ConversationId { get; set; } public string ContextId { get; set; }
public string MessageId { 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; Agent = agent;
Context = context; Context = context;
ConversationId = conversationId; ContextId = contextId;
MessageId = messageId; MessageId = messageId;
} }
} }

View file

@ -3,6 +3,6 @@ namespace BotSharp.Abstraction.Browsing.Models;
public class MessageInfo public class MessageInfo
{ {
public string AgentId { get; set; } public string AgentId { get; set; }
public string ConversationId { get; set; } public string ContextId { get; set; }
public string MessageId { get; set; } public string MessageId { get; set; }
} }

View file

@ -6,6 +6,7 @@ public class PlaywrightInstance : IDisposable
{ {
IPlaywright _playwright; IPlaywright _playwright;
Dictionary<string, IBrowserContext> _contexts = new Dictionary<string, IBrowserContext>(); Dictionary<string, IBrowserContext> _contexts = new Dictionary<string, IBrowserContext>();
public Dictionary<string, IBrowserContext> Contexts => _contexts;
public IPage GetPage(string id) public IPage GetPage(string id)
{ {
@ -13,24 +14,22 @@ public class PlaywrightInstance : IDisposable
return _contexts[id].Pages.LastOrDefault(); return _contexts[id].Pages.LastOrDefault();
} }
public async Task InitInstance(string id) public async Task<IBrowserContext> InitInstance(string id)
{ {
if (_playwright == null) if (_playwright == null)
{ {
_playwright = await Playwright.CreateAsync(); _playwright = await Playwright.CreateAsync();
} }
await InitContext(id); return await InitContext(id);
} }
public async Task InitContext(string id) public async Task<IBrowserContext> InitContext(string id)
{ {
if (_contexts.ContainsKey(id)) if (_contexts.ContainsKey(id))
return; return _contexts[id];
#if DEBUG
string tempFolderPath = $"{Path.GetTempPath()}\\playwright";
#else
string tempFolderPath = $"{Path.GetTempPath()}\\playwright\\{id}"; string tempFolderPath = $"{Path.GetTempPath()}\\playwright\\{id}";
#endif
_contexts[id] = await _playwright.Chromium.LaunchPersistentContextAsync(tempFolderPath, new BrowserTypeLaunchPersistentContextOptions _contexts[id] = await _playwright.Chromium.LaunchPersistentContextAsync(tempFolderPath, new BrowserTypeLaunchPersistentContextOptions
{ {
#if DEBUG #if DEBUG
@ -65,6 +64,8 @@ public class PlaywrightInstance : IDisposable
Serilog.Log.Warning($"Playwright browser context is closed"); Serilog.Log.Warning($"Playwright browser context is closed");
_contexts.Remove(id); _contexts.Remove(id);
}; };
return _contexts[id];
} }
public async Task<IPage> NewPage(string id) public async Task<IPage> NewPage(string id)
@ -92,6 +93,14 @@ public class PlaywrightInstance : IDisposable
} }
} }
public async Task CloseCurrentPage(string id)
{
if (_contexts.ContainsKey(id))
{
await GetPage(id).CloseAsync();
}
}
public void Dispose() public void Dispose()
{ {
_contexts.Clear(); _contexts.Clear();

View file

@ -4,7 +4,7 @@ public partial class PlaywrightWebDriver
{ {
public async Task<BrowserActionResult> ActionOnElement(MessageInfo message, ElementLocatingArgs location, ElementActionArgs action) public async Task<BrowserActionResult> ActionOnElement(MessageInfo message, ElementLocatingArgs location, ElementActionArgs action)
{ {
await _instance.Wait(message.ConversationId); await _instance.Wait(message.ContextId);
var result = await LocateElement(message, location); var result = await LocateElement(message, location);
if (result.IsSuccess) if (result.IsSuccess)
{ {

View file

@ -1,5 +1,3 @@
using System.Text.RegularExpressions;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver public partial class PlaywrightWebDriver
@ -8,7 +6,7 @@ public partial class PlaywrightWebDriver
{ {
var result = new BrowserActionResult(); var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId); await _instance.Wait(actionParams.ContextId);
// Retrieve the page raw html and infer the element path // Retrieve the page raw html and infer the element path
var regexExpression = actionParams.Context.MatchRule.ToLower() switch var regexExpression = actionParams.Context.MatchRule.ToLower() switch
@ -19,7 +17,7 @@ public partial class PlaywrightWebDriver
_ => $"^{actionParams.Context.ElementText}$" _ => $"^{actionParams.Context.ElementText}$"
}; };
var regex = new Regex(regexExpression, RegexOptions.IgnoreCase); 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 count = await elements.CountAsync();
var errorMessage = $"Can't locate element by keyword {actionParams.Context.ElementText}"; var errorMessage = $"Can't locate element by keyword {actionParams.Context.ElementText}";
@ -55,7 +53,7 @@ public partial class PlaywrightWebDriver
} }
else else
{ {
elements = _instance.GetPage(actionParams.ConversationId).Locator($"#{id}"); elements = _instance.GetPage(actionParams.ContextId).Locator($"#{id}");
} }
count = await elements.CountAsync(); count = await elements.CountAsync();

View file

@ -5,10 +5,10 @@ public partial class PlaywrightWebDriver
public async Task<BrowserActionResult> ChangeListValue(BrowserActionParams actionParams) public async Task<BrowserActionResult> ChangeListValue(BrowserActionParams actionParams)
{ {
var result = new BrowserActionResult(); var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId); await _instance.Wait(actionParams.ContextId);
// Retrieve the page raw html and infer the element path // 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<string>(); var str = new List<string>();
var inputs = await body.QuerySelectorAllAsync("select"); var inputs = await body.QuerySelectorAllAsync("select");
@ -61,7 +61,7 @@ public partial class PlaywrightWebDriver
string.Join("", str), string.Join("", str),
actionParams.Context.ElementName, actionParams.Context.ElementName,
actionParams.MessageId); actionParams.MessageId);
ILocator element = Locator(actionParams.ConversationId, htmlElementContextOut); ILocator? element = Locator(actionParams.ContextId, htmlElementContextOut);
try try
{ {
@ -70,11 +70,11 @@ public partial class PlaywrightWebDriver
if (!isVisible) if (!isVisible)
{ {
// Select the element you want to make visible (replace with your own selector) // 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}"); .QuerySelectorAsync($"#{htmlElementContextOut.ElementId}");
// Show the element by modifying its CSS styles // Show the element by modifying its CSS styles
await _instance.GetPage(actionParams.ConversationId) await _instance.GetPage(actionParams.ContextId)
.EvaluateAsync(@"(element) => { .EvaluateAsync(@"(element) => {
element.style.display = 'block'; element.style.display = 'block';
element.style.visibility = 'visible'; element.style.visibility = 'visible';
@ -92,11 +92,11 @@ public partial class PlaywrightWebDriver
if (!isVisible) if (!isVisible)
{ {
// Select the element you want to make visible (replace with your own selector) // 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}"); .QuerySelectorAsync($"#{htmlElementContextOut.ElementId}");
// Show the element by modifying its CSS styles // 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.display = 'none';
element.style.visibility = 'hidden'; element.style.visibility = 'hidden';
}", control); }", control);

View file

@ -5,7 +5,7 @@ public partial class PlaywrightWebDriver
public async Task<BrowserActionResult> CheckRadioButton(BrowserActionParams actionParams) public async Task<BrowserActionResult> CheckRadioButton(BrowserActionParams actionParams)
{ {
var result = new BrowserActionResult(); var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId); await _instance.Wait(actionParams.ContextId);
// Retrieve the page raw html and infer the element path // Retrieve the page raw html and infer the element path
var regexExpression = actionParams.Context.MatchRule.ToLower() switch var regexExpression = actionParams.Context.MatchRule.ToLower() switch
@ -16,7 +16,7 @@ public partial class PlaywrightWebDriver
_ => $"^{actionParams.Context.ElementText}$" _ => $"^{actionParams.Context.ElementText}$"
}; };
var regex = new Regex(regexExpression, RegexOptions.IgnoreCase); 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 count = await elements.CountAsync();
var errorMessage = $"Can't locate element by keyword {actionParams.Context.ElementText}"; var errorMessage = $"Can't locate element by keyword {actionParams.Context.ElementText}";

View file

@ -5,10 +5,10 @@ public partial class PlaywrightWebDriver
public async Task<BrowserActionResult> ClickButton(BrowserActionParams actionParams) public async Task<BrowserActionResult> ClickButton(BrowserActionParams actionParams)
{ {
var result = new BrowserActionResult(); var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId); await _instance.Wait(actionParams.ContextId);
// Find by text exactly match // Find by text exactly match
var elements = _instance.GetPage(actionParams.ConversationId) var elements = _instance.GetPage(actionParams.ContextId)
.GetByRole(AriaRole.Button, new PageGetByRoleOptions .GetByRole(AriaRole.Button, new PageGetByRoleOptions
{ {
Name = actionParams.Context.ElementName Name = actionParams.Context.ElementName
@ -17,7 +17,7 @@ public partial class PlaywrightWebDriver
if (count == 0) if (count == 0)
{ {
elements = _instance.GetPage(actionParams.ConversationId) elements = _instance.GetPage(actionParams.ContextId)
.GetByRole(AriaRole.Link, new PageGetByRoleOptions .GetByRole(AriaRole.Link, new PageGetByRoleOptions
{ {
Name = actionParams.Context.ElementName Name = actionParams.Context.ElementName
@ -27,7 +27,7 @@ public partial class PlaywrightWebDriver
if (count == 0) if (count == 0)
{ {
elements = _instance.GetPage(actionParams.ConversationId) elements = _instance.GetPage(actionParams.ContextId)
.GetByText(actionParams.Context.ElementName); .GetByText(actionParams.Context.ElementName);
count = await elements.CountAsync(); count = await elements.CountAsync();
} }
@ -36,12 +36,12 @@ public partial class PlaywrightWebDriver
{ {
// Infer element if not found // Infer element if not found
var driverService = _services.GetRequiredService<WebDriverService>(); var driverService = _services.GetRequiredService<WebDriverService>();
var html = await FilteredButtonHtml(actionParams.ConversationId); var html = await FilteredButtonHtml(actionParams.ContextId);
var htmlElementContextOut = await driverService.InferElement(actionParams.Agent, var htmlElementContextOut = await driverService.InferElement(actionParams.Agent,
html, html,
actionParams.Context.ElementName, actionParams.Context.ElementName,
actionParams.MessageId); actionParams.MessageId);
elements = Locator(actionParams.ConversationId, htmlElementContextOut); elements = Locator(actionParams.ContextId, htmlElementContextOut);
if (elements == null) if (elements == null)
{ {
@ -54,7 +54,7 @@ public partial class PlaywrightWebDriver
try try
{ {
await elements.ClickAsync(); await elements.ClickAsync();
await _instance.Wait(actionParams.ConversationId); await _instance.Wait(actionParams.ContextId);
result.IsSuccess = true; result.IsSuccess = true;
} }
@ -67,12 +67,12 @@ public partial class PlaywrightWebDriver
return result; return result;
} }
private async Task<string> FilteredButtonHtml(string conversationId) private async Task<string> FilteredButtonHtml(string contextId)
{ {
var driverService = _services.GetRequiredService<WebDriverService>(); var driverService = _services.GetRequiredService<WebDriverService>();
// Retrieve the page raw html and infer the element path // 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<string>(); var str = new List<string>();
/*var anchors = await body.QuerySelectorAllAsync("a"); /*var anchors = await body.QuerySelectorAllAsync("a");

View file

@ -5,9 +5,9 @@ public partial class PlaywrightWebDriver
public async Task<BrowserActionResult> ClickElement(BrowserActionParams actionParams) public async Task<BrowserActionResult> ClickElement(BrowserActionParams actionParams)
{ {
var result = new BrowserActionResult(); 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; ILocator locator = default;
int count = 0; int count = 0;
@ -51,7 +51,7 @@ public partial class PlaywrightWebDriver
await locator.ClickAsync(); await locator.ClickAsync();
// Triggered ajax // Triggered ajax
await _instance.Wait(actionParams.ConversationId); await _instance.Wait(actionParams.ContextId);
result.IsSuccess = true; result.IsSuccess = true;
} }

View file

@ -2,8 +2,8 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver public partial class PlaywrightWebDriver
{ {
public async Task CloseBrowser(string conversationId) public async Task CloseBrowser(string contextId)
{ {
await _instance.Close(conversationId); await _instance.Close(contextId);
} }
} }

View file

@ -0,0 +1,9 @@
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task CloseCurrentPage(string contextId)
{
await _instance.CloseCurrentPage(contextId);
}
}

View file

@ -1,12 +1,10 @@
using BotSharp.Abstraction.Browsing.Enums;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver; namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver public partial class PlaywrightWebDriver
{ {
public async Task DoAction(MessageInfo message, ElementActionArgs action, BrowserActionResult result) 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); ILocator locator = page.Locator(result.Selector);
if (action.Action == BroswerActionEnum.Click) if (action.Action == BroswerActionEnum.Click)

View file

@ -2,10 +2,10 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver public partial class PlaywrightWebDriver
{ {
public async Task<T> EvaluateScript<T>(string conversationId, string script) public async Task<T> EvaluateScript<T>(string contextId, string script)
{ {
await _instance.Wait(conversationId); await _instance.Wait(contextId);
return await _instance.GetPage(conversationId).EvaluateAsync<T>(script); return await _instance.GetPage(contextId).EvaluateAsync<T>(script);
} }
} }

View file

@ -4,12 +4,12 @@ public partial class PlaywrightWebDriver
{ {
public async Task<string> ExtractData(BrowserActionParams actionParams) public async Task<string> ExtractData(BrowserActionParams actionParams)
{ {
await _instance.Wait(actionParams.ConversationId); await _instance.Wait(actionParams.ContextId);
await Task.Delay(3000); await Task.Delay(3000);
// Retrieve the page raw html and infer the element path // 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 content = await body.InnerTextAsync();
var driverService = _services.GetRequiredService<WebDriverService>(); var driverService = _services.GetRequiredService<WebDriverService>();

View file

@ -4,7 +4,7 @@ public partial class PlaywrightWebDriver
{ {
public async Task<string> GetAttributeValue(MessageInfo message, ElementLocatingArgs location, BrowserActionResult result) public async Task<string> 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); ILocator locator = page.Locator(result.Selector);
var value = string.Empty; var value = string.Empty;

View file

@ -2,18 +2,19 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver public partial class PlaywrightWebDriver
{ {
public async Task<BrowserActionResult> GoToPage(string conversationId, string url) public async Task<BrowserActionResult> GoToPage(string contextId, string url, bool openNewTab = false)
{ {
var result = new BrowserActionResult(); var result = new BrowserActionResult();
try try
{ {
var response = await _instance.GetPage(conversationId).GotoAsync(url); var page = openNewTab ? await _instance.NewPage(contextId) :
await _instance.GetPage(conversationId).WaitForLoadStateAsync(LoadState.DOMContentLoaded); _instance.GetPage(contextId);
await _instance.GetPage(conversationId).WaitForLoadStateAsync(LoadState.NetworkIdle); var response = await page.GotoAsync(url);
await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
if (response.Status == 200) if (response.Status == 200)
{ {
var page = _instance.GetPage(conversationId);
result.Body = await page.ContentAsync(); result.Body = await page.ContentAsync();
result.IsSuccess = true; result.IsSuccess = true;
} }

View file

@ -4,7 +4,7 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver public partial class PlaywrightWebDriver
{ {
public async Task<BrowserActionResult> SendHttpRequest(HttpRequestParams args) public async Task<BrowserActionResult> SendHttpRequest(string contextId, HttpRequestParams args)
{ {
var result = new BrowserActionResult(); var result = new BrowserActionResult();
@ -25,10 +25,9 @@ public partial class PlaywrightWebDriver
}})(); }})();
"; ";
var conv = _services.GetRequiredService<IConversationService>();
try try
{ {
var response = await EvaluateScript<object>(conv.ConversationId, script); var response = await EvaluateScript<object>(contextId, script);
result.IsSuccess = true; result.IsSuccess = true;
result.Body = JsonSerializer.Serialize(response); result.Body = JsonSerializer.Serialize(response);
} }

View file

@ -5,10 +5,10 @@ public partial class PlaywrightWebDriver
public async Task<BrowserActionResult> InputUserPassword(BrowserActionParams actionParams) public async Task<BrowserActionResult> InputUserPassword(BrowserActionParams actionParams)
{ {
var result = new BrowserActionResult(); var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId); await _instance.Wait(actionParams.ContextId);
// Retrieve the page raw html and infer the element path // 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"); .QuerySelectorAsync("body");
var inputs = await body.QuerySelectorAllAsync("input"); var inputs = await body.QuerySelectorAllAsync("input");

View file

@ -5,9 +5,9 @@ public partial class PlaywrightWebDriver
public async Task<BrowserActionResult> InputUserText(BrowserActionParams actionParams) public async Task<BrowserActionResult> InputUserText(BrowserActionParams actionParams)
{ {
var result = new BrowserActionResult(); 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; ILocator locator = default;
int count = 0; int count = 0;
@ -37,12 +37,12 @@ public partial class PlaywrightWebDriver
if (count == 0) if (count == 0)
{ {
var driverService = _services.GetRequiredService<WebDriverService>(); var driverService = _services.GetRequiredService<WebDriverService>();
var html = await FilteredInputHtml(actionParams.ConversationId); var html = await FilteredInputHtml(actionParams.ContextId);
var htmlElementContextOut = await driverService.InferElement(actionParams.Agent, var htmlElementContextOut = await driverService.InferElement(actionParams.Agent,
html, html,
actionParams.Context.ElementText, actionParams.Context.ElementText,
actionParams.MessageId); actionParams.MessageId);
locator = Locator(actionParams.ConversationId, htmlElementContextOut); locator = Locator(actionParams.ContextId, htmlElementContextOut);
count = await locator.CountAsync(); count = await locator.CountAsync();
} }
else if (count > 0) else if (count > 0)
@ -56,7 +56,7 @@ public partial class PlaywrightWebDriver
} }
// Triggered ajax // Triggered ajax
await _instance.Wait(actionParams.ConversationId); await _instance.Wait(actionParams.ContextId);
result.IsSuccess = true; result.IsSuccess = true;
} }
catch (Exception ex) catch (Exception ex)

View file

@ -2,17 +2,27 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver public partial class PlaywrightWebDriver
{ {
public async Task<BrowserActionResult> LaunchBrowser(string conversationId, string? url) public async Task<BrowserActionResult> LaunchBrowser(string contextId, string? url, bool openIfNotExist = true)
{ {
var result = new BrowserActionResult() var result = new BrowserActionResult()
{ {
IsSuccess = true IsSuccess = true
}; };
await _instance.InitInstance(conversationId); var context = await _instance.InitInstance(contextId);
if (!string.IsNullOrEmpty(url)) 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)) if (!string.IsNullOrEmpty(url))
{ {

View file

@ -11,7 +11,7 @@ public partial class PlaywrightWebDriver
public async Task<BrowserActionResult> LocateElement(MessageInfo message, ElementLocatingArgs location) public async Task<BrowserActionResult> LocateElement(MessageInfo message, ElementLocatingArgs location)
{ {
var result = new BrowserActionResult(); var result = new BrowserActionResult();
var page = _instance.GetPage(message.ConversationId); var page = _instance.GetPage(message.ContextId);
ILocator locator = page.Locator("body"); ILocator locator = page.Locator("body");
int count = 0; int count = 0;

View file

@ -2,12 +2,12 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver public partial class PlaywrightWebDriver
{ {
public async Task<BrowserActionResult> ScreenshotAsync(string conversationId, string path) public async Task<BrowserActionResult> ScreenshotAsync(string contextId, string path)
{ {
var result = new BrowserActionResult(); var result = new BrowserActionResult();
await _instance.Wait(conversationId); await _instance.Wait(contextId);
var page = _instance.GetPage(conversationId); var page = _instance.GetPage(contextId);
await Task.Delay(500); await Task.Delay(500);
var bytes = await page.ScreenshotAsync(new PageScreenshotOptions var bytes = await page.ScreenshotAsync(new PageScreenshotOptions

View file

@ -5,9 +5,9 @@ public partial class PlaywrightWebDriver
public async Task<BrowserActionResult> ScrollPageAsync(BrowserActionParams actionParams) public async Task<BrowserActionResult> ScrollPageAsync(BrowserActionParams actionParams)
{ {
var result = new BrowserActionResult(); 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") if(actionParams.Context.Direction == "down")
await page.EvaluateAsync("window.scrollBy(0, window.innerHeight - 200)"); await page.EvaluateAsync("window.scrollBy(0, window.innerHeight - 200)");

View file

@ -22,12 +22,12 @@ public partial class PlaywrightWebDriver : IWebBrowser
_agent = agent; _agent = agent;
} }
private ILocator? Locator(string conversationId, HtmlElementContextOut context) private ILocator? Locator(string contextId, HtmlElementContextOut context)
{ {
ILocator element = default; ILocator element = default;
if (!string.IsNullOrEmpty(context.ElementId)) 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)) else if (!string.IsNullOrEmpty(context.ElementName))
{ {
@ -38,7 +38,7 @@ public partial class PlaywrightWebDriver : IWebBrowser
"button" => AriaRole.Button, "button" => AriaRole.Button,
_ => AriaRole.Generic _ => AriaRole.Generic
}; };
element = _instance.GetPage(conversationId).Locator($"[name='{context.ElementName}']"); element = _instance.GetPage(contextId).Locator($"[name='{context.ElementName}']");
var count = element.CountAsync().Result; var count = element.CountAsync().Result;
if (count == 0) if (count == 0)
{ {
@ -58,7 +58,7 @@ public partial class PlaywrightWebDriver : IWebBrowser
_logger.LogError($"Can't locate the web element {context.Index}."); _logger.LogError($"Can't locate the web element {context.Index}.");
return null; return null;
} }
element = _instance.GetPage(conversationId).Locator(context.TagName).Nth(context.Index); element = _instance.GetPage(contextId).Locator(context.TagName).Nth(context.Index);
} }
return element; return element;

View file

@ -21,7 +21,7 @@ public class HttpRequestFn : IFunctionCallback
var agentService = _services.GetRequiredService<IAgentService>(); var agentService = _services.GetRequiredService<IAgentService>();
var agent = await agentService.LoadAgent(message.CurrentAgentId); 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 ? message.Content = result.IsSuccess ?
result.Body : result.Body :

View file

@ -9,6 +9,7 @@ global using Microsoft.Playwright;
global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Logging;
global using BotSharp.Abstraction.Browsing.Enums;
global using BotSharp.Abstraction.Conversations; global using BotSharp.Abstraction.Conversations;
global using BotSharp.Abstraction.Plugins; global using BotSharp.Abstraction.Plugins;
global using BotSharp.Abstraction.Conversations.Models; global using BotSharp.Abstraction.Conversations.Models;