Skip to content

Commit ff4e3ff

Browse files
authored
CDPSession docs (#292)
1 parent db7b703 commit ff4e3ff

24 files changed

+132
-85
lines changed

lib/PuppeteerSharp.Tests/PuppeteerBaseTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ protected void Initialize()
3333
HttpsServer.Reset();
3434
}
3535

36-
protected static Task<dynamic> WaitForEvents(Session emitter, string eventName, int eventCount = 1)
36+
protected static Task<dynamic> WaitForEvents(CDPSession emitter, string eventName, int eventCount = 1)
3737
{
3838
var completion = new TaskCompletionSource<dynamic>();
3939
void handler(object sender, MessageEventArgs e)

lib/PuppeteerSharp.Tests/TargetTests/CreateCDPSessionTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public CreateCDPSessionTests(ITestOutputHelper output) : base(output)
1818
[Fact]
1919
public async Task ShouldWork()
2020
{
21-
var client = await Page.Target.CreateCDPSession();
21+
var client = await Page.Target.CreateCDPSessionAsync();
2222

2323
await Task.WhenAll(
2424
client.SendAsync("Runtime.enable"),
@@ -31,7 +31,7 @@ await Task.WhenAll(
3131
[Fact]
3232
public async Task ShouldSendEvents()
3333
{
34-
var client = await Page.Target.CreateCDPSession();
34+
var client = await Page.Target.CreateCDPSessionAsync();
3535
await client.SendAsync("Network.enable");
3636
var events = new List<object>();
3737

@@ -50,7 +50,7 @@ public async Task ShouldSendEvents()
5050
[Fact]
5151
public async Task ShouldEnableAndDisableDomainsIndependently()
5252
{
53-
var client = await Page.Target.CreateCDPSession();
53+
var client = await Page.Target.CreateCDPSessionAsync();
5454
await client.SendAsync("Runtime.enable");
5555
await client.SendAsync("Debugger.enable");
5656
// JS coverage enables and then disables Debugger domain.
@@ -69,7 +69,7 @@ await Task.WhenAll(
6969
[Fact]
7070
public async Task ShouldBeAbleToDetachSession()
7171
{
72-
var client = await Page.Target.CreateCDPSession();
72+
var client = await Page.Target.CreateCDPSessionAsync();
7373
await client.SendAsync("Runtime.enable");
7474
var evalResponse = await client.SendAsync("Runtime.evaluate", new { expression = "1 + 2", returnByValue = true });
7575
Assert.Equal(3, evalResponse.result.value.ToObject<int>());

lib/PuppeteerSharp/Session.cs renamed to lib/PuppeteerSharp/CDPSession.cs

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,54 +7,103 @@
77

88
namespace PuppeteerSharp
99
{
10-
public class Session : IDisposable
10+
/// <summary>
11+
/// The CDPSession instances are used to talk raw Chrome Devtools Protocol:
12+
/// * Protocol methods can be called with <see cref="CDPSession.SendAsync(string, bool, dynamic)"/> method.
13+
/// * Protocol events, using the <see cref="CDPSession.MessageReceived"/> event.
14+
///
15+
/// Documentation on DevTools Protocol can be found here: <see href="https://chromedevtools.github.io/devtools-protocol/"/>.
16+
///
17+
/// <code>
18+
/// <![CDATA[
19+
/// var client = await Page.Target.CreateCDPSessionAsync();
20+
/// await client.SendAsync("Animation.enable");
21+
/// client.MessageReceived += (sender, e) =>
22+
/// {
23+
/// if (e.MessageID == "Animation.animationCreated")
24+
/// {
25+
/// Console.WriteLine("Animation created!");
26+
/// }
27+
/// };
28+
/// dynamic response = await client.SendAsync("Animation.getPlaybackRate");
29+
/// Console.WriteLine("playback rate is " + response.playbackRate);
30+
/// await client.SendAsync("Animation.setPlaybackRate", new
31+
/// {
32+
/// playbackRate = Convert.ToInt32(response.playbackRate / 2)
33+
/// });
34+
/// ]]></code>
35+
/// </summary>
36+
public class CDPSession : IDisposable
1137
{
12-
public Session(Connection connection, string targetId, string sessionId)
38+
internal CDPSession(Connection connection, string targetId, string sessionId)
1339
{
1440
Connection = connection;
1541
TargetId = targetId;
1642
SessionId = sessionId;
1743

1844
_callbacks = new Dictionary<int, MessageTask>();
19-
_logger = Connection.LoggerFactory.CreateLogger<Session>();
45+
_logger = Connection.LoggerFactory.CreateLogger<CDPSession>();
2046
}
2147

2248
#region Private Members
23-
private int _lastId = 0;
49+
private int _lastId;
2450
private readonly Dictionary<int, MessageTask> _callbacks;
2551
private readonly ILogger _logger;
2652
#endregion
2753

2854
#region Properties
55+
/// <summary>
56+
/// Gets the target identifier.
57+
/// </summary>
58+
/// <value>The target identifier.</value>
2959
public string TargetId { get; }
60+
/// <summary>
61+
/// Gets the session identifier.
62+
/// </summary>
63+
/// <value>The session identifier.</value>
3064
public string SessionId { get; }
65+
/// <summary>
66+
/// Gets the connection.
67+
/// </summary>
68+
/// <value>The connection.</value>
3169
public Connection Connection { get; private set; }
70+
/// <summary>
71+
/// Occurs when message received from Chromium.
72+
/// </summary>
3273
public event EventHandler<MessageEventArgs> MessageReceived;
74+
/// <summary>
75+
/// Occurs when tracing is completed.
76+
/// </summary>
3377
public event EventHandler<TracingCompleteEventArgs> TracingComplete;
78+
/// <summary>
79+
/// Gets or sets a value indicating whether this <see cref="T:PuppeteerSharp.CDPSession"/> is closed.
80+
/// </summary>
81+
/// <value><c>true</c> if is closed; otherwise, <c>false</c>.</value>
3482
public bool IsClosed { get; internal set; }
3583
#endregion
3684

3785
#region Public Methods
3886

39-
public async Task<T> SendAsync<T>(string method, dynamic args = null)
87+
internal async Task<T> SendAsync<T>(string method, dynamic args = null)
4088
{
4189
var content = await SendAsync(method, true, args);
4290
return JsonConvert.DeserializeObject<T>(content);
4391
}
4492

45-
public Task<dynamic> SendAsync(string method, dynamic args = null)
93+
internal Task<dynamic> SendAsync(string method, dynamic args = null)
4694
{
4795
return SendAsync(method, false, args ?? new { });
4896
}
4997

50-
public async Task<dynamic> SendAsync(string method, bool rawContent, dynamic args = null)
98+
internal async Task<dynamic> SendAsync(string method, bool rawContent, dynamic args = null)
5199
{
52100
if (Connection == null)
53101
{
54102
throw new Exception($"Protocol error ({method}): Session closed. Most likely the page has been closed.");
55103
}
56104
int id = ++_lastId;
57-
var message = JsonConvert.SerializeObject(new Dictionary<string, object>(){
105+
var message = JsonConvert.SerializeObject(new Dictionary<string, object>
106+
{
58107
{"id", id},
59108
{"method", method},
60109
{"params", args}
@@ -72,7 +121,8 @@ public async Task<dynamic> SendAsync(string method, bool rawContent, dynamic arg
72121

73122
try
74123
{
75-
await Connection.SendAsync("Target.sendMessageToTarget", new Dictionary<string, object>() {
124+
await Connection.SendAsync("Target.sendMessageToTarget", new Dictionary<string, object>
125+
{
76126
{"sessionId", SessionId},
77127
{"message", message}
78128
});
@@ -100,10 +150,20 @@ public Task DetachAsync()
100150

101151
#region Private Methods
102152

153+
/// <summary>
154+
/// Releases all resource used by the <see cref="T:PuppeteerSharp.CDPSession"/> object by sending a ""Target.closeTarget"
155+
/// using the <see cref="Connection.SendAsync(string, dynamic)"/> method.
156+
/// </summary>
157+
/// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="PuppeteerSharp.CDPSession"/>. The
158+
/// <see cref="Dispose"/> method leaves the <see cref="PuppeteerSharp.CDPSession"/> in an unusable state.
159+
/// After calling <see cref="Dispose"/>, you must release all references to the
160+
/// <see cref="PuppeteerSharp.CDPSession"/> so the garbage collector can reclaim the memory that the
161+
/// <see cref="PuppeteerSharp.CDPSession"/> was occupying.</remarks>
103162
public void Dispose()
104163
{
105-
Connection.SendAsync("Target.closeTarget", new Dictionary<string, object>() {
106-
{"targetId", TargetId}
164+
Connection.SendAsync("Target.closeTarget", new Dictionary<string, object>
165+
{
166+
["targetId"] = TargetId
107167
}).GetAwaiter().GetResult();
108168
}
109169

lib/PuppeteerSharp/Connection.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal Connection(string url, int delay, ClientWebSocket ws, ILoggerFactory lo
2929
_logger = LoggerFactory.CreateLogger<Connection>();
3030
_socketQueue = new TaskQueue();
3131
_responses = new Dictionary<int, MessageTask>();
32-
_sessions = new Dictionary<string, Session>();
32+
_sessions = new Dictionary<string, CDPSession>();
3333
_websocketReaderCancellationSource = new CancellationTokenSource();
3434

3535
Task task = Task.Factory.StartNew(async () =>
@@ -41,7 +41,7 @@ internal Connection(string url, int delay, ClientWebSocket ws, ILoggerFactory lo
4141
#region Private Members
4242
private int _lastId;
4343
private Dictionary<int, MessageTask> _responses;
44-
private Dictionary<string, Session> _sessions;
44+
private Dictionary<string, CDPSession> _sessions;
4545
private TaskQueue _socketQueue;
4646
private const string CloseMessage = "Browser.close";
4747
private bool _stopReading;
@@ -113,10 +113,10 @@ internal async Task<dynamic> SendAsync(string method, dynamic args = null)
113113
return await _responses[id].TaskWrapper.Task;
114114
}
115115

116-
internal async Task<Session> CreateSession(string targetId)
116+
internal async Task<CDPSession> CreateSessionAsync(string targetId)
117117
{
118118
string sessionId = (await SendAsync("Target.attachToTarget", new { targetId })).sessionId;
119-
var session = new Session(this, targetId, sessionId);
119+
var session = new CDPSession(this, targetId, sessionId);
120120
_sessions.Add(sessionId, session);
121121
return session;
122122
}

lib/PuppeteerSharp/Dialog.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ namespace PuppeteerSharp
55
{
66
public class Dialog
77
{
8-
private Session _client;
9-
8+
private readonly CDPSession _client;
9+
1010
public DialogType DialogType { get; set; }
1111
public string DefaultValue { get; set; }
1212
public string Message { get; set; }
1313

14-
public Dialog(Session client, DialogType type, string message, string defaultValue)
14+
public Dialog(CDPSession client, DialogType type, string message, string defaultValue)
1515
{
1616
_client = client;
1717
DialogType = type;

lib/PuppeteerSharp/ElementHandle.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class ElementHandle : JSHandle
1717
{
1818
internal Page Page { get; }
1919

20-
internal ElementHandle(ExecutionContext context, Session client, object remoteObject, Page page) :
20+
internal ElementHandle(ExecutionContext context, CDPSession client, object remoteObject, Page page) :
2121
base(context, client, remoteObject)
2222
{
2323
Page = page;

lib/PuppeteerSharp/EmulationManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ namespace PuppeteerSharp
66
{
77
internal class EmulationManager
88
{
9-
private Session _client;
9+
private readonly CDPSession _client;
1010
private string _injectedTouchScriptId;
1111
private bool _emulatingMobile;
1212

13-
public EmulationManager(Session client)
13+
public EmulationManager(CDPSession client)
1414
{
1515
_client = client;
1616
}
1717

18-
internal async Task<bool> EmulateViewport(Session client, ViewPortOptions viewport)
18+
internal async Task<bool> EmulateViewport(CDPSession client, ViewPortOptions viewport)
1919
{
2020
var mobile = viewport.IsMobile;
2121
var width = viewport.Width;

lib/PuppeteerSharp/ExecutionContext.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ namespace PuppeteerSharp
1313
/// </summary>
1414
public class ExecutionContext
1515
{
16-
private readonly Session _client;
16+
private readonly CDPSession _client;
1717
private readonly int _contextId;
1818

19-
internal ExecutionContext(Session client, ContextPayload contextPayload, Func<dynamic, JSHandle> objectHandleFactory)
19+
internal ExecutionContext(CDPSession client, ContextPayload contextPayload, Func<dynamic, JSHandle> objectHandleFactory)
2020
{
2121
_client = client;
2222
_contextId = contextPayload.Id;

lib/PuppeteerSharp/Frame.cs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ namespace PuppeteerSharp
3838
/// </example>
3939
public class Frame
4040
{
41-
private readonly Session _client;
41+
private readonly CDPSession _client;
4242
private readonly Page _page;
43-
4443
private TaskCompletionSource<ElementHandle> _documentCompletionSource;
4544
private TaskCompletionSource<ExecutionContext> _contextResolveTaskWrapper;
4645

@@ -49,14 +48,7 @@ public class Frame
4948
internal string LoaderId { get; set; }
5049
internal List<string> LifecycleEvents { get; }
5150

52-
/// <summary>
53-
/// Initializes a new instance of the <see cref="Frame"/> class.
54-
/// </summary>
55-
/// <param name="client">The client</param>
56-
/// <param name="page">The page containing the frame</param>
57-
/// <param name="parentFrame">The parent frame</param>
58-
/// <param name="frameId">The frameId</param>
59-
public Frame(Session client, Page page, Frame parentFrame, string frameId)
51+
internal Frame(CDPSession client, Page page, Frame parentFrame, string frameId)
6052
{
6153
_client = client;
6254
_page = page;
@@ -90,7 +82,7 @@ public Frame(Session client, Page page, Frame parentFrame, string frameId)
9082
/// Gets the frame's url
9183
/// </summary>
9284
public string Url { get; private set; }
93-
85+
9486
/// <summary>
9587
/// Gets a value indicating if the frame is detached or not
9688
/// </summary>
@@ -215,7 +207,7 @@ function hasVisibleBoundingBox() {
215207
}, selector, options.Visible, options.Hidden);
216208
return handle as ElementHandle;
217209
}
218-
210+
219211
/// <summary>
220212
/// Waits for a timeout
221213
/// </summary>
@@ -483,7 +475,7 @@ internal void SetDefaultContext(ExecutionContext context)
483475
_contextResolveTaskWrapper = new TaskCompletionSource<ExecutionContext>();
484476
}
485477
}
486-
478+
487479
internal void Detach()
488480
{
489481
while (WaitTasks.Count > 0)

lib/PuppeteerSharp/FrameManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ namespace PuppeteerSharp
1010
{
1111
public class FrameManager
1212
{
13-
private readonly Session _client;
13+
private readonly CDPSession _client;
1414
private readonly Page _page;
15-
private readonly Dictionary<int, ExecutionContext> _contextIdToContext;
15+
private Dictionary<int, ExecutionContext> _contextIdToContext;
1616
private readonly ILogger _logger;
1717

18-
public FrameManager(Session client, FrameTree frameTree, Page page)
18+
public FrameManager(CDPSession client, FrameTree frameTree, Page page)
1919
{
2020
_client = client;
2121
_page = page;

0 commit comments

Comments
 (0)