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
50 changes: 50 additions & 0 deletions lib/PuppeteerSharp.Tests/BrowserTests/AddRemoveScreenTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Threading.Tasks;
using NUnit.Framework;
using PuppeteerSharp.Nunit;

namespace PuppeteerSharp.Tests.BrowserTests
{
public class AddRemoveScreenTests : PuppeteerBrowserBaseTest
{
[Test, PuppeteerTest("browser.spec", "Browser specs Browser.add|removeScreen", "should add and remove a screen")]
public async Task ShouldAddAndRemoveAScreen()
{
var screenInfo = await Browser.AddScreenAsync(new AddScreenParams
{
Left = 800,
Top = 0,
Width = 1600,
Height = 1200,
ColorDepth = 32,
WorkAreaInsets = new WorkAreaInsets { Bottom = 80 },
Label = "secondary",
});

Assert.That(screenInfo.AvailHeight, Is.EqualTo(1120));
Assert.That(screenInfo.AvailLeft, Is.EqualTo(800));
Assert.That(screenInfo.AvailTop, Is.EqualTo(0));
Assert.That(screenInfo.AvailWidth, Is.EqualTo(1600));
Assert.That(screenInfo.ColorDepth, Is.EqualTo(32));
Assert.That(screenInfo.DevicePixelRatio, Is.EqualTo(1));
Assert.That(screenInfo.Height, Is.EqualTo(1200));
Assert.That(screenInfo.Id, Is.EqualTo("2"));
Assert.That(screenInfo.IsExtended, Is.True);
Assert.That(screenInfo.IsInternal, Is.False);
Assert.That(screenInfo.IsPrimary, Is.False);
Assert.That(screenInfo.Label, Is.EqualTo("secondary"));
Assert.That(screenInfo.Left, Is.EqualTo(800));
Assert.That(screenInfo.Orientation.Angle, Is.EqualTo(0));
Assert.That(screenInfo.Orientation.Type, Is.EqualTo("landscapePrimary"));
Assert.That(screenInfo.Top, Is.EqualTo(0));
Assert.That(screenInfo.Width, Is.EqualTo(1600));

var screens = await Browser.ScreensAsync();
Assert.That(screens, Has.Length.EqualTo(2));

await Browser.RemoveScreenAsync(screenInfo.Id);

screens = await Browser.ScreensAsync();
Assert.That(screens, Has.Length.EqualTo(1));
}
}
}
33 changes: 33 additions & 0 deletions lib/PuppeteerSharp.Tests/BrowserTests/ScreensTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Threading.Tasks;
using NUnit.Framework;
using PuppeteerSharp.Nunit;

