CloseCurrentPage
This commit is contained in:
parent
ae4b3f4237
commit
bad93b971b
|
|
@ -5,4 +5,6 @@ public enum BroswerActionEnum
|
|||
Click = 1,
|
||||
InputText = 2,
|
||||
Typing = 3,
|
||||
Hover = 4,
|
||||
Scroll = 5,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ namespace BotSharp.Abstraction.Browsing;
|
|||
|
||||
public interface IWebBrowser
|
||||
{
|
||||
Task<BrowserActionResult> LaunchBrowser(MessageInfo message, string? url);
|
||||
Task<BrowserActionResult> LaunchBrowser(MessageInfo message);
|
||||
Task<BrowserActionResult> ScreenshotAsync(MessageInfo message, string path);
|
||||
Task<BrowserActionResult> ScrollPageAsync(BrowserActionParams actionParams);
|
||||
Task<BrowserActionResult> ScrollPage(MessageInfo message, PageActionArgs args);
|
||||
|
||||
Task<BrowserActionResult> ActionOnElement(MessageInfo message, ElementLocatingArgs location, ElementActionArgs action);
|
||||
Task<BrowserActionResult> LocateElement(MessageInfo message, ElementLocatingArgs location);
|
||||
|
|
@ -19,11 +19,11 @@ public interface IWebBrowser
|
|||
Task<BrowserActionResult> ChangeListValue(BrowserActionParams actionParams);
|
||||
Task<BrowserActionResult> CheckRadioButton(BrowserActionParams actionParams);
|
||||
Task<BrowserActionResult> ChangeCheckbox(BrowserActionParams actionParams);
|
||||
Task<BrowserActionResult> GoToPage(MessageInfo message, string url, bool openNewTab = false);
|
||||
Task<BrowserActionResult> GoToPage(MessageInfo message, PageActionArgs args);
|
||||
Task<string> ExtractData(BrowserActionParams actionParams);
|
||||
Task<T> EvaluateScript<T>(string contextId, string script);
|
||||
Task CloseBrowser(string contextId);
|
||||
Task CloseCurrentPage(string contextId);
|
||||
Task<BrowserActionResult> CloseCurrentPage(MessageInfo message);
|
||||
Task<BrowserActionResult> SendHttpRequest(MessageInfo message, HttpRequestParams actionParams);
|
||||
Task<BrowserActionResult> GetAttributeValue(MessageInfo message, ElementLocatingArgs location);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
using BotSharp.Abstraction.Browsing.Enums;
|
||||
|
||||
namespace BotSharp.Abstraction.Browsing.Models;
|
||||
|
||||
public class PageActionArgs
|
||||
{
|
||||
public BroswerActionEnum Action { get; set; }
|
||||
|
||||
public string? Content { get; set; }
|
||||
public string? Direction { get; set; }
|
||||
|
||||
public string Url { get; set; } = null!;
|
||||
public bool OpenNewTab { get; set; } = false;
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<LangVersion>12.0</LangVersion>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
<GenerateDocumentationFile>$(GenerateDocumentationFile)</GenerateDocumentationFile>
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Playwright" Version="1.44.0" />
|
||||
<PackageReference Include="Selenium.WebDriver" Version="4.21.0" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.61" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -38,16 +38,16 @@ public class PlaywrightInstance : IDisposable
|
|||
Headless = true,
|
||||
#endif
|
||||
Channel = "chrome",
|
||||
IgnoreDefaultArgs = new[]
|
||||
{
|
||||
IgnoreDefaultArgs =
|
||||
[
|
||||
"--enable-automation",
|
||||
},
|
||||
Args = new[]
|
||||
{
|
||||
],
|
||||
Args =
|
||||
[
|
||||
"--disable-infobars",
|
||||
"--no-sandbox",
|
||||
"--test-type"
|
||||
// "--start-maximized"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
_contexts[id].Page += async (sender, e) =>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,14 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
|
|||
|
||||
public partial class PlaywrightWebDriver
|
||||
{
|
||||
public async Task CloseCurrentPage(string contextId)
|
||||
public async Task<BrowserActionResult> CloseCurrentPage(MessageInfo message)
|
||||
{
|
||||
await _instance.CloseCurrentPage(contextId);
|
||||
await _instance.CloseCurrentPage(message.ContextId);
|
||||
var result = new BrowserActionResult
|
||||
{
|
||||
IsSuccess = true
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,5 +42,9 @@ public partial class PlaywrightWebDriver
|
|||
await locator.PressAsync(action.PressKey);
|
||||
}
|
||||
}
|
||||
else if (action.Action == BroswerActionEnum.Hover)
|
||||
{
|
||||
await locator.HoverAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,21 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
|
|||
|
||||
public partial class PlaywrightWebDriver
|
||||
{
|
||||
public async Task<BrowserActionResult> GoToPage(MessageInfo message, string url, bool openNewTab = false)
|
||||
public async Task<BrowserActionResult> GoToPage(MessageInfo message, PageActionArgs args)
|
||||
{
|
||||
var result = new BrowserActionResult();
|
||||
var context = await _instance.InitInstance(message.ContextId);
|
||||
try
|
||||
{
|
||||
// Check if the page is already open
|
||||
if (!openNewTab && context.Pages.Count > 0)
|
||||
if (!args.OpenNewTab && context.Pages.Count > 0)
|
||||
{
|
||||
foreach (var p in context.Pages)
|
||||
{
|
||||
if (p.Url == url)
|
||||
if (p.Url == args.Url)
|
||||
{
|
||||
result.Body = await p.ContentAsync();
|
||||
// Disable this due to performance issue, some page is too large
|
||||
// result.Body = await p.ContentAsync();
|
||||
result.IsSuccess = true;
|
||||
await p.BringToFrontAsync();
|
||||
return result;
|
||||
|
|
@ -23,14 +24,11 @@ public partial class PlaywrightWebDriver
|
|||
}
|
||||
}
|
||||
|
||||
var page = openNewTab ? await _instance.NewPage(message.ContextId) :
|
||||
var page = args.OpenNewTab ? await _instance.NewPage(message.ContextId) :
|
||||
_instance.GetPage(message.ContextId);
|
||||
var response = await page.GotoAsync(url);
|
||||
var response = await page.GotoAsync(args.Url);
|
||||
await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
||||
await page.WaitForLoadStateAsync(LoadState.NetworkIdle, new PageWaitForLoadStateOptions
|
||||
{
|
||||
Timeout = 1000 * 60 * 5
|
||||
});
|
||||
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
|
||||
|
||||
if (response.Status == 200)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,44 +2,13 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
|
|||
|
||||
public partial class PlaywrightWebDriver
|
||||
{
|
||||
public async Task<BrowserActionResult> LaunchBrowser(MessageInfo message, string? url)
|
||||
public async Task<BrowserActionResult> LaunchBrowser(MessageInfo message)
|
||||
{
|
||||
var result = new BrowserActionResult()
|
||||
{
|
||||
IsSuccess = true
|
||||
};
|
||||
var context = await _instance.InitInstance(message.ContextId);
|
||||
|
||||
if (!string.IsNullOrEmpty(url))
|
||||
var result = new BrowserActionResult
|
||||
{
|
||||
// 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(message.ContextId);
|
||||
|
||||
try
|
||||
{
|
||||
var response = await page.GotoAsync(url, new PageGotoOptions
|
||||
{
|
||||
Timeout = 15 * 1000
|
||||
});
|
||||
await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
||||
result.IsSuccess = response.Status == 200;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Message = ex.Message;
|
||||
result.StackTrace = ex.StackTrace;
|
||||
_logger.LogError(ex.Message);
|
||||
}
|
||||
}
|
||||
IsSuccess = context.Pages.Count > 0
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,21 +2,43 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
|
|||
|
||||
public partial class PlaywrightWebDriver
|
||||
{
|
||||
public async Task<BrowserActionResult> ScrollPageAsync(BrowserActionParams actionParams)
|
||||
public async Task<BrowserActionResult> ScrollPage(MessageInfo message, PageActionArgs args)
|
||||
{
|
||||
var result = new BrowserActionResult();
|
||||
await _instance.Wait(actionParams.ContextId);
|
||||
await _instance.Wait(message.ContextId);
|
||||
|
||||
var page = _instance.GetPage(actionParams.ContextId);
|
||||
var page = _instance.GetPage(message.ContextId);
|
||||
|
||||
if(actionParams.Context.Direction == "down")
|
||||
await page.EvaluateAsync("window.scrollBy(0, window.innerHeight - 200)");
|
||||
else if (actionParams.Context.Direction == "up")
|
||||
await page.EvaluateAsync("window.scrollBy(0, -window.innerHeight + 200)");
|
||||
else if (actionParams.Context.Direction == "left")
|
||||
await page.EvaluateAsync("window.scrollBy(-400, 0)");
|
||||
else if (actionParams.Context.Direction == "right")
|
||||
await page.EvaluateAsync("window.scrollBy(400, 0)");
|
||||
if (args.Direction == "down")
|
||||
{
|
||||
// Get the total page height
|
||||
int scrollY = await page.EvaluateAsync<int>("document.body.scrollHeight");
|
||||
|
||||
// Scroll to the bottom
|
||||
await page.Mouse.WheelAsync(0, scrollY);
|
||||
}
|
||||
else if (args.Direction == "up")
|
||||
{
|
||||
// Get the total page height
|
||||
int scrollY = await page.EvaluateAsync<int>("document.body.scrollHeight");
|
||||
|
||||
// Scroll to the bottom
|
||||
await page.Mouse.WheelAsync(0, -scrollY);
|
||||
}
|
||||
else if (args.Direction == "left")
|
||||
{
|
||||
await page.EvaluateAsync(@"
|
||||
var scrollingElement = (document.scrollingElement || document.body);
|
||||
scrollingElement.scrollLeft = 0;
|
||||
");
|
||||
}
|
||||
else if (args.Direction == "right")
|
||||
{
|
||||
await page.EvaluateAsync(@"
|
||||
var scrollingElement = (document.scrollingElement || document.body);
|
||||
scrollingElement.scrollLeft = scrollingElement.scrollWidth;
|
||||
");
|
||||
}
|
||||
|
||||
result.IsSuccess = true;
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@ namespace BotSharp.Plugin.WebDriver.Drivers.SeleniumDriver;
|
|||
|
||||
public partial class SeleniumWebDriver
|
||||
{
|
||||
public async Task<BrowserActionResult> GoToPage(MessageInfo message, string url, bool openNewTab = false)
|
||||
public async Task<BrowserActionResult> GoToPage(MessageInfo message, PageActionArgs args)
|
||||
{
|
||||
var result = new BrowserActionResult();
|
||||
try
|
||||
{
|
||||
var page = openNewTab ? await _instance.NewPage(message.ContextId) :
|
||||
var page = args.OpenNewTab ? await _instance.NewPage(message.ContextId) :
|
||||
_instance.GetPage(message.ContextId);
|
||||
page.GoToUrl(url);
|
||||
page.GoToUrl(args.Url);
|
||||
await _instance.Wait(message.ContextId);
|
||||
|
||||
result.Body = _instance.GetPageContent(message.ContextId);
|
||||
|
|
|
|||
|
|
@ -2,32 +2,13 @@ namespace BotSharp.Plugin.WebDriver.Drivers.SeleniumDriver;
|
|||
|
||||
public partial class SeleniumWebDriver
|
||||
{
|
||||
public async Task<BrowserActionResult> LaunchBrowser(MessageInfo message, string? url)
|
||||
public async Task<BrowserActionResult> LaunchBrowser(MessageInfo message)
|
||||
{
|
||||
var context = await _instance.InitInstance(message.ContextId);
|
||||
var result = new BrowserActionResult()
|
||||
{
|
||||
IsSuccess = true
|
||||
};
|
||||
var context = await _instance.InitInstance(message.ContextId);
|
||||
|
||||
if (!string.IsNullOrEmpty(url))
|
||||
{
|
||||
// Check if the page is already open
|
||||
var page = await _instance.NewPage(message.ContextId);
|
||||
|
||||
try
|
||||
{
|
||||
page.GoToUrl(url);
|
||||
result.IsSuccess = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Message = ex.Message;
|
||||
result.StackTrace = ex.StackTrace;
|
||||
_logger.LogError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public partial class SeleniumWebDriver : IWebBrowser
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task CloseCurrentPage(string contextId)
|
||||
public Task<BrowserActionResult> CloseCurrentPage(MessageInfo message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ public partial class SeleniumWebDriver : IWebBrowser
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<BrowserActionResult> ScrollPageAsync(BrowserActionParams actionParams)
|
||||
public Task<BrowserActionResult> ScrollPage(MessageInfo message, PageActionArgs args)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,10 @@ public class GoToPageFn : IFunctionCallback
|
|||
AgentId = message.CurrentAgentId,
|
||||
ContextId = convService.ConversationId,
|
||||
MessageId = message.MessageId
|
||||
}, url);
|
||||
}, new PageActionArgs
|
||||
{
|
||||
Url = url
|
||||
});
|
||||
message.Content = result.IsSuccess ? $"Page {url} is open." : $"Page {url} open failed. {result.Message}";
|
||||
|
||||
var path = webDriverService.GetScreenshotFilePath(message.MessageId);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using SQLitePCL;
|
||||
|
||||
namespace BotSharp.Plugin.WebDriver.Functions;
|
||||
|
||||
public class OpenBrowserFn : IFunctionCallback
|
||||
|
|
@ -23,12 +25,17 @@ public class OpenBrowserFn : IFunctionCallback
|
|||
var url = webDriverService.ReplaceToken(args.Url);
|
||||
|
||||
url = url.Replace("https://https://", "https://");
|
||||
var result = await _browser.LaunchBrowser(new MessageInfo
|
||||
var msgInfo = new MessageInfo
|
||||
{
|
||||
AgentId = message.CurrentAgentId,
|
||||
ContextId = convService.ConversationId,
|
||||
MessageId = message.MessageId
|
||||
}, url);
|
||||
};
|
||||
var result = await _browser.LaunchBrowser(msgInfo);
|
||||
result = await _browser.GoToPage(msgInfo, new PageActionArgs
|
||||
{
|
||||
Url = url
|
||||
});
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,17 @@ public class ScrollPageFn : IFunctionCallback
|
|||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var agent = await agentService.LoadAgent(message.CurrentAgentId);
|
||||
|
||||
message.Data = await _browser.ScrollPageAsync(new BrowserActionParams(agent, args, convService.ConversationId, message.MessageId));
|
||||
message.Data = await _browser.ScrollPage(new MessageInfo
|
||||
{
|
||||
AgentId = agent.Id,
|
||||
ContextId = convService.ConversationId,
|
||||
MessageId = message.MessageId
|
||||
}, new PageActionArgs
|
||||
{
|
||||
Action = BroswerActionEnum.Scroll,
|
||||
Direction = args.Direction,
|
||||
});
|
||||
|
||||
message.Content = "Scrolled. You can scroll more if needed.";
|
||||
|
||||
var webDriverService = _services.GetRequiredService<WebDriverService>();
|
||||
|
|
|
|||
44
src/Plugins/BotSharp.Plugin.WebDriver/WebPageHelper.cs
Normal file
44
src/Plugins/BotSharp.Plugin.WebDriver/WebPageHelper.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using HtmlAgilityPack;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace BotSharp.Plugin.WebDriver;
|
||||
|
||||
public static class WebPageHelper
|
||||
{
|
||||
public static string RemoveElements(string html, string selector)
|
||||
{
|
||||
var htmlDoc = new HtmlDocument();
|
||||
htmlDoc.LoadHtml(html);
|
||||
|
||||
var nodesToRemove = htmlDoc.DocumentNode.SelectNodes(selector);
|
||||
|
||||
if (nodesToRemove != null)
|
||||
{
|
||||
foreach (var node in nodesToRemove)
|
||||
{
|
||||
node.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
return htmlDoc.DocumentNode.OuterHtml;
|
||||
}
|
||||
|
||||
public static string RemoveAttribute(string html, string attrName)
|
||||
{
|
||||
var htmlDoc = new HtmlDocument();
|
||||
htmlDoc.LoadHtml(html);
|
||||
|
||||
// Select all elements with a style attribute
|
||||
var nodesWithStyle = htmlDoc.DocumentNode.SelectNodes($"//*[@{attrName}]");
|
||||
|
||||
if (nodesWithStyle != null)
|
||||
{
|
||||
foreach (var node in nodesWithStyle)
|
||||
{
|
||||
node.Attributes.Remove(attrName);
|
||||
}
|
||||
}
|
||||
|
||||
return htmlDoc.DocumentNode.OuterHtml;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue