Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/PuppeteerSharp.Tests/PageTests/NewPageTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Threading.Tasks;
using NUnit.Framework;
using PuppeteerSharp.Nunit;

namespace PuppeteerSharp.Tests.PageTests
{
public class NewPageTests : PuppeteerPageBaseTest
{
[Test, PuppeteerTest("page.spec", "Page Page.newPage", "should create a background page")]
public async Task ShouldCreateABackgroundPage()
{
var page = await Context.NewPageAsync(new CreatePageOptions { Background = true });

var visibilityState = await page.EvaluateExpressionAsync<string>("document.visibilityState");
Assert.That(visibilityState, Is.EqualTo("hidden"));
}
}
}
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/Bidi/BidiBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public override async Task CloseAsync()
}

/// <inheritdoc />
public override Task<IPage> NewPageAsync() => DefaultContext.NewPageAsync();
public override Task<IPage> NewPageAsync(CreatePageOptions options = null) => DefaultContext.NewPageAsync(options);

/// <inheritdoc/>
public override Task<ScreenInfo[]> ScreensAsync()
Expand Down
10 changes: 8 additions & 2 deletions lib/PuppeteerSharp/Bidi/BidiBrowserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,15 @@ public override async Task ClearPermissionOverridesAsync()
public override Task<IPage[]> PagesAsync() => Task.FromResult(_pages.Values.Cast<IPage>().ToArray());

