Skip to content

Commit

Permalink
Introduce ConsoleMessage.Location (#919)
Browse files Browse the repository at this point in the history
* Some progress

* Introduce ConsoleMessage.Location

* CodeFactor + Test
  • Loading branch information
kblok authored Feb 13, 2019
1 parent 9d24cdb commit 3683608
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 10 deletions.
42 changes: 42 additions & 0 deletions lib/PuppeteerSharp.Tests/PageTests/Events/ConsoleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,48 @@ public async Task ShouldTriggerCorrectLog()
Assert.Equal(ConsoleType.Error, message.Type);
}

[Fact]
public async Task ShouldHaveLocationWhenFetchFails()
{
await Page.GoToAsync(TestConstants.EmptyPage);
var consoleTask = new TaskCompletionSource<ConsoleEventArgs>();
Page.Console += (sender, e) => consoleTask.TrySetResult(e);

await Task.WhenAll(
consoleTask.Task,
Page.SetContentAsync("<script>fetch('http://wat');</script>"));

var args = await consoleTask.Task;
Assert.Contains("ERR_NAME", args.Message.Text);
Assert.Equal(ConsoleType.Error, args.Message.Type);
Assert.Equal(new ConsoleMessageLocation
{
URL = "http://wat/",
}, args.Message.Location);
}

[Fact]
public async Task ShouldHaveLocationForConsoleAPICalls()
{
await Page.GoToAsync(TestConstants.EmptyPage);
var consoleTask = new TaskCompletionSource<ConsoleEventArgs>();
Page.Console += (sender, e) => consoleTask.TrySetResult(e);

await Task.WhenAll(
consoleTask.Task,
Page.GoToAsync(TestConstants.ServerUrl + "/consolelog.html"));

var args = await consoleTask.Task;
Assert.Equal("yellow", args.Message.Text);
Assert.Equal(ConsoleType.Log, args.Message.Type);
Assert.Equal(new ConsoleMessageLocation
{
URL = TestConstants.ServerUrl + "/consolelog.html",
LineNumber = 7,
ColumnNumber = 14
}, args.Message.Location);
}

[Fact]
public async Task ShouldNotThrowWhenThereAreConsoleMessagesInDetachedIframes()
{
Expand Down
6 changes: 6 additions & 0 deletions lib/PuppeteerSharp.Tests/WorkerTests/WorkerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ public async Task ShouldReportConsoleLogs()

var log = await consoleTcs.Task;
Assert.Equal("1", log.Text);
Assert.Equal(new ConsoleMessageLocation
{
URL = "data:text/javascript,console.log(1)",
LineNumber = 0,
ColumnNumber = 8
}, log.Location);
}

[Fact]
Expand Down
9 changes: 8 additions & 1 deletion lib/PuppeteerSharp/ConsoleMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,24 @@ public class ConsoleMessage
/// <value>The arguments.</value>
public IList<JSHandle> Args { get; }

/// <summary>
/// Gets the location.
/// </summary>
public ConsoleMessageLocation Location { get; }

/// <summary>
/// Initializes a new instance of the <see cref="ConsoleMessage"/> class.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="text">Text.</param>
/// <param name="args">Arguments.</param>
public ConsoleMessage(ConsoleType type, string text, IList<JSHandle> args = null)
/// <param name="location">Message location</param>
public ConsoleMessage(ConsoleType type, string text, IList<JSHandle> args, ConsoleMessageLocation location = null)
{
Type = type;
Text = text;
Args = args;
Location = location;
}
}
}
48 changes: 48 additions & 0 deletions lib/PuppeteerSharp/ConsoleMessageLocation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;

