Skip to content

Commit 76a021d

Browse files
Meir017kblok
authored andcommitted
added Page.title tests (#96)
closes #49
1 parent d98f9c6 commit 76a021d

File tree

11 files changed

+96
-26
lines changed

11 files changed

+96
-26
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ Thumbs.db
290290

291291
# ignore local cert
292292
/lib/PuppeteerSharp.TestServer/testCert.cer
293+
/lib/PuppeteerSharp.Tests/Screenshots/test.png
293294

294295
demos/PuppeteerSharpPdfDemo/google.pdf
295-
demos/PuppeteerSharpPdfDemo/.local-chromium/
296+
demos/PuppeteerSharpPdfDemo/.local-chromium/
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Threading.Tasks;
2+
using Xunit;
3+
4+
namespace PuppeteerSharp.Tests.Page
5+
{
6+
[Collection("PuppeteerLoaderFixture collection")]
7+
public class TitleTests : PuppeteerBaseTest
8+
{
9+
[Fact]
10+
public async Task ShouldReturnThePageTitle()
11+
{
12+
var page = await Browser.NewPageAsync();
13+
14+
await page.GoToAsync(TestConstants.ServerUrl + "/input/button.html");
15+
Assert.Equal("Button test", await page.GetTitleAsync());
16+
}
17+
}
18+
}

lib/PuppeteerSharp.Tests/PuppeteerSharp.Tests.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
</ItemGroup>
1616
<ItemGroup>
1717
<Folder Include="Puppeteer\" />
18-
<Folder Include="Page\" />
1918
</ItemGroup>
2019
<ItemGroup>
2120
<ProjectReference Include="..\PuppeteerSharp\PuppeteerSharp.csproj" />

lib/PuppeteerSharp/ContextPayload.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
{
33
public class ContextPayload
44
{
5-
65
public ContextPayload(dynamic context)
76
{
87
Id = context.id;
8+
AuxData = context.auxData.ToObject<ContextPayloadAuxData>();
99
}
1010

11-
public string Id { get; internal set; }
11+
public int Id { get; internal set; }
12+
13+
public ContextPayloadAuxData AuxData { get; internal set; }
1214
}
1315
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace PuppeteerSharp
2+
{
3+
public struct ContextPayloadAuxData
4+
{
5+
public string FrameId { get; set; }
6+
public bool IsDefault { get; set; }
7+
}
8+
}

lib/PuppeteerSharp/ExecutionContext.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@ namespace PuppeteerSharp
66
{
77
public class ExecutionContext
88
{
9-
private Session _client;
10-
private string _contextId;
9+
private readonly Session _client;
10+
private readonly int _contextId;
1111

1212
public ExecutionContext(Session client, ContextPayload contextPayload, Func<dynamic, JSHandle> objectHandleFactory)
1313
{
1414
_client = client;
1515
_contextId = contextPayload.Id;
16+
FrameId = contextPayload.AuxData.FrameId;
17+
IsDefault = contextPayload.AuxData.IsDefault;
1618
ObjectHandleFactory = objectHandleFactory;
1719
}
1820

19-
public Func<JSHandle, dynamic> ObjectHandleFactory { get; internal set; }
21+
public Func<dynamic, JSHandle> ObjectHandleFactory { get; internal set; }
2022
public string FrameId { get; internal set; }
2123
public bool IsDefault { get; internal set; }
2224

@@ -43,12 +45,13 @@ internal async Task<JSHandle> EvaluateHandleAsync(string pageFunction, object[]
4345
{
4446
remoteObject = await _client.SendAsync("Runtime.evaluate", new Dictionary<string, object>()
4547
{
46-
{"expression", _contextId},
47-
{"returnByValue", false},
48-
{"awaitPromise", true}
48+
["expression"] = pageFunction,
49+
["contextId"] = _contextId,
50+
["returnByValue"] = false,
51+
["awaitPromise"] = true
4952
});
5053

51-
return ObjectHandleFactory(remoteObject);
54+
return ObjectHandleFactory(remoteObject.result);
5255
}
5356
catch (Exception ex)
5457
{

lib/PuppeteerSharp/Frame.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,17 @@ public Frame(Session client, Page page, Frame parentFrame, string frameId)
5151

5252
public Task<ExecutionContext> GetExecutionContextAsync() => ContextResolveTaskWrapper.Task;
5353

54+
internal async Task<dynamic> EvaluateAsync(string pageFunction, params object[] args)
55+
{
56+
var context = await GetExecutionContextAsync();
57+
return await context.Evaluate(pageFunction, args);
58+
}
59+
5460
internal async Task<ElementHandle> GetElementAsync(string selector)
5561
{
5662
throw new NotImplementedException();
5763
}
5864

59-
6065
internal Task<object> Eval(string selector, Func<object> pageFunction, object[] args)
6166
{
6267
throw new NotImplementedException();
@@ -92,6 +97,12 @@ internal Task<ElementHandle> AddScriptTag(dynamic options)
9297
throw new NotImplementedException();
9398
}
9499

100+
internal async Task<string> GetTitleAsync()
101+
{
102+
var result = await EvaluateAsync("document.title");
103+
return result.ToString();
104+
}
105+
95106
internal void OnLifecycleEvent(string loaderId, string name)
96107
{
97108
if (name == "init")
@@ -113,7 +124,6 @@ internal void SetDefaultContext(ExecutionContext context)
113124
if (context != null)
114125
{
115126
ContextResolveTaskWrapper.SetResult(context);
116-
ContextResolveTaskWrapper = null;
117127

118128
foreach (var waitTask in _waitTasks)
119129
{
@@ -137,8 +147,9 @@ internal void Detach()
137147
{
138148
_parentFrame.ChildFrames.Remove(this);
139149
}
140-
_parentFrame = null;
141-
#endregion
150+
_parentFrame = null;
142151
}
152+
153+
#endregion
143154
}
144155
}

lib/PuppeteerSharp/FrameManager.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Diagnostics.Contracts;
44
using PuppeteerSharp.Input;
55
using Newtonsoft.Json.Linq;
6+
using System.Diagnostics;
67

78
namespace PuppeteerSharp
89
{
@@ -12,14 +13,14 @@ public class FrameManager
1213
private Mouse _mouse;
1314
private Touchscreen _touchscreen;
1415
private Page _page;
15-
private Dictionary<string, ExecutionContext> _contextIdToContext;
16+
private Dictionary<int, ExecutionContext> _contextIdToContext;
1617

1718
public FrameManager(Session client, FrameTree frameTree, Page page)
1819
{
1920
_client = client;
2021
_page = page;
2122
Frames = new Dictionary<string, Frame>();
22-
_contextIdToContext = new Dictionary<string, ExecutionContext>();
23+
_contextIdToContext = new Dictionary<int, ExecutionContext>();
2324

2425
_client.MessageReceived += _client_MessageReceived;
2526
HandleFrameTree(frameTree);
@@ -60,7 +61,7 @@ void _client_MessageReceived(object sender, PuppeteerSharp.MessageEventArgs e)
6061
break;
6162

6263
case "Runtime.executionContextDestroyed":
63-
OnExecutionContextDestroyed(e.MessageData.executionContextId.ToString());
64+
OnExecutionContextDestroyed((int)e.MessageData.executionContextId);
6465
break;
6566
case "Runtime.executionContextsCleared":
6667
OnExecutionContextsCleared();
@@ -92,7 +93,7 @@ private void OnExecutionContextsCleared()
9293
_contextIdToContext.Clear();
9394
}
9495

95-
private void OnExecutionContextDestroyed(string executionContextId)
96+
private void OnExecutionContextDestroyed(int executionContextId)
9697
{
9798
_contextIdToContext.TryGetValue(executionContextId, out var context);
9899

@@ -109,8 +110,11 @@ private void OnExecutionContextCreated(ContextPayload contextPayload)
109110
var context = new ExecutionContext(_client, contextPayload, (dynamic remoteObject) =>
110111
{
111112
_contextIdToContext.TryGetValue(contextPayload.Id, out var storedContext);
112-
113-
Contract.Assert(storedContext == null, $"INTERNAL ERROR: missing context with id = {contextPayload.Id}");
113+
114+
if(storedContext == null)
115+
{
116+
Console.WriteLine($"INTERNAL ERROR: missing context with id = {contextPayload.Id}");
117+
}
114118
if (remoteObject.Subtype == "node")
115119
{
116120
return new ElementHandle(storedContext, _client, remoteObject, _page);

lib/PuppeteerSharp/Helper.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,35 @@ internal class Helper
77
{
88
internal static object ValueFromRemoteObject(dynamic remoteObject)
99
{
10-
throw new NotImplementedException();
10+
if (remoteObject.unserializableValue != null)
11+
{
12+
switch (remoteObject.unserializableValue.ToString())
13+
{
14+
case "-0": return -0;
15+
case "NaN": return double.NaN;
16+
case "Infinity": return double.PositiveInfinity;
17+
case "-Infinity": return double.NegativeInfinity;
18+
default:
19+
throw new Exception("Unsupported unserializable value: " + remoteObject.unserializableValue);
20+
}
21+
}
22+
return remoteObject.value;
1123
}
1224

13-
internal static Task ReleaseObject(Session client, dynamic remoteObject)
25+
internal static async Task ReleaseObject(Session client, dynamic remoteObject)
1426
{
15-
throw new NotImplementedException();
27+
if (remoteObject.objectId == null)
28+
return;
29+
try
30+
{
31+
await client.SendAsync("Runtime.releaseObject", new { remoteObject.objectId });
32+
}
33+
catch (Exception ex)
34+
{
35+
// Exceptions might happen in case of a page been navigated or closed.
36+
// Swallow these since they are harmless and we don't leak anything in this case.
37+
Console.WriteLine(ex.ToString());
38+
}
1639
}
1740
}
1841
}

lib/PuppeteerSharp/JSHandle.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ public async Task<Dictionary<string, object>> GetProperty(string propertyName)
3737

3838
public async Task<object> JsonValue()
3939
{
40-
if (((IDictionary<string, object>)RemoteObject).ContainsKey("objectId"))
40+
if (RemoteObject.objectId != null)
4141
{
42-
dynamic response = await _client.SendAsync("Retunrime.callFunctionOn", new Dictionary<string, object>()
42+
dynamic response = await _client.SendAsync("Runtime.callFunctionOn", new Dictionary<string, object>()
4343
{
4444
{"functionDeclaration", "function() { return this; }"},
4545
{"objectId", RemoteObject.objectId},

0 commit comments

Comments
 (0)