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

More robust chrome process clean-up (take 2) #585

Merged
merged 10 commits into from
Sep 6, 2018
4 changes: 3 additions & 1 deletion lib/PuppeteerSharp.Tests/FrameTests/FrameManagementTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ public FrameManagementTests(ITestOutputHelper output) : base(output)
public async Task ShouldHandleNestedFrames()
{
await Page.GoToAsync(TestConstants.ServerUrl + "/frames/nested-frames.html");
Assert.Equal(TestConstants.NestedFramesDumpResult, FrameUtils.DumpFrames(Page.MainFrame));
Assert.Equal(
TestUtils.CompressText(TestConstants.NestedFramesDumpResult),
TestUtils.CompressText(FrameUtils.DumpFrames(Page.MainFrame)));
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp.Tests/Issues/Issue0128.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class Issue0128
[Fact]
public async Task LauncherShouldFailGracefully()
{
await Assert.ThrowsAsync<ChromeProcessException>(async () =>
await Assert.ThrowsAsync<ChromiumProcessException>(async () =>
{
var options = TestConstants.DefaultBrowserOptions();
options.Args = new[] { "-remote-debugging-port=-2" };
Expand Down
15 changes: 5 additions & 10 deletions lib/PuppeteerSharp.Tests/PuppeteerBrowserBaseTest.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System;
using System.IO;
using System.IO;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace PuppeteerSharp.Tests
{
public class PuppeteerBrowserBaseTest : PuppeteerBaseTest, IDisposable
public class PuppeteerBrowserBaseTest : PuppeteerBaseTest, IAsyncLifetime
{
protected Browser Browser { get; set; }

Expand All @@ -18,16 +18,11 @@ public PuppeteerBrowserBaseTest(ITestOutputHelper output) : base(output)
{
dirInfo.Create();
}

InitializeAsync().GetAwaiter().GetResult();
}

protected virtual async Task InitializeAsync()
{
public virtual async Task InitializeAsync() =>
Browser = await Puppeteer.LaunchAsync(TestConstants.DefaultBrowserOptions(), TestConstants.LoggerFactory);
}

protected virtual async Task DisposeAsync() => await Browser.CloseAsync();
public void Dispose() => DisposeAsync().GetAwaiter().GetResult();
public virtual async Task DisposeAsync() => await Browser.CloseAsync();
}
}
4 changes: 2 additions & 2 deletions lib/PuppeteerSharp.Tests/PuppeteerPageBaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ public PuppeteerPageBaseTest(ITestOutputHelper output) : base(output)

protected Page Page { get; set; }

protected override async Task InitializeAsync()
public override async Task InitializeAsync()
{
await base.InitializeAsync();
Page = await Browser.NewPageAsync();
}

protected override async Task DisposeAsync()
public override async Task DisposeAsync()
{
await Page.CloseAsync();
await base.DisposeAsync();
Expand Down
53 changes: 35 additions & 18 deletions lib/PuppeteerSharp.Tests/PuppeteerTests/BrowserFetcherTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@ namespace PuppeteerSharp.Tests.PuppeteerTests
[Collection("PuppeteerLoaderFixture collection")]
public class BrowserFetcherTests : PuppeteerBaseTest
{
public BrowserFetcherTests(ITestOutputHelper output) : base(output) { }
private readonly string _downloadsFolder;

public BrowserFetcherTests(ITestOutputHelper output) : base(output)
{
_downloadsFolder = Path.Combine(Directory.GetCurrentDirectory(), ".test-chromium");
EnsureDownloadsFolderIsDeleted();
}

[Fact]
public async Task ShouldDownloadAndExtractLinuxBinary()
{
var downloadsFolder = Path.Combine(Directory.GetCurrentDirectory(), ".test-chromium");
var browserFetcher = Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions
{
Platform = Platform.Linux,
Path = downloadsFolder,
Path = _downloadsFolder,
Host = TestConstants.ServerUrl
});
var revisionInfo = browserFetcher.RevisionInfo(123456);
Expand All @@ -29,22 +34,34 @@ public async Task ShouldDownloadAndExtractLinuxBinary()
Assert.False(await browserFetcher.CanDownloadAsync(100000));
Assert.True(await browserFetcher.CanDownloadAsync(123456));

revisionInfo = await browserFetcher.DownloadAsync(123456);
Assert.True(revisionInfo.Local);
Assert.Equal("LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath));
Assert.Equal(new[] { 123456 }, browserFetcher.LocalRevisions());
browserFetcher.Remove(123456);
Assert.Empty(browserFetcher.LocalRevisions());

//Download should return data from a downloaded version
//This section is not in the Puppeteer test.
await browserFetcher.DownloadAsync(123456);
Server.Reset();
revisionInfo = await browserFetcher.DownloadAsync(123456);
Assert.True(revisionInfo.Local);
Assert.Equal("LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath));
try
{
revisionInfo = await browserFetcher.DownloadAsync(123456);
Assert.True(revisionInfo.Local);
Assert.Equal("LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath));
Assert.Equal(new[] {123456}, browserFetcher.LocalRevisions());
browserFetcher.Remove(123456);
Assert.Empty(browserFetcher.LocalRevisions());

new DirectoryInfo(downloadsFolder).Delete(true);
//Download should return data from a downloaded version
//This section is not in the Puppeteer test.
await browserFetcher.DownloadAsync(123456);
Server.Reset();
revisionInfo = await browserFetcher.DownloadAsync(123456);
Assert.True(revisionInfo.Local);
Assert.Equal("LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath));
}
finally
{
EnsureDownloadsFolderIsDeleted();
}
}
private void EnsureDownloadsFolderIsDeleted()
{
if (Directory.Exists(_downloadsFolder))
{
Directory.Delete(_downloadsFolder, true);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public async Task ShouldBeAbleToReconnectToADisconnectedBrowser()
var restoredPage = pages.FirstOrDefault(x => x.Url == url);
Assert.NotNull(restoredPage);
var frameDump = FrameUtils.DumpFrames(restoredPage.MainFrame);
Assert.Equal(TestConstants.NestedFramesDumpResult, frameDump);
Assert.Equal(TestUtils.CompressText(TestConstants.NestedFramesDumpResult), TestUtils.CompressText(frameDump));
var response = await restoredPage.EvaluateExpressionAsync<int>("7 * 8");
Assert.Equal(56, response);
}
Expand Down
162 changes: 83 additions & 79 deletions lib/PuppeteerSharp.Tests/PuppeteerTests/PuppeteerLaunchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Net;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using PuppeteerSharp.Helpers;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -119,116 +120,118 @@ public async Task ShouldRejectIfExecutablePathIsInvalid()
[Fact]
public async Task UserDataDirOption()
{
var launcher = new Launcher(TestConstants.LoggerFactory);
var userDataDir = Launcher.GetTemporaryDirectory();
var options = TestConstants.DefaultBrowserOptions();
options.UserDataDir = userDataDir;

using (var browser = await launcher.LaunchAsync(options))
using (var userDataDir = new TempDirectory())
{
Assert.True(Directory.GetFiles(userDataDir).Length > 0);
await browser.CloseAsync();
Assert.True(Directory.GetFiles(userDataDir).Length > 0);
await launcher.TryDeleteUserDataDir();
var options = TestConstants.DefaultBrowserOptions();
options.UserDataDir = userDataDir.Path;

var launcher = new Launcher(TestConstants.LoggerFactory);
using (var browser = await launcher.LaunchAsync(options))
{
Assert.True(Directory.GetFiles(userDataDir.Path).Length > 0);
await browser.CloseAsync();
Assert.True(Directory.GetFiles(userDataDir.Path).Length > 0);
}
}
}

[Fact]
public async Task UserDataDirArgument()
{
var launcher = new Launcher(TestConstants.LoggerFactory);
var userDataDir = Launcher.GetTemporaryDirectory();
var options = TestConstants.DefaultBrowserOptions();
options.Args = options.Args.Concat(new[] { $"--user-data-dir=\"{userDataDir}\"" }).ToArray();

using (var browser = await launcher.LaunchAsync(options))
using (var userDataDir = new TempDirectory())
{
// Open a page to make sure its functional.
await browser.NewPageAsync();
Assert.True(Directory.GetFiles(userDataDir).Length > 0);
await browser.CloseAsync();
Assert.True(Directory.GetFiles(userDataDir).Length > 0);
await launcher.TryDeleteUserDataDir();
var launcher = new Launcher(TestConstants.LoggerFactory);
var options = TestConstants.DefaultBrowserOptions();
options.Args = options.Args.Concat(new[] {$"--user-data-dir=\"{userDataDir}\""}).ToArray();

using (var browser = await launcher.LaunchAsync(options))
{
// Open a page to make sure its functional.
await browser.NewPageAsync();
Assert.True(Directory.GetFiles(userDataDir.Path).Length > 0);
await browser.CloseAsync();
Assert.True(Directory.GetFiles(userDataDir.Path).Length > 0);
}
}
}

[Fact]
public async Task UserDataDirOptionShouldRestoreState()
{
var launcher = new Launcher(TestConstants.LoggerFactory);
var userDataDir = Launcher.GetTemporaryDirectory();
var options = TestConstants.DefaultBrowserOptions();
options.Args = options.Args.Concat(new[] { $"--user-data-dir=\"{userDataDir}\"" }).ToArray();

using (var browser = await launcher.LaunchAsync(options))
using (var userDataDir = new TempDirectory())
{
var page = await browser.NewPageAsync();
await page.GoToAsync(TestConstants.EmptyPage);
await page.EvaluateExpressionAsync("localStorage.hey = 'hello'");
}
var launcher = new Launcher(TestConstants.LoggerFactory);
var options = TestConstants.DefaultBrowserOptions();
options.Args = options.Args.Concat(new[] {$"--user-data-dir=\"{userDataDir}\""}).ToArray();

using (var browser2 = await Puppeteer.LaunchAsync(options, TestConstants.LoggerFactory))
{
var page2 = await browser2.NewPageAsync();
await page2.GoToAsync(TestConstants.EmptyPage);
Assert.Equal("hello", await page2.EvaluateExpressionAsync("localStorage.hey"));
}
using (var browser = await launcher.LaunchAsync(options))
{
var page = await browser.NewPageAsync();
await page.GoToAsync(TestConstants.EmptyPage);
await page.EvaluateExpressionAsync("localStorage.hey = 'hello'");
}

await launcher.TryDeleteUserDataDir();
using (var browser2 = await Puppeteer.LaunchAsync(options, TestConstants.LoggerFactory))
{
var page2 = await browser2.NewPageAsync();
await page2.GoToAsync(TestConstants.EmptyPage);
Assert.Equal("hello", await page2.EvaluateExpressionAsync("localStorage.hey"));
}
}
}

[Fact]
public async Task UserDataDirOptionShouldRestoreCookies()
{
var launcher = new Launcher(TestConstants.LoggerFactory);
var userDataDir = Launcher.GetTemporaryDirectory();
var options = TestConstants.DefaultBrowserOptions();
options.Args = options.Args.Concat(new[] { $"--user-data-dir=\"{userDataDir}\"" }).ToArray();

using (var browser = await launcher.LaunchAsync(options))
using (var userDataDir = new TempDirectory())
{
var page = await browser.NewPageAsync();
await page.GoToAsync(TestConstants.EmptyPage);
await page.EvaluateExpressionAsync(
"document.cookie = 'doSomethingOnlyOnce=true; expires=Fri, 31 Dec 9999 23:59:59 GMT'");
}
var launcher = new Launcher(TestConstants.LoggerFactory);
var options = TestConstants.DefaultBrowserOptions();
options.Args = options.Args.Concat(new[] {$"--user-data-dir=\"{userDataDir}\""}).ToArray();

using (var browser2 = await Puppeteer.LaunchAsync(options, TestConstants.LoggerFactory))
{
var page2 = await browser2.NewPageAsync();
await page2.GoToAsync(TestConstants.EmptyPage);
Assert.Equal("doSomethingOnlyOnce=true", await page2.EvaluateExpressionAsync("document.cookie"));
}
using (var browser = await launcher.LaunchAsync(options))
{
var page = await browser.NewPageAsync();
await page.GoToAsync(TestConstants.EmptyPage);
await page.EvaluateExpressionAsync(
"document.cookie = 'doSomethingOnlyOnce=true; expires=Fri, 31 Dec 9999 23:59:59 GMT'");
}

await launcher.TryDeleteUserDataDir();
using (var browser2 = await Puppeteer.LaunchAsync(options, TestConstants.LoggerFactory))
{
var page2 = await browser2.NewPageAsync();
await page2.GoToAsync(TestConstants.EmptyPage);
Assert.Equal("doSomethingOnlyOnce=true", await page2.EvaluateExpressionAsync("document.cookie"));
}
}
}

[Fact]
public async Task HeadlessShouldBeAbleToReadCookiesWrittenByHeadful()
{
var launcher = new Launcher(TestConstants.LoggerFactory);
var userDataDir = Launcher.GetTemporaryDirectory();
var options = TestConstants.DefaultBrowserOptions();
options.Args = options.Args.Concat(new[] { $"--user-data-dir=\"{userDataDir}\"" }).ToArray();
options.Headless = false;

using (var browser = await launcher.LaunchAsync(options))
using (var userDataDir = new TempDirectory())
{
var page = await browser.NewPageAsync();
await page.GoToAsync(TestConstants.EmptyPage);
await page.EvaluateExpressionAsync(
"document.cookie = 'foo=true; expires=Fri, 31 Dec 9999 23:59:59 GMT'");
}
var launcher = new Launcher(TestConstants.LoggerFactory);
var options = TestConstants.DefaultBrowserOptions();
options.Args = options.Args.Concat(new[] {$"--user-data-dir=\"{userDataDir}\""}).ToArray();
options.Headless = false;

options.Headless = true;
using (var browser2 = await Puppeteer.LaunchAsync(options, TestConstants.LoggerFactory))
{
var page2 = await browser2.NewPageAsync();
await page2.GoToAsync(TestConstants.EmptyPage);
Assert.Equal("foo=true", await page2.EvaluateExpressionAsync("document.cookie"));
}
using (var browser = await launcher.LaunchAsync(options))
{
var page = await browser.NewPageAsync();
await page.GoToAsync(TestConstants.EmptyPage);
await page.EvaluateExpressionAsync(
"document.cookie = 'foo=true; expires=Fri, 31 Dec 9999 23:59:59 GMT'");
}

await launcher.TryDeleteUserDataDir();
options.Headless = true;
using (var browser2 = await Puppeteer.LaunchAsync(options, TestConstants.LoggerFactory))
{
var page2 = await browser2.NewPageAsync();
await page2.GoToAsync(TestConstants.EmptyPage);
Assert.Equal("foo=true", await page2.EvaluateExpressionAsync("document.cookie"));
}
}
}

[Fact]
Expand Down Expand Up @@ -278,7 +281,7 @@ public async Task ChromeShouldBeClosed()

await browser.CloseAsync();

Assert.True(launcher.IsChromeClosed);
Assert.True(launcher.Process.HasExited);
}
}

Expand All @@ -295,7 +298,8 @@ public async Task ChromeShouldBeClosedOnDispose()
Assert.Equal(HttpStatusCode.OK, response.Status);
}

Assert.True(launcher.IsChromeClosed);
Assert.True(await launcher.Process.WaitForExitAsync(TimeSpan.FromSeconds(10)));
Assert.True(launcher.Process.HasExited);
}

[Fact]
Expand Down
Loading