namespace PuppeteerSharp
{
/// <summary>
/// Console message location.
/// </summary>
public class ConsoleMessageLocation : IEquatable<ConsoleMessageLocation>
{
/// <summary>
/// URL of the resource if known.
/// </summary>
public string URL { get; set; }

/// <summary>
/// Line number in the resource if known.
/// </summary>
public int? LineNumber { get; set; }

/// <summary>
/// Column number in the resource if known.
/// </summary>
public int? ColumnNumber { get; set; }

/// <inheritdoc/>
public bool Equals(ConsoleMessageLocation other)
=> (URL, LineNumber, ColumnNumber) == (other?.URL, other?.LineNumber, other?.ColumnNumber);

/// <inheritdoc/>
public override bool Equals(object obj) => Equals(obj as ConsoleMessageLocation);

/// <inheritdoc/>
public override int GetHashCode()
=> 412870874 +
EqualityComparer<string>.Default.GetHashCode(URL) +
EqualityComparer<int?>.Default.GetHashCode(LineNumber) +
EqualityComparer<int?>.Default.GetHashCode(ColumnNumber);

/// <inheritdoc/>
public static bool operator ==(ConsoleMessageLocation location1, ConsoleMessageLocation location2)
=> EqualityComparer<ConsoleMessageLocation>.Default.Equals(location1, location2);

/// <inheritdoc/>
public static bool operator !=(ConsoleMessageLocation location1, ConsoleMessageLocation location2)
=> !(location1 == location2);
}
}
2 changes: 2 additions & 0 deletions lib/PuppeteerSharp/Messaging/LogEntryAddedResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ internal class LogEntry
public RemoteObject[] Args { get; set; }
public ConsoleType Level { get; set; }
public string Text { get; set; }
public string URL { get; set; }
public int? LineNumber { get; set; }
}
}
}
1 change: 1 addition & 0 deletions lib/PuppeteerSharp/Messaging/PageConsoleResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ internal class PageConsoleResponse
public ConsoleType Type { get; set; }
public RemoteObject[] Args { get; set; }
public int ExecutionContextId { get; set; }
public StackTrace StackTrace { get; set; }
}
}
7 changes: 7 additions & 0 deletions lib/PuppeteerSharp/Messaging/StackTrace.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace PuppeteerSharp.Messaging
{
internal class StackTrace
{
public ConsoleMessageLocation[] CallFrames { get; set; }
}
}
30 changes: 24 additions & 6 deletions lib/PuppeteerSharp/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1744,7 +1744,7 @@ private Clip ProcessClip(Clip clip)
{
var x = Math.Round(clip.X);
var y = Math.Round(clip.Y);

return new Clip
{
X = x,
Expand Down Expand Up @@ -1951,7 +1951,7 @@ private async Task OnAttachedToTarget(TargetAttachedToTargetResponse e)
return;
}
var session = Client.CreateSession(TargetType.Worker, sessionId);
var worker = new Worker(session, targetInfo.Url, AddConsoleMessage, HandleException);
var worker = new Worker(session, targetInfo.Url, AddConsoleMessageAsync, HandleException);
_workers[sessionId] = worker;
WorkerCreated?.Invoke(this, new WorkerEventArgs(worker));
}
Expand All @@ -1967,7 +1967,15 @@ private async Task OnLogEntryAddedAsync(LogEntryAddedResponse e)
}
if (e.Entry.Source != TargetType.Worker)
{
Console?.Invoke(this, new ConsoleEventArgs(new ConsoleMessage(e.Entry.Level, e.Entry.Text)));
Console?.Invoke(this, new ConsoleEventArgs(new ConsoleMessage(
e.Entry.Level,
e.Entry.Text,
null,
new ConsoleMessageLocation
{
URL = e.Entry.URL,
LineNumber = e.Entry.LineNumber
})));
}
}

Expand Down Expand Up @@ -2039,10 +2047,11 @@ private Task OnConsoleAPI(PageConsoleResponse message)
}
var ctx = _frameManager.ExecutionContextById(message.ExecutionContextId);
var values = message.Args.Select(ctx.CreateJSHandle).ToArray();
return AddConsoleMessage(message.Type, values);

return AddConsoleMessageAsync(message.Type, values, message.StackTrace);
}

private async Task AddConsoleMessage(ConsoleType type, JSHandle[] values)
private async Task AddConsoleMessageAsync(ConsoleType type, JSHandle[] values, Messaging.StackTrace stackTrace)
{
if (Console?.GetInvocationList().Length == 0)
{
Expand All @@ -2054,7 +2063,16 @@ private async Task AddConsoleMessage(ConsoleType type, JSHandle[] values)
? i.ToString()
: RemoteObjectHelper.ValueFromRemoteObject<string>(i.RemoteObject));

var consoleMessage = new ConsoleMessage(type, string.Join(" ", tokens), values);
var location = new ConsoleMessageLocation();
if (stackTrace?.CallFrames?.Length > 0)
{
var callFrame = stackTrace.CallFrames[0];
location.URL = callFrame.URL;
location.LineNumber = callFrame.LineNumber;
location.ColumnNumber = callFrame.ColumnNumber;
}

var consoleMessage = new ConsoleMessage(type, string.Join(" ", tokens), values, location);
Console?.Invoke(this, new ConsoleEventArgs(consoleMessage));
}

Expand Down
7 changes: 4 additions & 3 deletions lib/PuppeteerSharp/Worker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ public class Worker
private readonly ILogger _logger;
private readonly CDPSession _client;
private ExecutionContext _executionContext;
private readonly Func<ConsoleType, JSHandle[], Task> _consoleAPICalled;
private readonly Func<ConsoleType, JSHandle[], StackTrace, Task> _consoleAPICalled;
private readonly Action<EvaluateExceptionResponseDetails> _exceptionThrown;
private readonly TaskCompletionSource<ExecutionContext> _executionContextCallback;
private Func<ExecutionContext, RemoteObject, JSHandle> _jsHandleFactory;

internal Worker(
CDPSession client,
string url,
Func<ConsoleType, JSHandle[], Task> consoleAPICalled,
Func<ConsoleType, JSHandle[], StackTrace, Task> consoleAPICalled,
Action<EvaluateExceptionResponseDetails> exceptionThrown)
{
_logger = client.Connection.LoggerFactory.CreateLogger<Worker>();
Expand Down Expand Up @@ -128,7 +128,8 @@ private async Task OnConsoleAPICalled(MessageEventArgs e)
var consoleData = e.MessageData.ToObject<PageConsoleResponse>(true);
await _consoleAPICalled(
consoleData.Type,
consoleData.Args.Select(i => _jsHandleFactory(_executionContext, i)).ToArray())
consoleData.Args.Select(i => _jsHandleFactory(_executionContext, i)).ToArray(),
consoleData.StackTrace)
.ConfigureAwait(false);
}

Expand Down

0 comments on commit 3683608

Please sign in to comment.