Skip to content

Commit 8b61c88

Browse files
committed
some progress
1 parent f7cfaac commit 8b61c88

File tree

7 files changed

+123
-32
lines changed

7 files changed

+123
-32
lines changed

lib/PuppeteerSharp/Bidi/BidiBrowser.cs

Lines changed: 95 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@
2121
// * SOFTWARE.
2222

2323
using System;
24-
using System.Diagnostics;
24+
using System.Diagnostics.CodeAnalysis;
2525
using System.Threading.Tasks;
2626
using Microsoft.Extensions.Logging;
2727
using PuppeteerSharp.Bidi.Core;
28-
using PuppeteerSharp.Transport;
2928
using WebDriverBiDi;
3029
using WebDriverBiDi.Session;
3130

@@ -36,9 +35,37 @@ namespace PuppeteerSharp.Bidi;
3635
/// </summary>
3736
public class BidiBrowser : Browser
3837
{
38+
private readonly LaunchOptions _options;
39+
40+
private BidiBrowser(Core.Browser browserCore, LaunchOptions options)
41+
{
42+
_options = options;
43+
BrowserCore = browserCore;
44+
}
45+
3946
/// <inheritdoc />
4047
public override bool IsClosed { get; }
4148

49+
internal Core.Browser BrowserCore { get; }
50+
51+
internal static string[] SubscribeModules { get; } = [
52+
"browsingContext",
53+
"network",
54+
"log",
55+
"script",
56+
];
57+
58+
internal static string[] SubscribeCdpEvents { get; } =
59+
[
60+
"cdp.Debugger.scriptParsed",
61+
"cdp.CSS.styleSheetAdded",
62+
"cdp.Runtime.executionContextsCleared",
63+
"cdp.Tracing.tracingComplete",
64+
"cdp.Network.requestWillBeSent",
65+
"cdp.Debugger.scriptParsed",
66+
"cdp.Page.screencastFrame",
67+
];
68+
4269
internal override ProtocolType Protocol => ProtocolType.WebdriverBiDi;
4370

4471
/// <inheritdoc />
@@ -47,32 +74,89 @@ public class BidiBrowser : Browser
4774
/// <inheritdoc />
4875
public override Task<string> GetUserAgentAsync() => throw new NotImplementedException();
4976

77+
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "We return the session, the browser needs to dispose the session")]
5078
internal static async Task<BidiBrowser> CreateAsync(
5179
BiDiDriver driver,
5280
LaunchOptions options,
5381
ILoggerFactory loggerFactory)
5482
{
55-
var session = await Session.FromAsync(driver,
83+
var session = await Session.FromAsync(
84+
driver,
5685
new NewCommandParameters
5786
{
5887
AlwaysMatch = new CapabilitiesRequest()
5988
{
60-
AcceptInsecureCertificates = options.IgnoreHTTPSErrors, WebSocketUrl = true,
61-
}
89+
AcceptInsecureCertificates = options.IgnoreHTTPSErrors,
90+
AdditionalCapabilities =
91+
{
92+
["webSocketUrl"] = true,
93+
},
94+
},
6295
},
6396
loggerFactory).ConfigureAwait(false);
6497

6598
await session.SubscribeAsync(
66-
session.capabilities.browserName.toLocaleLowerCase().includes('firefox')
67-
? BidiBrowser.subscribeModules
68-
: [...BidiBrowser.subscribeModules, ...BidiBrowser.subscribeCdpEvents]
69-
);
99+
session.Info.Capabilities.BrowserName.ToLowerInvariant().Contains("firefox")
100+
? SubscribeModules
101+
: [.. SubscribeModules, .. SubscribeCdpEvents]).ConfigureAwait(false);
70102

71-
const browser = new BidiBrowser(session.browser, opts);
72-
browser.#initialize();
103+
var browser = new BidiBrowser(session.Browser, options);
104+
browser.InitializeAsync();
73105
return browser;
74106
}
75107