/// <inheritdoc />
public override async Task<IPage> NewPageAsync()
public override async Task<IPage> NewPageAsync(CreatePageOptions options = null)
{
var context = await UserContext.CreateBrowserContextAsync(WebDriverBiDi.BrowsingContext.CreateType.Tab).ConfigureAwait(false);
var type = options?.Type == "window"
? WebDriverBiDi.BrowsingContext.CreateType.Window
: WebDriverBiDi.BrowsingContext.CreateType.Tab;

var context = await UserContext.CreateBrowserContextAsync(
type,
background: options?.Background).ConfigureAwait(false);

if (!_pages.TryGetValue(context, out var page))
{
Expand Down
8 changes: 6 additions & 2 deletions lib/PuppeteerSharp/Bidi/Core/UserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,13 @@ public void Dispose()
GC.SuppressFinalize(this);
}

public async Task<BrowsingContext> CreateBrowserContextAsync(CreateType contextType)
public async Task<BrowsingContext> CreateBrowserContextAsync(CreateType contextType, bool? background = null)
{
var createParams = new CreateCommandParameters(contextType) { UserContextId = Id };
var createParams = new CreateCommandParameters(contextType)
{
UserContextId = Id,
IsCreatedInBackground = background,
};
var result = await Session.Driver.BrowsingContext.CreateAsync(createParams).ConfigureAwait(false);

if (_browsingContexts.TryGetValue(result.BrowsingContextId, out var browsingContext))
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/Browser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public abstract class Browser : IBrowser
internal abstract ProtocolType Protocol { get; }

/// <inheritdoc/>
public abstract Task<IPage> NewPageAsync();
public abstract Task<IPage> NewPageAsync(CreatePageOptions options = null);

/// <inheritdoc/>
public abstract ITarget[] Targets();
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/BrowserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public Task<ITarget> WaitForTargetAsync(Func<ITarget, bool> predicate, WaitForOp
public abstract Task<IPage[]> PagesAsync();

/// <inheritdoc/>
public abstract Task<IPage> NewPageAsync();
public abstract Task<IPage> NewPageAsync(CreatePageOptions options = null);

/// <inheritdoc/>
public abstract Task CloseAsync();
Expand Down
16 changes: 14 additions & 2 deletions lib/PuppeteerSharp/Cdp/CdpBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public override bool IsClosed
internal override ProtocolType Protocol => ProtocolType.Cdp;

/// <inheritdoc/>
public override Task<IPage> NewPageAsync() => DefaultContext.NewPageAsync();
public override Task<IPage> NewPageAsync(CreatePageOptions options = null) => DefaultContext.NewPageAsync(options);

/// <inheritdoc/>
public override ITarget[] Targets()
Expand Down Expand Up @@ -205,11 +205,23 @@ internal static async Task<CdpBrowser> CreateAsync(
}
}

internal async Task<IPage> CreatePageInContextAsync(string contextId)
internal async Task<IPage> CreatePageInContextAsync(string contextId, CreatePageOptions options = null)
{
var hasTargets = Array.Exists(Targets(), t => t.BrowserContext.Id == contextId);
var windowBounds = options?.Type == "window" ? options.WindowBounds : null;

var createTargetRequest = new TargetCreateTargetRequest
{
Url = "about:blank",
Left = windowBounds?.Left,
Top = windowBounds?.Top,
Width = windowBounds?.Width,
Height = windowBounds?.Height,
WindowState = windowBounds?.WindowState,

// Works around crbug.com/454825274.
NewWindow = hasTargets && options?.Type == "window" ? true : null,
Background = options?.Background,
};

if (contextId != null)
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/Cdp/CdpBrowserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public override async Task<IPage[]> PagesAsync()
.Where(p => p != null).ToArray();

/// <inheritdoc/>
public override Task<IPage> NewPageAsync() => _browser.CreatePageInContextAsync(Id);
public override Task<IPage> NewPageAsync(CreatePageOptions options = null) => _browser.CreatePageInContextAsync(Id, options);

/// <inheritdoc/>
public override Task CloseAsync()
Expand Down
23 changes: 23 additions & 0 deletions lib/PuppeteerSharp/Cdp/Messaging/TargetCreateTargetRequest.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,32 @@
using System.Text.Json.Serialization;

namespace PuppeteerSharp.Cdp.Messaging
{
internal class TargetCreateTargetRequest
{
public string Url { get; set; }

public object BrowserContextId { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Left { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Top { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Width { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Height { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public WindowState? WindowState { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? NewWindow { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? Background { get; set; }
}
}
25 changes: 25 additions & 0 deletions lib/PuppeteerSharp/CreatePageOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace PuppeteerSharp
{
/// <summary>
/// Options for creating a new page.
/// </summary>
public class CreatePageOptions
{
/// <summary>
/// Gets or sets the type of page to create.
/// Use <c>"tab"</c> (default) or <c>"window"</c>.
/// </summary>
public string Type { get; set; }

/// <summary>
/// Gets or sets the window bounds when <see cref="Type"/> is <c>"window"</c>.
/// </summary>
public WindowBounds WindowBounds { get; set; }

/// <summary>
/// Gets or sets a value indicating whether to create the page in the background.
/// </summary>
/// <value><c>false</c> by default.</value>
public bool? Background { get; set; }
}
}
3 changes: 2 additions & 1 deletion lib/PuppeteerSharp/IBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,9 @@ public interface IBrowser : IDisposable, IAsyncDisposable
/// <summary>
/// Creates a new page.
/// </summary>
/// <param name="options">Options for creating the page.</param>
/// <returns>Task which resolves to a new <see cref="IPage"/> object.</returns>
Task<IPage> NewPageAsync();
Task<IPage> NewPageAsync(CreatePageOptions options = null);

/// <summary>
/// Returns a Task which resolves to an array of all open pages.
Expand Down
3 changes: 2 additions & 1 deletion lib/PuppeteerSharp/IBrowserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ public interface IBrowserContext : IDisposable, IAsyncDisposable
/// <summary>
/// Creates a new page.
/// </summary>
/// <param name="options">Options for creating the page.</param>
/// <returns>Task which resolves to a new <see cref="IPage"/> object.</returns>
Task<IPage> NewPageAsync();
Task<IPage> NewPageAsync(CreatePageOptions options = null);

/// <summary>
/// Overrides the browser context permissions.
Expand Down
33 changes: 33 additions & 0 deletions lib/PuppeteerSharp/WindowBounds.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace PuppeteerSharp
{
/// <summary>
/// Bounds for a browser window.
/// </summary>
public class WindowBounds
{
/// <summary>
/// Gets or sets the left position of the window.
/// </summary>
public int? Left { get; set; }

/// <summary>
/// Gets or sets the top position of the window.
/// </summary>
public int? Top { get; set; }

/// <summary>
/// Gets or sets the width of the window.
/// </summary>
public int? Width { get; set; }

/// <summary>
/// Gets or sets the height of the window.
/// </summary>
public int? Height { get; set; }

/// <summary>
/// Gets or sets the window state.
/// </summary>
public WindowState? WindowState { get; set; }
}
}
37 changes: 37 additions & 0 deletions lib/PuppeteerSharp/WindowState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using PuppeteerSharp.Helpers.Json;

namespace PuppeteerSharp
{
/// <summary>
/// Window state for <see cref="WindowBounds"/>.
/// </summary>
[JsonConverter(typeof(JsonStringEnumMemberConverter<WindowState>))]
public enum WindowState
{
/// <summary>
/// Normal window state.
/// </summary>
[EnumMember(Value = "normal")]
Normal,

/// <summary>
/// Minimized window state.
/// </summary>
[EnumMember(Value = "minimized")]
Minimized,

/// <summary>
/// Maximized window state.
/// </summary>
[EnumMember(Value = "maximized")]
Maximized,

/// <summary>
/// Fullscreen window state.
/// </summary>
[EnumMember(Value = "fullscreen")]
Fullscreen,
}
}
Loading