Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

We don't need no dynamics #823

Merged
merged 6 commits into from
Dec 31, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<LangVersion>7.2</LangVersion>
<TargetFrameworks>netcoreapp2.2;net471</TargetFrameworks>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'=='net471'">
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
Expand Down
10 changes: 2 additions & 8 deletions demos/PuppeteerSharpPdfDemo/PuppeteerSharpPdfDemo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,8 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<LangVersion>7.2</LangVersion>
<TargetFramework>netcoreapp2.2</TargetFramework>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PuppeteerSharp" Version="1.0.1" />
Expand Down
14 changes: 7 additions & 7 deletions lib/PuppeteerSharp/CDPSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace PuppeteerSharp
{
/// <summary>
/// The CDPSession instances are used to talk raw Chrome Devtools Protocol:
/// * Protocol methods can be called with <see cref="CDPSession.SendAsync(string, dynamic, bool)"/> method.
/// * Protocol methods can be called with <see cref="CDPSession.SendAsync(string, object, bool)"/> method.
/// * Protocol events, using the <see cref="CDPSession.MessageReceived"/> event.
///
/// Documentation on DevTools Protocol can be found here: <see href="https://chromedevtools.github.io/devtools-protocol/"/>.
Expand Down Expand Up @@ -106,7 +106,7 @@ internal CDPSession(IConnection connection, TargetType targetType, string sessio

#region Public Methods

internal void Send(string method, dynamic args = null)
internal void Send(string method, object args = null)
=> _ = SendAsync(method, args, false);

/// <summary>
Expand All @@ -115,9 +115,9 @@ internal void Send(string method, dynamic args = null)
/// <param name="method">The method name</param>
/// <param name="args">The method args</param>
/// <returns>The task.</returns>
public async Task<T> SendAsync<T>(string method, dynamic args = null)
public async Task<T> SendAsync<T>(string method, object args = null)
{
JObject content = await SendAsync(method, args).ConfigureAwait(false);
var content = await SendAsync(method, args).ConfigureAwait(false);

return content.ToObject<T>(true);
}
Expand All @@ -133,7 +133,7 @@ public async Task<T> SendAsync<T>(string method, dynamic args = null)
/// </param>
/// <returns>The task.</returns>
/// <exception cref="PuppeteerSharp.PuppeteerException"></exception>
public async Task<JObject> SendAsync(string method, dynamic args = null, bool waitForCallback = true)
public async Task<JObject> SendAsync(string method, object args = null, bool waitForCallback = true)
{
if (Connection == null)
{
Expand All @@ -150,7 +150,7 @@ public async Task<JObject> SendAsync(string method, dynamic args = null, bool wa
{ MessageKeys.Params, args }
}, JsonHelper.DefaultJsonSerializerSettings);

_logger.LogTrace("Send ► {Id} Method {Method} Params {@Params}", id, method, (object)args);
_logger.LogTrace("Send ► {Id} Method {Method} Params {@Params}", id, method, args);

MessageTask callback = null;
if (waitForCallback)
Expand Down Expand Up @@ -310,7 +310,7 @@ internal CDPSession CreateSession(TargetType targetType, string sessionId)
#region IConnection
ILoggerFactory IConnection.LoggerFactory => LoggerFactory;
bool IConnection.IsClosed => IsClosed;
Task<JObject> IConnection.SendAsync(string method, dynamic args, bool waitForCallback)
Task<JObject> IConnection.SendAsync(string method, object args, bool waitForCallback)
=> SendAsync(method, args, waitForCallback);
IConnection IConnection.Connection => Connection;
void IConnection.Close(string closeReason) => Close(closeReason);
Expand Down
8 changes: 4 additions & 4 deletions lib/PuppeteerSharp/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ internal Connection(string url, int delay, IConnectionTransport transport, ILogg

#region Public Methods

internal async Task<JObject> SendAsync(string method, dynamic args = null, bool waitForCallback = true)
internal async Task<JObject> SendAsync(string method, object args = null, bool waitForCallback = true)
{
if (IsClosed)
{
Expand Down Expand Up @@ -119,9 +119,9 @@ internal async Task<JObject> SendAsync(string method, dynamic args = null, bool
return waitForCallback ? await callback.TaskWrapper.Task.WithConnectionCheck(this).ConfigureAwait(false) : null;
}

internal async Task<T> SendAsync<T>(string method, dynamic args = null)
internal async Task<T> SendAsync<T>(string method, object args = null)
{
JToken response = await SendAsync(method, args).ConfigureAwait(false);
var response = await SendAsync(method, args).ConfigureAwait(false);
return response.ToObject<T>(true);
}

Expand Down Expand Up @@ -305,7 +305,7 @@ public void Dispose()
#region IConnection
ILoggerFactory IConnection.LoggerFactory => LoggerFactory;
bool IConnection.IsClosed => IsClosed;
Task<JObject> IConnection.SendAsync(string method, dynamic args, bool waitForCallback)
Task<JObject> IConnection.SendAsync(string method, object args, bool waitForCallback)
=> SendAsync(method, args, waitForCallback);
IConnection IConnection.Connection => null;
void IConnection.Close(string closeReason) => Close(closeReason);
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/EvaluationFailedException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace PuppeteerSharp
{
/// <summary>
/// Exception thrown by <see cref="ExecutionContext.EvaluateHandleAsync(string, dynamic)"/>.
/// Exception thrown by <see cref="ExecutionContext.EvaluateHandleAsync(string, object)"/>.
/// </summary>
[Serializable]
public class EvaluationFailedException : PuppeteerException
Expand Down
19 changes: 10 additions & 9 deletions lib/PuppeteerSharp/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Newtonsoft.Json.Linq;
using PuppeteerSharp.Messaging;
using PuppeteerSharp.Helpers;
using static PuppeteerSharp.Messaging.RuntimeQueryObjectsResponse;

namespace PuppeteerSharp
{
Expand Down Expand Up @@ -116,12 +117,12 @@ public async Task<JSHandle> QueryObjectsAsync(JSHandle prototypeHandle)
throw new PuppeteerException("Prototype JSHandle must not be referencing primitive value");
}

var response = await _client.SendAsync("Runtime.queryObjects", new Dictionary<string, object>
var response = await _client.SendAsync<RuntimeQueryObjectsResponse>("Runtime.queryObjects", new Dictionary<string, object>
{
{"prototypeObjectId", objectId.ToString()}
}).ConfigureAwait(false);

return CreateJSHandle(response[MessageKeys.Objects]);
return CreateJSHandle(response.Objects);
}

internal async Task<JSHandle> EvaluateExpressionHandleAsync(string script)
Expand Down Expand Up @@ -173,8 +174,8 @@ internal async Task<JSHandle> EvaluateFunctionHandleAsync(string script, params
}
}

internal JSHandle CreateJSHandle(dynamic remoteObject)
=> (remoteObject.subtype == "node" && Frame != null)
internal JSHandle CreateJSHandle(JToken remoteObject)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to create a class for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the shape of the Token (adding this for reference)

image
image
image
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will implement a class @Meir017 the shape will be a composition of that ;)

=> (remoteObject.SelectToken(MessageKeys.Subtype).AsString() == "node" && Frame != null)
? new ElementHandle(this, _client, remoteObject, Frame.FrameManager.Page, Frame.FrameManager)
: new JSHandle(this, _client, remoteObject);

Expand All @@ -201,17 +202,17 @@ private async Task<T> EvaluateAsync<T>(Task<JSHandle> handleEvaluator)
return result is JToken token && token.Type == JTokenType.Null ? default : result;
}

private async Task<JSHandle> EvaluateHandleAsync(string method, dynamic args)
private async Task<JSHandle> EvaluateHandleAsync(string method, object args)
{
var response = await _client.SendAsync(method, args).ConfigureAwait(false);
var response = await _client.SendAsync<EvaluateHandleResponse>(method, args).ConfigureAwait(false);

if (response[MessageKeys.ExceptionDetails] is JToken exceptionDetails)
if (response.ExceptionDetails != null)
{
throw new EvaluationFailedException("Evaluation failed: " +
GetExceptionMessage(exceptionDetails.ToObject<EvaluateExceptionResponseDetails>(true)));
GetExceptionMessage(response.ExceptionDetails.ToObject<EvaluateExceptionResponseDetails>(true)));
}

return CreateJSHandle(response.result);
return CreateJSHandle(response.Result);
}

private object FormatArgument(object arg)
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/Helpers/RemoteObjectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ internal static object ValueFromRemoteObject<T>(JToken remoteObject)
}
}

internal static async Task ReleaseObject(CDPSession client, JToken remoteObject, ILogger logger)
internal static async Task ReleaseObjectAsync(CDPSession client, JToken remoteObject, ILogger logger)
{
var objectId = remoteObject[MessageKeys.ObjectId]?.AsString();

Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/IConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal interface IConnection
/// If <c>true</c> the method will return a task to be completed when the message is confirmed by Chromium.
/// If <c>false</c> the task will be considered complete after sending the message to Chromium.
/// </param>
Task<JObject> SendAsync(string method, dynamic args = null, bool waitForCallback = true);
Task<JObject> SendAsync(string method, object args = null, bool waitForCallback = true);
/// <summary>
/// Gets the parent connection
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/JSHandle.cs
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public async Task DisposeAsync()
}

Disposed = true;
await RemoteObjectHelper.ReleaseObject(Client, RemoteObject, Logger).ConfigureAwait(false);
await RemoteObjectHelper.ReleaseObjectAsync(Client, RemoteObject, Logger).ConfigureAwait(false);
}