108+
private void InitializeAsync()
109+
{
110+
// Initializing existing contexts.
111+
foreach (var userContext in BrowserCore.UserContexts)
112+
{
113+
CreateBrowserContext(userContext);
114+
}
115+
116+
this.#browserCore.once('disconnected', () => {
117+
this.#trustedEmitter.emit(BrowserEvent.Disconnected, undefined);
118+
this.#trustedEmitter.removeAllListeners();
119+
});
120+
this.#process?.once('close', () => {
121+
this.#browserCore.dispose('Browser process exited.', true);
122+
this.connection.dispose();
123+
});
124+
}
125+
126+
private BidiBrowserContext CreateBrowserContext(UserContext userContext)
127+
{
128+
const browserContext = BidiBrowserContext.From(
129+
this,
130+
userContext,
131+
new LaunchOptions()
132+
{
133+
DefaultViewport: _options.DefaultViewport,
134+
});
135+
136+
this.#browserContexts.set(userContext, browserContext);
137+
138+
browserContext.trustedEmitter.on(
139+
BrowserContextEvent.TargetCreated,
140+
target => {
141+
this.#trustedEmitter.emit(BrowserEvent.TargetCreated, target);
142+
}
143+
);
144+
browserContext.trustedEmitter.on(
145+
BrowserContextEvent.TargetChanged,
146+
target => {
147+
this.#trustedEmitter.emit(BrowserEvent.TargetChanged, target);
148+
}
149+
);
150+
browserContext.trustedEmitter.on(
151+
BrowserContextEvent.TargetDestroyed,
152+
target => {
153+
this.#trustedEmitter.emit(BrowserEvent.TargetDestroyed, target);
154+
}
155+
);
156+
157+
return browserContext;
158+
}
159+
76160
/// <inheritdoc />
77161
public override void Disconnect() => throw new NotImplementedException();
78162

lib/PuppeteerSharp/Bidi/Core/Browser.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222

2323
using System;
2424
using System.Collections.Concurrent;
25+
using System.Collections.Generic;
2526
using System.Threading.Tasks;
2627
using PuppeteerSharp.Cdp;
27-
using PuppeteerSharp.States;
2828
using WebDriverBiDi.Protocol;
2929
using WebDriverBiDi.Script;
3030

@@ -33,7 +33,7 @@ namespace PuppeteerSharp.Bidi.Core;
3333
internal class Browser(Session session) : IDisposable
3434
{
3535
private bool _disposed;
36-
36+
private readonly ConcurrentDictionary<string, UserContext> _userContexts = new();
3737
private readonly ConcurrentDictionary<string, CdpWebWorker> _workers = new();
3838

3939
public Session Session { get; } = session;
@@ -42,6 +42,8 @@ internal class Browser(Session session) : IDisposable
4242

4343
public string Reason { get; set; }
4444

45+
internal ICollection<UserContext> UserContexts => _userContexts.Values;
46+
4547
public async Task<Browser> From(Session session)
4648
{
4749
var browser = new Browser(session);
@@ -94,7 +96,7 @@ private void OnEventReceived(object sender, EventReceivedEventArgs e)
9496
}
9597
}
9698

97-
private void OnSessionEnded(object sender, SessionEndedArgs e)
99+
private void OnSessionEnded(object sender, SessionEndArgs e)
98100
{
99101
Dispose(e.Reason);
100102
}

lib/PuppeteerSharp/Bidi/Core/Session.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,41 +21,45 @@
2121
// * SOFTWARE.
2222

2323
using System;
24+
using System.Collections.Generic;
2425
using System.Threading.Tasks;
2526
using Microsoft.Extensions.Logging;
2627
using WebDriverBiDi;
2728
using WebDriverBiDi.Session;
2829

2930
namespace PuppeteerSharp.Bidi.Core;
3031

