Skip to content

Commit b1fb17f

Browse files
kblokMeir017
authored andcommitted
CloseMe tests (#382)
* Project * Progress * Test * EditorConfig errors * Feature complete * Improve Unix kill * Remove unused code * Code review * Reuse process creation * Ups
1 parent 332796a commit b1fb17f

File tree

10 files changed

+158
-49
lines changed

10 files changed

+158
-49
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace PuppeteerSharp.Tests.CloseMe
5+
{
6+
class Program
7+
{
8+
public static async Task Main(string[] args)
9+
{
10+
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
11+
var options = new LaunchOptions
12+
{
13+
Headless = true,
14+
DumpIO = false,
15+
ExecutablePath = args[0]
16+
};
17+
18+
using (var browser = await Puppeteer.LaunchAsync(options))
19+
{
20+
Console.WriteLine(browser.WebSocketEndpoint);
21+
Console.ReadLine();
22+
}
23+
}
24+
}
25+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
5+
<LangVersion>7.2</LangVersion>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<ProjectReference Include="..\PuppeteerSharp\PuppeteerSharp.csproj" />
9+
</ItemGroup>
10+
<ItemGroup>
11+
<Compile Remove="Properties\AssemblyInfo.cs" />
12+
</ItemGroup>
13+
</Project>

lib/PuppeteerSharp.Tests/NetworkTests/NetworkEventTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,13 @@ public async Task PageEventsRequestFailed()
153153
Page.Request += async (sender, e) =>
154154
{
155155
if (e.Request.Url.EndsWith("css"))
156+
{
156157
await e.Request.AbortAsync();
158+
}
157159
else
160+
{
158161
await e.Request.ContinueAsync();
162+
}
159163
};
160164
var failedRequests = new List<Request>();
161165
Page.RequestFailed += (sender, e) => failedRequests.Add(e.Request);

lib/PuppeteerSharp.Tests/PuppeteerTests/PuppeteerLaunchTests.cs

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO;
55
using System.Linq;
66
using System.Net;
7+
using System.Runtime.InteropServices;
78
using System.Threading.Tasks;
89
using Xunit;
910
using Xunit.Abstractions;
@@ -76,7 +77,7 @@ public async Task ShouldWorkInRealLifeWithOptions()
7677
{
7778
var response = await page.GoToAsync(
7879
"https://www.google.com",
79-
new NavigationOptions()
80+
new NavigationOptions
8081
{
8182
Timeout = 10000,
8283
WaitUntil = new[] { WaitUntilNavigation.Networkidle0 }
@@ -288,20 +289,9 @@ public void ShouldDumpBrowserProcessStderr()
288289
{
289290
var dumpioTextToLog = "MAGIC_DUMPIO_TEST";
290291
var success = false;
291-
var process = new Process();
292-
293-
#if NETCOREAPP
294-
process.StartInfo.WorkingDirectory = GetDumpIOAppDirectory();
295-
process.StartInfo.FileName = "dotnet";
296-
process.StartInfo.Arguments = $"PuppeteerSharp.Tests.DumpIO.dll {dumpioTextToLog} " +
297-
$"\"{new BrowserFetcher().RevisionInfo(BrowserFetcher.DefaultRevision).ExecutablePath}\"";
298-
#else
299-
process.StartInfo.FileName = Path.Combine(GetDumpIOAppDirectory(), "PuppeteerSharp.Tests.DumpIO.exe");
300-
process.StartInfo.Arguments = $"{dumpioTextToLog} " +
301-
$"\"{new BrowserFetcher().RevisionInfo(BrowserFetcher.DefaultRevision).ExecutablePath}\"";
302-
#endif
303-
process.StartInfo.UseShellExecute = false;
304-
process.StartInfo.RedirectStandardError = true;
292+
var process = GetTestAppProcess(
293+
"PuppeteerSharp.Tests.DumpIO",
294+
$"{dumpioTextToLog} \"{new BrowserFetcher().RevisionInfo(BrowserFetcher.DefaultRevision).ExecutablePath}\"");
305295

306296
process.ErrorDataReceived += (sender, e) =>
307297
{
@@ -314,28 +304,107 @@ public void ShouldDumpBrowserProcessStderr()
314304
Assert.True(success);
315305
}
316306

317-
private string GetDumpIOAppDirectory()
307+
[Fact]
308+
public async Task ShouldCloseTheBrowserWhenTheProcessCloses()
309+
{
310+
var process = GetTestAppProcess(
311+
"PuppeteerSharp.Tests.CloseMe",
312+
$"\"{new BrowserFetcher().RevisionInfo(BrowserFetcher.DefaultRevision).ExecutablePath}\"");
313+
314+
var webSocketTaskWrapper = new TaskCompletionSource<string>();
315+
var browserClosedTaskWrapper = new TaskCompletionSource<bool>();
316+
317+
process.StartInfo.UseShellExecute = false;
318+
process.StartInfo.RedirectStandardOutput = true;
319+
320+
process.OutputDataReceived += (sender, e) =>
321+
{
322+
if (!webSocketTaskWrapper.Task.IsCompleted)
323+
{
324+
webSocketTaskWrapper.SetResult(e.Data);
325+
}
326+
};
327+
328+
process.Start();
329+
process.BeginOutputReadLine();
330+
331+
var browser = await Puppeteer.ConnectAsync(new ConnectOptions
332+
{
333+
BrowserWSEndpoint = await webSocketTaskWrapper.Task
334+
});
335+
336+
browser.Disconnected += (sender, e) =>
337+
{
338+
browserClosedTaskWrapper.SetResult(true);
339+
};
340+
341+
KillProcess(process.Id);
342+
343+
await browserClosedTaskWrapper.Task;
344+
Assert.True(process.HasExited);
345+
}
346+
347+
private Process GetTestAppProcess(string appName, string arguments)
348+
{
349+
var process = new Process();
350+
351+
#if NETCOREAPP
352+
process.StartInfo.WorkingDirectory = GetSubprocessWorkingDir(appName);
353+
process.StartInfo.FileName = "dotnet";
354+
process.StartInfo.Arguments = $"{appName}.dll {arguments}";
355+
#else
356+
process.StartInfo.FileName = Path.Combine(GetSubprocessWorkingDir(appName), $"{appName}.exe");
357+
process.StartInfo.Arguments = arguments;
358+
#endif
359+
process.StartInfo.UseShellExecute = false;
360+
process.StartInfo.RedirectStandardError = true;
361+
return process;
362+
}
363+
364+
private string GetSubprocessWorkingDir(string dir)
318365
{
319366
#if DEBUG
320367
var build = "Debug";
321368
#else
369+
322370
var build = "Release";
323371
#endif
324372
#if NETCOREAPP
325373
return Path.Combine(
326374
TestUtils.FindParentDirectory("lib"),
327-
"PuppeteerSharp.Tests.DumpIO",
375+
dir,
328376
"bin",
329377
build,
330378
"netcoreapp2.0");
331379
#else
332380
return Path.Combine(
333381
TestUtils.FindParentDirectory("lib"),
334-
"PuppeteerSharp.Tests.DumpIO",
382+
dir,
335383
"bin",
336384
build,
337385
"net471");
338386
#endif
339387
}
388+
389+
private void KillProcess(int pid)
390+
{
391+
var process = new Process();
392+
393+
//We need to kill the process tree manually
394+
//See: https://github.com/dotnet/corefx/issues/26234
395+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
396+
{
397+
process.StartInfo.FileName = "taskkill";
398+
process.StartInfo.Arguments = $"-pid {pid} -t -f";
399+
}
400+
else
401+
{
402+
process.StartInfo.FileName = "/bin/bash";
403+
process.StartInfo.Arguments = $"-c \"kill -s 9 {pid}\"";
404+
}
405+
406+
process.Start();
407+
process.WaitForExit();
408+
}
340409
}
341410
}

lib/PuppeteerSharp.sln

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
21
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 2012
4-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PuppeteerSharp", "PuppeteerSharp\PuppeteerSharp.csproj", "{19B9B1ED-AF6C-4DAF-8B73-401570111F88}"
2+
# Visual Studio 15
3+
VisualStudioVersion = 15.0.27703.2035
4+
MinimumVisualStudioVersion = 10.0.40219.1
5+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PuppeteerSharp", "PuppeteerSharp\PuppeteerSharp.csproj", "{19B9B1ED-AF6C-4DAF-8B73-401570111F88}"
56
EndProject
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PuppeteerSharp.Tests", "PuppeteerSharp.Tests\PuppeteerSharp.Tests.csproj", "{1682289E-5ED3-405F-8ABC-01A3ED58CBC6}"
7+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PuppeteerSharp.Tests", "PuppeteerSharp.Tests\PuppeteerSharp.Tests.csproj", "{1682289E-5ED3-405F-8ABC-01A3ED58CBC6}"
78
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PuppeteerSharp.TestServer", "PuppeteerSharp.TestServer\PuppeteerSharp.TestServer.csproj", "{0CC393AB-10C2-4CDB-8353-78924D3DD5D3}"
9+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PuppeteerSharp.TestServer", "PuppeteerSharp.TestServer\PuppeteerSharp.TestServer.csproj", "{0CC393AB-10C2-4CDB-8353-78924D3DD5D3}"
910
EndProject
10-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PuppeteerSharp.Tests.DumpIO", "PuppeteerSharp.Tests.DumpIO\PuppeteerSharp.Tests.DumpIO.csproj", "{B1892212-CEE3-4DC3-ADB8-04A2D9A081A0}"
11+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PuppeteerSharp.Tests.DumpIO", "PuppeteerSharp.Tests.DumpIO\PuppeteerSharp.Tests.DumpIO.csproj", "{B1892212-CEE3-4DC3-ADB8-04A2D9A081A0}"
12+
EndProject
13+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PuppeteerSharp.Tests.CloseMe", "PuppeteerSharp.Tests.CloseMe\PuppeteerSharp.Tests.CloseMe.csproj", "{B1B0358F-88A2-4038-9974-7850D906C76B}"
1114
EndProject
1215
Global
1316
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -31,6 +34,10 @@ Global
3134
{B1892212-CEE3-4DC3-ADB8-04A2D9A081A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
3235
{B1892212-CEE3-4DC3-ADB8-04A2D9A081A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
3336
{B1892212-CEE3-4DC3-ADB8-04A2D9A081A0}.Release|Any CPU.Build.0 = Release|Any CPU
37+
{B1B0358F-88A2-4038-9974-7850D906C76B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38+
{B1B0358F-88A2-4038-9974-7850D906C76B}.Debug|Any CPU.Build.0 = Debug|Any CPU
39+
{B1B0358F-88A2-4038-9974-7850D906C76B}.Release|Any CPU.ActiveCfg = Release|Any CPU
40+
{B1B0358F-88A2-4038-9974-7850D906C76B}.Release|Any CPU.Build.0 = Release|Any CPU
3441
EndGlobalSection
3542
GlobalSection(SolutionProperties) = preSolution
3643
HideSolutionNode = FALSE

lib/PuppeteerSharp/Browser.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,10 @@ public async Task CloseAsync()
221221

222222
#region Private Methods
223223

224-
internal void ChangeTarget(Target target)
224+
internal void ChangeTarget(Target target) => TargetChanged?.Invoke(this, new TargetChangedArgs
225225
{
226-
TargetChanged?.Invoke(this, new TargetChangedArgs
227-
{
228-
Target = target
229-
});
230-
}
226+
Target = target
227+
});
231228

232229
private async void Connect_MessageReceived(object sender, MessageEventArgs e)
233230
{
@@ -318,15 +315,11 @@ internal static async Task<Browser> CreateAsync(
318315

319316
return browser;
320317
}
321-
322318
#endregion
323319

324320
#region IDisposable
325321
/// <inheritdoc />
326-
public void Dispose()
327-
{
328-
CloseAsync().GetAwaiter().GetResult();
329-
}
322+
public void Dispose() => CloseAsync().GetAwaiter().GetResult();
330323
#endregion
331324
}
332325
}

lib/PuppeteerSharp/Connection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ internal async Task<dynamic> SendAsync(string method, dynamic args = null)
104104

105105
var encoded = Encoding.UTF8.GetBytes(message);
106106
var buffer = new ArraySegment<byte>(encoded, 0, encoded.Length);
107-
await _socketQueue.Enqueue(() => WebSocket.SendAsync(buffer, WebSocketMessageType.Text, true, default(CancellationToken)));
107+
await _socketQueue.Enqueue(() => WebSocket.SendAsync(buffer, WebSocketMessageType.Text, true, default));
108108

109109
if (method == CloseMessage)
110110
{
@@ -279,7 +279,7 @@ internal static async Task<Connection> Create(string url, int delay = 0, int kee
279279
{
280280
var ws = new ClientWebSocket();
281281
ws.Options.KeepAliveInterval = new TimeSpan(0, 0, keepAliveInterval);
282-
await ws.ConnectAsync(new Uri(url), default(CancellationToken)).ConfigureAwait(false);
282+
await ws.ConnectAsync(new Uri(url), default).ConfigureAwait(false);
283283
return new Connection(url, delay, ws, loggerFactory);
284284
}
285285

lib/PuppeteerSharp/NetworkManager.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,11 @@ internal async Task SetOfflineModeAsync(bool value)
8282
}
8383
}
8484

85-
internal async Task SetUserAgentAsync(string userAgent)
86-
{
87-
await _client.SendAsync("Network.setUserAgentOverride", new Dictionary<string, object>
85+
internal Task SetUserAgentAsync(string userAgent)
86+
=> _client.SendAsync("Network.setUserAgentOverride", new Dictionary<string, object>
8887
{
8988
{ "userAgent", userAgent }
9089
});
91-
}
9290

9391
internal async Task SetRequestInterceptionAsync(bool value)
9492
{
@@ -258,7 +256,7 @@ private async Task OnRequestInterceptedAsync(RequestInterceptedResponse e)
258256
return;
259257
}
260258

261-
string requestHash = e.Request.Hash;
259+
var requestHash = e.Request.Hash;
262260
var requestId = _requestHashToRequestIds.FirstValue(requestHash);
263261
if (requestId != null)
264262
{
@@ -388,7 +386,7 @@ private void OnRequestWillBeSent(RequestWillBeSentResponse e)
388386
{
389387
return;
390388
}
391-
string requestHash = e.Request.Hash;
389+
var requestHash = e.Request.Hash;
392390
var interceptionId = _requestHashToInterceptionIds.FirstValue(requestHash);
393391
if (interceptionId != null && _interceptionIdToRequest.TryGetValue(interceptionId, out var request))
394392
{

lib/PuppeteerSharp/Page.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -981,17 +981,17 @@ public async Task<byte[]> ScreenshotDataAsync(ScreenshotOptions options)
981981
/// Closes the page.
982982
/// </summary>
983983
/// <returns>Task.</returns>
984-
public async Task CloseAsync()
984+
public Task CloseAsync()
985985
{
986986
if (!(Client?.Connection?.IsClosed ?? true))
987987
{
988-
await Client.Connection.SendAsync("Target.closeTarget", new
988+
return Client.Connection.SendAsync("Target.closeTarget", new
989989
{
990990
targetId = Target.TargetId
991-
});
992-
993-
await Target.CloseTask;
991+
}).ContinueWith((task) => Target.CloseTask);
994992
}
993+
994+
return Task.CompletedTask;
995995
}
996996

997997
/// <summary>

lib/PuppeteerSharp/Target.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ internal Target(TargetInfo targetInfo, Func<Task<CDPSession>> sessionFactory, Br
5858
public string TargetId => _targetInfo.TargetId;
5959
internal Task<bool> InitializedTask => InitilizedTaskWrapper.Task;
6060
internal TaskCompletionSource<bool> InitilizedTaskWrapper { get; }
61-
internal Task<bool> CloseTask => CloseTaskWrapper.Task;
61+
internal Task CloseTask => CloseTaskWrapper.Task;
6262
internal TaskCompletionSource<bool> CloseTaskWrapper { get; }
6363
#endregion
6464

0 commit comments

Comments
 (0)