namespace PuppeteerSharp.Tests.BrowserTests
{
public class ScreensTests : PuppeteerBrowserBaseTest
{
[Test, PuppeteerTest("browser.spec", "Browser specs Browser.screens", "should return default screen info")]
public async Task ShouldReturnDefaultScreenInfo()
{
var screenInfos = await Browser.ScreensAsync();
Assert.That(screenInfos, Has.Length.EqualTo(1));
Assert.That(screenInfos[0].AvailHeight, Is.EqualTo(600));
Assert.That(screenInfos[0].AvailLeft, Is.EqualTo(0));
Assert.That(screenInfos[0].AvailTop, Is.EqualTo(0));
Assert.That(screenInfos[0].AvailWidth, Is.EqualTo(800));
Assert.That(screenInfos[0].ColorDepth, Is.EqualTo(24));
Assert.That(screenInfos[0].DevicePixelRatio, Is.EqualTo(1));
Assert.That(screenInfos[0].Height, Is.EqualTo(600));
Assert.That(screenInfos[0].Id, Is.EqualTo("1"));
Assert.That(screenInfos[0].IsExtended, Is.False);
Assert.That(screenInfos[0].IsInternal, Is.False);
Assert.That(screenInfos[0].IsPrimary, Is.True);
Assert.That(screenInfos[0].Label, Is.EqualTo(""));
Assert.That(screenInfos[0].Left, Is.EqualTo(0));
Assert.That(screenInfos[0].Orientation.Angle, Is.EqualTo(0));
Assert.That(screenInfos[0].Orientation.Type, Is.EqualTo("landscapePrimary"));
Assert.That(screenInfos[0].Top, Is.EqualTo(0));
Assert.That(screenInfos[0].Width, Is.EqualTo(800));
}
}
}
58 changes: 58 additions & 0 deletions lib/PuppeteerSharp/AddScreenParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace PuppeteerSharp
{
/// <summary>
/// Parameters for adding a new screen.
/// </summary>
public class AddScreenParams
{
/// <summary>
/// Gets or sets the left position of the screen.
/// </summary>
public int Left { get; set; }

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

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

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

/// <summary>
/// Gets or sets the work area insets.
/// </summary>
public WorkAreaInsets WorkAreaInsets { get; set; }

/// <summary>
/// Gets or sets the device pixel ratio.
/// </summary>
public double? DevicePixelRatio { get; set; }

/// <summary>
/// Gets or sets the rotation in degrees.
/// </summary>
public int? Rotation { get; set; }

/// <summary>
/// Gets or sets the color depth.
/// </summary>
public int? ColorDepth { get; set; }

/// <summary>
/// Gets or sets the screen label.
/// </summary>
public string Label { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the screen is internal.
/// </summary>
public bool? IsInternal { get; set; }
}
}
12 changes: 12 additions & 0 deletions lib/PuppeteerSharp/Bidi/BidiBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,18 @@ public override async Task CloseAsync()
/// <inheritdoc />
public override Task<IPage> NewPageAsync() => DefaultContext.NewPageAsync();

/// <inheritdoc/>
public override Task<ScreenInfo[]> ScreensAsync()
=> throw new NotSupportedException("Screens is not supported in WebDriver BiDi.");

/// <inheritdoc/>
public override Task<ScreenInfo> AddScreenAsync(AddScreenParams @params)
=> throw new NotSupportedException("AddScreen is not supported in WebDriver BiDi.");

/// <inheritdoc/>
public override Task RemoveScreenAsync(string screenId)
=> throw new NotSupportedException("RemoveScreen is not supported in WebDriver BiDi.");

/// <inheritdoc />
public override ITarget[] Targets()
=>
Expand Down
9 changes: 9 additions & 0 deletions lib/PuppeteerSharp/Browser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ public abstract class Browser : IBrowser
/// <inheritdoc/>
public abstract IBrowserContext[] BrowserContexts();

/// <inheritdoc/>
public abstract Task<ScreenInfo[]> ScreensAsync();

/// <inheritdoc/>
public abstract Task<ScreenInfo> AddScreenAsync(AddScreenParams @params);

/// <inheritdoc/>
public abstract Task RemoveScreenAsync(string screenId);

/// <inheritdoc/>
public async Task<IPage[]> PagesAsync()
=> (await Task.WhenAll(
Expand Down
20 changes: 20 additions & 0 deletions lib/PuppeteerSharp/Cdp/CdpBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,26 @@ public override async Task<IBrowserContext> CreateBrowserContextAsync(BrowserCon
/// <inheritdoc/>
public override IBrowserContext[] BrowserContexts() => [DefaultContext, .. _contexts.Values];

/// <inheritdoc/>
public override async Task<ScreenInfo[]> ScreensAsync()
{
var response = await Connection.SendAsync<EmulationGetScreenInfosResponse>("Emulation.getScreenInfos").ConfigureAwait(false);
return response.ScreenInfos;
}

/// <inheritdoc/>
public override async Task<ScreenInfo> AddScreenAsync(AddScreenParams @params)
{
var response = await Connection.SendAsync<EmulationAddScreenResponse>("Emulation.addScreen", @params).ConfigureAwait(false);
return response.ScreenInfo;
}

/// <inheritdoc/>
public override async Task RemoveScreenAsync(string screenId)
{
await Connection.SendAsync("Emulation.removeScreen", new EmulationRemoveScreenRequest { ScreenId = screenId }).ConfigureAwait(false);
}

internal static async Task<CdpBrowser> CreateAsync(
SupportedBrowser browserToCreate,
Connection connection,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace PuppeteerSharp.Cdp.Messaging
{
internal class EmulationAddScreenResponse
{
public ScreenInfo ScreenInfo { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace PuppeteerSharp.Cdp.Messaging
{
internal class EmulationGetScreenInfosResponse
{
public ScreenInfo[] ScreenInfos { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace PuppeteerSharp.Cdp.Messaging
{
internal class EmulationRemoveScreenRequest
{
public string ScreenId { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ namespace PuppeteerSharp.Helpers.Json;
[JsonSerializable(typeof(EmulationSetDeviceMetricsOverrideRequest))]
[JsonSerializable(typeof(EmulationSetEmulatedMediaFeatureRequest))]
[JsonSerializable(typeof(EmulationSetEmulatedMediaTypeRequest))]
[JsonSerializable(typeof(EmulationAddScreenResponse))]
[JsonSerializable(typeof(EmulationGetScreenInfosResponse))]
[JsonSerializable(typeof(EmulationRemoveScreenRequest))]
[JsonSerializable(typeof(EmulationSetEmulatedVisionDeficiencyRequest))]
[JsonSerializable(typeof(EmulationSetIdleOverrideRequest))]
[JsonSerializable(typeof(EmulationSetScriptExecutionDisabledRequest))]
Expand Down Expand Up @@ -186,6 +189,11 @@ namespace PuppeteerSharp.Helpers.Json;
[JsonSerializable(typeof(RuntimeQueryObjectsResponse))]
[JsonSerializable(typeof(RuntimeReleaseObjectRequest))]
[JsonSerializable(typeof(RuntimeRemoveBindingRequest))]
[JsonSerializable(typeof(ScreenInfo))]
[JsonSerializable(typeof(ScreenInfo[]))]
[JsonSerializable(typeof(ScreenOrientationInfo))]
[JsonSerializable(typeof(AddScreenParams))]
[JsonSerializable(typeof(WorkAreaInsets))]
[JsonSerializable(typeof(SecurityHandleCertificateErrorResponse))]
[JsonSerializable(typeof(SecuritySetIgnoreCertificateErrorsRequest))]
[JsonSerializable(typeof(SecuritySetOverrideCertificateErrorsRequest))]
Expand Down
22 changes: 22 additions & 0 deletions lib/PuppeteerSharp/IBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,5 +229,27 @@ public interface IBrowser : IDisposable, IAsyncDisposable
/// Clears all registered handlers.
/// </summary>
void ClearCustomQueryHandlers();

/// <summary>
/// Gets a list of <see cref="ScreenInfo"/> objects.
/// </summary>
/// <returns>A task that resolves to an array of screen information objects.</returns>
Task<ScreenInfo[]> ScreensAsync();

/// <summary>
/// Adds a new screen with specified parameters and returns a <see cref="ScreenInfo"/> object, including the new screen's ID.
/// </summary>
/// <param name="params">The parameters for the new screen.</param>
/// <returns>A task that resolves to the added screen information.</returns>
/// <remarks>Only supported in headless mode.</remarks>
Task<ScreenInfo> AddScreenAsync(AddScreenParams @params);

/// <summary>
/// Removes the screen associated with the given screen ID, unless it is the primary screen.
/// </summary>
/// <param name="screenId">The ID of the screen to remove.</param>
/// <returns>A task that completes when the screen is removed.</returns>
/// <remarks>Only supported in headless mode. Fails if the primary screen ID is specified.</remarks>
Task RemoveScreenAsync(string screenId);
}
}
88 changes: 88 additions & 0 deletions lib/PuppeteerSharp/ScreenInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
namespace PuppeteerSharp
{
/// <summary>
/// Contains information about a screen.
/// </summary>
public class ScreenInfo
{
/// <summary>
/// Gets or sets the left position of the screen.
/// </summary>
public int Left { get; set; }

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

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

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

/// <summary>
/// Gets or sets the available left position.
/// </summary>
public int AvailLeft { get; set; }

/// <summary>
/// Gets or sets the available top position.
/// </summary>
public int AvailTop { get; set; }

/// <summary>
/// Gets or sets the available width.
/// </summary>
public int AvailWidth { get; set; }

/// <summary>
/// Gets or sets the available height.
/// </summary>
public int AvailHeight { get; set; }

/// <summary>
/// Gets or sets the device pixel ratio.
/// </summary>
public double DevicePixelRatio { get; set; }

/// <summary>
/// Gets or sets the color depth.
/// </summary>
public int ColorDepth { get; set; }

/// <summary>
/// Gets or sets the screen orientation.
/// </summary>
public ScreenOrientationInfo Orientation { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the screen is extended.
/// </summary>
public bool IsExtended { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the screen is internal.
/// </summary>
public bool IsInternal { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the screen is the primary screen.
/// </summary>
public bool IsPrimary { get; set; }

/// <summary>
/// Gets or sets the screen label.
/// </summary>
public string Label { get; set; }

/// <summary>
/// Gets or sets the screen ID.
/// </summary>
public string Id { get; set; }
}
}
18 changes: 18 additions & 0 deletions lib/PuppeteerSharp/ScreenOrientationInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace PuppeteerSharp
{
/// <summary>
/// Represents screen orientation information.
/// </summary>
public class ScreenOrientationInfo
{
/// <summary>
/// Gets or sets the orientation angle.
/// </summary>
public int Angle { get; set; }

/// <summary>
/// Gets or sets the orientation type.
/// </summary>
public string Type { get; set; }
}
}
Loading
Loading