31-
internal class Session(BiDiDriver driver, NewCommandResult newCommandResult) : IDisposable
32+
internal class Session(BiDiDriver driver, NewCommandResult info) : IDisposable
3233
{
33-
public event EventHandler<SessionEndedArgs> Ended;
34+
public event EventHandler<SessionEndArgs> Ended;
3435

3536
public BiDiDriver Driver { get; } = driver;
3637

37-
public NewCommandResult NewCommandResult { get; } = newCommandResult;
38+
public NewCommandResult Info { get; } = info;
3839

3940
public Browser Browser { get; private set; }
4041

41-
public void Dispose()
42-
{
43-
}
44-
45-
internal static async Task<Session> FromAsync(BiDiDriver driver, NewCommandParameters capabilities, ILoggerFactory loggerFactory)
42+
public static async Task<Session> FromAsync(BiDiDriver driver, NewCommandParameters capabilities, ILoggerFactory loggerFactory)
4643
{
4744
var result = await driver.Session.NewSessionAsync(capabilities).ConfigureAwait(false);
4845
var session = new Session(driver, result);
4946
await session.InitializeAsync().ConfigureAwait(false);
5047
return session;
5148
}
5249

50+
public void Dispose()
51+
{
52+
}
53+
54+
public Task SubscribeAsync(string[] events, string[] contexts = null)
55+
=> Driver.Session.SubscribeAsync(new SubscribeCommandParameters(events, contexts ?? []);
56+
5357
private async Task InitializeAsync()
5458
{
5559
Browser = await Browser.From(this).ConfigureAwait(false);
5660

57-
const browserEmitter = this.#disposables.use(this.browser);
58-
browserEmitter.once('closed', ({reason}) => {
61+
Browser.Closed += () => Dispose()
62+
Browser.once('closed', ({reason}) => {
5963
this.dispose(reason);
6064
});
6165

lib/PuppeteerSharp/Bidi/Core/SessionEndedArgs.cs renamed to lib/PuppeteerSharp/Bidi/Core/SessionEndArgs.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
namespace PuppeteerSharp.Bidi.Core;
2424

25-
internal record SessionEndedArgs
25+
internal record SessionEndArgs
2626
{
2727
public string Reason { get; set; }
2828
}

lib/PuppeteerSharp/Browser.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.Linq;
5-
using System.Net.Sockets;
65
using System.Threading.Tasks;
76
using PuppeteerSharp.Cdp;
87
using PuppeteerSharp.Helpers;

lib/PuppeteerSharp/Launcher.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23
using System.Globalization;
34
using System.IO;
45
using System.Net.Http;
@@ -43,6 +44,7 @@ public class Launcher
4344
/// for a description of the differences between Chromium and Chrome.
4445
/// <a href="https://chromium.googlesource.com/chromium/src/+/lkcr/docs/chromium_browser_vs_google_chrome.md">This article</a> describes some differences for Linux users.
4546
/// </remarks>
47+
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The caller is responsible for disposing the returned object.")]
4648
public async Task<IBrowser> LaunchAsync(LaunchOptions options)
4749
{
4850
if (options == null)

lib/PuppeteerSharp/Page.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,12 @@ internal void OnDialog(PageJavascriptDialogOpeningResponse message)
780780
Dialog?.Invoke(this, new DialogEventArgs(dialog));
781781
}
782782

783+
/// <summary>
784+
/// Raises the <see cref="FrameAttached"/> event.
785+
/// </summary>
786+
/// <param name="e">Event arguments.</param>
787+
internal void OnFrameAttached(FrameEventArgs e) => FrameAttached?.Invoke(this, e);
788+
783789
/// <summary>
784790
/// Dispose resources.
785791
/// </summary>
@@ -790,12 +796,6 @@ protected virtual void Dispose(bool disposing)
790796
_ = DisposeAsync();
791797
}
792798

793-
/// <summary>
794-
/// Raises the <see cref="FrameAttached"/> event.
795-
/// </summary>
796-
/// <param name="e">Event arguments.</param>
797-
protected void OnFrameAttached(FrameEventArgs e) => FrameAttached?.Invoke(this, e);
798-
799799
/// <summary>
800800
/// Raises the <see cref="FrameNavigated"/> event.
801801
/// </summary>

0 commit comments

Comments
 (0)