Skip to content

Commit 787a76b

Browse files
authored
Target refactor (#373)
1 parent 21ad44f commit 787a76b

File tree

6 files changed

+112
-27
lines changed

6 files changed

+112
-27
lines changed

lib/PuppeteerSharp.Tests/TargetTests/TargetTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ public void BrowserTargetsShouldReturnAllOfTheTargets()
1919
{
2020
// The pages will be the testing page and the original newtab page
2121
var targets = Browser.Targets();
22-
Assert.Contains(targets, target => target.Type == "page"
22+
Assert.Contains(targets, target => target.Type == TargetType.Page
2323
&& target.Url == TestConstants.AboutBlank);
24-
Assert.Contains(targets, target => target.Type == "browser");
24+
Assert.Contains(targets, target => target.Type == TargetType.Browser);
2525
}
2626

2727
[Fact]
@@ -38,7 +38,7 @@ public async Task BrowserPagesShouldReturnAllOfThePages()
3838
public void ShouldContainBrowserTarget()
3939
{
4040
var targets = Browser.Targets();
41-
var browserTarget = targets.FirstOrDefault(target => target.Type == "browser");
41+
var browserTarget = targets.FirstOrDefault(target => target.Type == TargetType.Browser);
4242
Assert.NotNull(browserTarget);
4343
}
4444

@@ -102,7 +102,7 @@ void TargetCreatedEventHandler(object sender, TargetChangedArgs e)
102102
await Page.GoToAsync(TestConstants.ServerUrl + "/serviceworkers/empty/sw.html");
103103

104104
var createdTarget = await createdTargetTaskCompletion.Task;
105-
Assert.Equal("service_worker", createdTarget.Type);
105+
Assert.Equal(TargetType.ServiceWorker, createdTarget.Type);
106106
Assert.Equal(TestConstants.ServerUrl + "/serviceworkers/empty/sw.js", createdTarget.Url);
107107

108108
var targetDestroyedTaskCompletion = new TaskCompletionSource<Target>();
@@ -144,7 +144,7 @@ void ChangedTargetEventHandler(object sender, TargetChangedArgs e)
144144
public async Task ShouldNotReportUninitializedPages()
145145
{
146146
var targetChanged = false;
147-
EventHandler<TargetChangedArgs> listener = (sender, e) => targetChanged = true;
147+
void listener(object sender, TargetChangedArgs e) => targetChanged = true;
148148
Browser.TargetChanged += listener;
149149
var targetCompletionTask = new TaskCompletionSource<Target>();
150150
void TargetCreatedEventHandler(object sender, TargetChangedArgs e)

lib/PuppeteerSharp/Browser.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,13 @@ public Browser(Connection connection, IBrowserOptions options, Process process,
5555
Connection.MessageReceived += Connect_MessageReceived;
5656

5757
_closeCallBack = closeCallBack;
58+
_logger = Connection.LoggerFactory.CreateLogger<Browser>();
5859
}
5960

6061
#region Private members
6162
private readonly Dictionary<string, Target> _targets;
6263
private readonly Func<Task> _closeCallBack;
64+
private readonly ILogger<Browser> _logger;
6365
#endregion
6466

6567
#region Properties
@@ -138,7 +140,7 @@ public async Task<Page> NewPageAsync()
138140
{
139141
string targetId = (await Connection.SendAsync("Target.createTarget", new Dictionary<string, object>
140142
{
141-
{"url", "about:blank"}
143+
["url"] = "about:blank"
142144
})).targetId.ToString();
143145

144146
var target = _targets[targetId];
@@ -272,7 +274,7 @@ private async Task DestroyTargetAsync(TargetDestroyedResponse e)
272274
}
273275
if (await target.InitializedTask)
274276
{
275-
TargetDestroyed?.Invoke(this, new TargetChangedArgs()
277+
TargetDestroyed?.Invoke(this, new TargetChangedArgs
276278
{
277279
Target = target
278280
});
@@ -281,12 +283,21 @@ private async Task DestroyTargetAsync(TargetDestroyedResponse e)
281283

282284
private async Task CreateTargetAsync(TargetCreatedResponse e)
283285
{
284-
var target = new Target(this, e.TargetInfo);
286+
var target = new Target(
287+
e.TargetInfo,
288+
() => Connection.CreateSessionAsync(e.TargetInfo.TargetId),
289+
this);
290+
291+
if (_targets.ContainsKey(e.TargetInfo.TargetId))
292+
{
293+
_logger.LogError("Target should not exist before targetCreated");
294+
}
295+
285296
_targets[e.TargetInfo.TargetId] = target;
286297

287298
if (await target.InitializedTask)
288299
{
289-
TargetCreated?.Invoke(this, new TargetChangedArgs()
300+
TargetCreated?.Invoke(this, new TargetChangedArgs
290301
{
291302
Target = target
292303
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using Newtonsoft.Json;
3+
using Newtonsoft.Json.Converters;
4+
5+
namespace PuppeteerSharp.Helpers
6+
{
7+
internal class FlexibleStringEnumConverter : StringEnumConverter
8+
{
9+
private Enum _fallbackValue;
10+
11+
public FlexibleStringEnumConverter(Enum fallbackValue)
12+
{
13+
_fallbackValue = fallbackValue;
14+
}
15+
16+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
17+
{
18+
try
19+
{
20+
return base.ReadJson(reader, objectType, existingValue, serializer);
21+
}
22+
catch
23+
{
24+
return _fallbackValue;
25+
}
26+
}
27+
}
28+
}

lib/PuppeteerSharp/Target.cs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
using System.Diagnostics;
1+
using System;
2+
using System.Diagnostics;
23
using System.Threading.Tasks;
4+
using PuppeteerSharp.Helpers;
35

46
namespace PuppeteerSharp
57
{
@@ -10,25 +12,30 @@ namespace PuppeteerSharp
1012
public class Target
1113
{
1214
#region Private members
13-
private Browser _browser;
15+
private readonly Browser _browser;
1416
private TargetInfo _targetInfo;
17+
private string _targetId;
18+
private Func<Task<CDPSession>> _sessionFactory;
1519
private Task<Page> _pageTask;
1620
#endregion
1721

1822
internal bool IsInitialized;
1923

20-
internal Target(Browser browser, TargetInfo targetInfo)
24+
internal Target(TargetInfo targetInfo, Func<Task<CDPSession>> sessionFactory, Browser browser)
2125
{
22-
_browser = browser;
2326
_targetInfo = targetInfo;
27+
_targetId = targetInfo.TargetId;
28+
_sessionFactory = sessionFactory;
29+
_browser = browser;
30+
_pageTask = null;
2431

2532
InitilizedTaskWrapper = new TaskCompletionSource<bool>();
2633
CloseTaskWrapper = new TaskCompletionSource<bool>();
27-
IsInitialized = _targetInfo.Type != "page" || _targetInfo.Url != string.Empty;
34+
IsInitialized = _targetInfo.Type != TargetType.Page || _targetInfo.Url != string.Empty;
2835

29-
if (IsInitialized)
30-
{
31-
InitilizedTaskWrapper.SetResult(true);
36+
if (IsInitialized)
37+
{
38+
InitilizedTaskWrapper.SetResult(true);
3239
}
3340
}
3441

@@ -42,7 +49,8 @@ internal Target(Browser browser, TargetInfo targetInfo)
4249
/// Gets the type. It will be <see cref="TargetInfo.Type"/> if it's "page" or "service_worker". Otherwise it will be "other"
4350
/// </summary>
4451
/// <value>The type.</value>
45-
public string Type => _targetInfo.Type == "page" || _targetInfo.Type == "service_worker" || _targetInfo.Type == "browser" ? _targetInfo.Type : "other";
52+
public TargetType Type => _targetInfo.Type;
53+
4654
/// <summary>
4755
/// Gets the target identifier.
4856
/// </summary>
@@ -60,22 +68,26 @@ internal Target(Browser browser, TargetInfo targetInfo)
6068
/// <returns>a task that returns a new <see cref="Page"/></returns>
6169
public async Task<Page> PageAsync()
6270
{
63-
if (_targetInfo.Type == "page" && _pageTask == null)
64-
{
65-
_pageTask = await _browser.Connection.CreateSessionAsync(_targetInfo.TargetId)
66-
.ContinueWith(clientTask
67-
=> Page.CreateAsync(clientTask.Result, this, _browser.IgnoreHTTPSErrors, _browser.AppMode, _browser.ScreenshotTaskQueue));
71+
if (_targetInfo.Type == TargetType.Page && _pageTask == null)
72+
{
73+
_pageTask = CreatePageAsync();
6874
}
6975

7076
return await (_pageTask ?? Task.FromResult<Page>(null));
7177
}
7278

79+
private async Task<Page> CreatePageAsync()
80+
{
81+
var session = await _sessionFactory();
82+
return await Page.CreateAsync(session, this, _browser.IgnoreHTTPSErrors, _browser.AppMode, _browser.ScreenshotTaskQueue);
83+
}
84+
7385
internal void TargetInfoChanged(TargetInfo targetInfo)
7486
{
7587
var previousUrl = _targetInfo.Url;
7688
_targetInfo = targetInfo;
7789

78-
if (!IsInitialized && (_targetInfo.Type != "page" || _targetInfo.Url != string.Empty))
90+
if (!IsInitialized && (_targetInfo.Type != TargetType.Page || _targetInfo.Url != string.Empty))
7991
{
8092
IsInitialized = true;
8193
InitilizedTaskWrapper.SetResult(true);

lib/PuppeteerSharp/TargetInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ internal TargetInfo()
1616
/// </summary>
1717
/// <value>The type.</value>
1818
[JsonProperty("type")]
19-
public string Type { get; internal set; }
19+
public TargetType Type { get; internal set; }
2020
/// <summary>
2121
/// Gets or sets the URL.
2222
/// </summary>
@@ -28,6 +28,6 @@ internal TargetInfo()
2828
/// </summary>
2929
/// <value>The target identifier.</value>
3030
[JsonProperty("targetId")]
31-
public string TargetId { get; internal set; }
31+
public string TargetId { get; internal set; }
3232
}
33-
}
33+
}

lib/PuppeteerSharp/TargetType.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.Runtime.Serialization;
2+
using Newtonsoft.Json;
3+
using Newtonsoft.Json.Converters;
4+
using PuppeteerSharp.Helpers;
5+
6+
namespace PuppeteerSharp
7+
{
8+
/// <summary>
9+
/// Target type.
10+
/// </summary>
11+
[JsonConverter(typeof(FlexibleStringEnumConverter), Other)]
12+
public enum TargetType
13+
{
14+
/// <summary>
15+
/// The other.
16+
/// </summary>
17+
Other,
18+
/// <summary>
19+
/// Target type page.
20+
/// </summary>
21+
[EnumMember(Value = "page")]
22+
Page,
23+
/// <summary>
24+
/// Target type service worker.
25+
/// </summary>
26+
[EnumMember(Value = "service_worker")]
27+
ServiceWorker,
28+
/// <summary>
29+
/// Target type browser.
30+
/// </summary>
31+
[EnumMember(Value = "browser")]
32+
Browser
33+
}
34+
}

0 commit comments

Comments
 (0)