/// <inheritdoc/>
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/MessageException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace PuppeteerSharp
{
/// <summary>
/// Exception thrown by <seealso cref="CDPSession.SendAsync(string, dynamic)"/>
/// Exception thrown by <seealso cref="CDPSession.SendAsync(string, object)"/>
/// </summary>
public class MessageException : PuppeteerException
{
Expand Down
10 changes: 10 additions & 0 deletions lib/PuppeteerSharp/Messaging/EvaluateHandleResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Newtonsoft.Json.Linq;

namespace PuppeteerSharp.Messaging
{
internal class EvaluateHandleResponse
{
public JToken ExceptionDetails { get; set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be a class?

public JToken Result { get; set; }
}
}
6 changes: 4 additions & 2 deletions lib/PuppeteerSharp/Messaging/LogEntryAddedResponse.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace PuppeteerSharp.Messaging
using Newtonsoft.Json.Linq;

namespace PuppeteerSharp.Messaging
{
internal class LogEntryAddedResponse
{
Expand All @@ -7,7 +9,7 @@ internal class LogEntryAddedResponse
internal class LogEntry
{
public TargetType Source { get; set; }
public dynamic[] Args { get; set; }
public JToken[] Args { get; set; }
public ConsoleType Level { get; set; }
public string Text { get; set; }
}
Expand Down
1 change: 0 additions & 1 deletion lib/PuppeteerSharp/Messaging/MessageKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ internal class MessageKeys
public const string PromptText = "promptText";
public const string Enumerable = "enumerable";
public const string Data = "data";
public const string Objects = "objects";
public const string Name = "name";
public const string Value = "value";
public const string Text = "text";
Expand Down
15 changes: 15 additions & 0 deletions lib/PuppeteerSharp/Messaging/PageCaptureScreenshotRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Newtonsoft.Json;
using PuppeteerSharp.Media;

namespace PuppeteerSharp.Messaging
{
internal class PageCaptureScreenshotRequest
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Format { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int Quality { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Clip Clip { get; set; }
}
}
6 changes: 4 additions & 2 deletions lib/PuppeteerSharp/Messaging/PageConsoleResponse.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
namespace PuppeteerSharp.Messaging
using Newtonsoft.Json.Linq;

namespace PuppeteerSharp.Messaging
{
internal class PageConsoleResponse
{
public ConsoleType Type { get; set; }
public dynamic[] Args { get; set; }
public JToken[] Args { get; set; }
public int ExecutionContextId { get; set; }
}
}
9 changes: 9 additions & 0 deletions lib/PuppeteerSharp/Messaging/RuntimeQueryObjectsResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Newtonsoft.Json.Linq;

namespace PuppeteerSharp.Messaging
{
internal class RuntimeQueryObjectsResponse
{
public JToken Objects { get; set; }
}
}
25 changes: 13 additions & 12 deletions lib/PuppeteerSharp/Page.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -1679,18 +1678,19 @@ private async Task<string> PerformScreenshot(ScreenshotType type, ScreenshotOpti
}
}

dynamic screenMessage = new ExpandoObject();

screenMessage.format = type.ToString().ToLower();
var screenMessage = new PageCaptureScreenshotRequest
{
Format = type.ToString().ToLower()
};

if (options.Quality.HasValue)
{
screenMessage.quality = options.Quality.Value;
screenMessage.Quality = options.Quality.Value;
}

if (clip != null)
{
screenMessage.clip = clip;
screenMessage.Clip = clip;
}

var result = await Client.SendAsync<PageCaptureScreenshotResponse>("Page.captureScreenshot", screenMessage).ConfigureAwait(false);
Expand Down Expand Up @@ -1797,7 +1797,7 @@ private async void Client_MessageReceived(object sender, MessageEventArgs e)
OnDetachedFromTarget(e);
break;
case "Log.entryAdded":
OnLogEntryAdded(e.MessageData.ToObject<LogEntryAddedResponse>(true));
await OnLogEntryAddedAsync(e.MessageData.ToObject<LogEntryAddedResponse>(true)).ConfigureAwait(false);
break;
case "Runtime.bindingCalled":
await OnBindingCalled(e.MessageData.ToObject<BindingCalledResponse>(true)).ConfigureAwait(false);
Expand Down Expand Up @@ -1851,6 +1851,7 @@ private async Task OnBindingCalled(BindingCalledResponse e)

private async Task<object> ExecuteBinding(BindingCalledResponse e)
{
const string taskResultPropertyName = "Result";
object result;
var binding = _pageBindings[e.BindingPayload.Name];
var methodParams = binding.Method.GetParameters().Select(parameter => parameter.ParameterType).ToArray();
Expand All @@ -1865,7 +1866,7 @@ private async Task<object> ExecuteBinding(BindingCalledResponse e)
if (taskResult.GetType().IsGenericType)
{
// the task is already awaited and therefore the call to property Result will not deadlock
result = ((dynamic)taskResult).Result;
result = taskResult.GetType().GetProperty(taskResultPropertyName).GetValue(taskResult);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the old way was weird but this also feels a bit odd, is there a clean way to do this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I open to new ideas 😂

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created an issue for this #824

}
}

Expand Down Expand Up @@ -1904,13 +1905,13 @@ private async Task OnAttachedToTarget(MessageEventArgs e)
WorkerCreated?.Invoke(this, new WorkerEventArgs(worker));
}

private void OnLogEntryAdded(LogEntryAddedResponse e)
private async Task OnLogEntryAddedAsync(LogEntryAddedResponse e)
{
if (e.Entry.Args != null)
{
foreach (var arg in e.Entry?.Args)
{
RemoteObjectHelper.ReleaseObject(Client, arg, _logger);
await RemoteObjectHelper.ReleaseObjectAsync(Client, arg, _logger);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this missing .ConfigureAwait(false) ?

}
}
if (e.Entry.Source != TargetType.Worker)
Expand Down Expand Up @@ -1982,7 +1983,7 @@ private void OnDialog(PageJavascriptDialogOpeningResponse message)
private Task OnConsoleAPI(PageConsoleResponse message)
{
var ctx = _frameManager.ExecutionContextById(message.ExecutionContextId);
var values = message.Args.Select<dynamic, JSHandle>(i => ctx.CreateJSHandle(i)).ToArray();
var values = message.Args.Select<JToken, JSHandle>(i => ctx.CreateJSHandle(i)).ToArray();
return AddConsoleMessage(message.Type, values);
}

Expand All @@ -1992,7 +1993,7 @@ private async Task AddConsoleMessage(ConsoleType type, JSHandle[] values)
{
foreach (var arg in values)
{
await RemoteObjectHelper.ReleaseObject(Client, arg.RemoteObject, _logger).ConfigureAwait(false);
await RemoteObjectHelper.ReleaseObjectAsync(Client, arg.RemoteObject, _logger).ConfigureAwait(false);
}

return;
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/Worker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ private async Task OnConsoleAPICalled(MessageEventArgs e)
var consoleData = e.MessageData.ToObject<PageConsoleResponse>(true);
await _consoleAPICalled(
consoleData.Type,
consoleData.Args.Select<dynamic, JSHandle>(i => _jsHandleFactory(_executionContext, i)).ToArray())
consoleData.Args.Select<JToken, JSHandle>(i => _jsHandleFactory(_executionContext, i)).ToArray())
.ConfigureAwait(false);
}

Expand Down