diff --git a/lib/PuppeteerSharp.Tests/EmulationTests/EmulateMediaFeaturesTests.cs b/lib/PuppeteerSharp.Tests/EmulationTests/EmulateMediaFeaturesTests.cs index af18956bd..794d5a697 100644 --- a/lib/PuppeteerSharp.Tests/EmulationTests/EmulateMediaFeaturesTests.cs +++ b/lib/PuppeteerSharp.Tests/EmulationTests/EmulateMediaFeaturesTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using PuppeteerSharp.Media; using PuppeteerSharp.Tests.Attributes; using PuppeteerSharp.Xunit; using Xunit; diff --git a/lib/PuppeteerSharp.Tests/EmulationTests/PageEmulateCPUThrottlingTests.cs b/lib/PuppeteerSharp.Tests/EmulationTests/PageEmulateCPUThrottlingTests.cs new file mode 100644 index 000000000..8a41dfcb8 --- /dev/null +++ b/lib/PuppeteerSharp.Tests/EmulationTests/PageEmulateCPUThrottlingTests.cs @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using PuppeteerSharp.Tests.Attributes; +using PuppeteerSharp.Xunit; +using Xunit; +using Xunit.Abstractions; + +namespace PuppeteerSharp.Tests.EmulationTests +{ + [Collection(TestConstants.TestFixtureCollectionName)] + public class PageEmulateCPUThrottlingTests : PuppeteerPageBaseTest + { + public PageEmulateCPUThrottlingTests(ITestOutputHelper output) : base(output) + { + } + + [PuppeteerTest("emulation.spec.ts", "Page.emulateCPUThrottling", "should change the CPU throttling rate successfully")] + [SkipBrowserFact(skipFirefox: true)] + public async Task ShouldChangeTheCPUThrottlingRateSuccessfully() + { + await Page.EmulateCPUThrottlingAsync(100); + await Page.EmulateCPUThrottlingAsync(); + } + } +} diff --git a/lib/PuppeteerSharp.Tests/EmulationTests/EmulateNetworkConditions.cs b/lib/PuppeteerSharp.Tests/EmulationTests/PageEmulateNetworkConditionsTests.cs similarity index 85% rename from lib/PuppeteerSharp.Tests/EmulationTests/EmulateNetworkConditions.cs rename to lib/PuppeteerSharp.Tests/EmulationTests/PageEmulateNetworkConditionsTests.cs index ffcafe6be..d6a075815 100644 --- a/lib/PuppeteerSharp.Tests/EmulationTests/EmulateNetworkConditions.cs +++ b/lib/PuppeteerSharp.Tests/EmulationTests/PageEmulateNetworkConditionsTests.cs @@ -1,16 +1,15 @@ -using System.Net; using System.Threading.Tasks; using PuppeteerSharp.Tests.Attributes; using PuppeteerSharp.Xunit; using Xunit; using Xunit.Abstractions; -namespace PuppeteerSharp.Tests.PageTests +namespace PuppeteerSharp.Tests.EmulationTests { [Collection(TestConstants.TestFixtureCollectionName)] - public class EmulateNetworkConditionsTests : PuppeteerPageBaseTest + public class PageEmulateNetworkConditionsTests : PuppeteerPageBaseTest { - public EmulateNetworkConditionsTests(ITestOutputHelper output) : base(output) + public PageEmulateNetworkConditionsTests(ITestOutputHelper output) : base(output) { } diff --git a/lib/PuppeteerSharp.Tests/EmulationTests/PageEmulateVisionDeficiencyTests.cs b/lib/PuppeteerSharp.Tests/EmulationTests/PageEmulateVisionDeficiencyTests.cs new file mode 100644 index 000000000..56ce2c9f5 --- /dev/null +++ b/lib/PuppeteerSharp.Tests/EmulationTests/PageEmulateVisionDeficiencyTests.cs @@ -0,0 +1,52 @@ +using System.Threading.Tasks; +using PuppeteerSharp.Tests.Attributes; +using PuppeteerSharp.Xunit; +using Xunit; +using Xunit.Abstractions; + +namespace PuppeteerSharp.Tests.EmulationTests +{ + [Collection(TestConstants.TestFixtureCollectionName)] + public class PageEmulateVisionDeficiencyTests : PuppeteerPageBaseTest + { + public PageEmulateVisionDeficiencyTests(ITestOutputHelper output) : base(output) + { + } + + [PuppeteerTest("emulation.spec.ts", "Page.emulateVisionDeficiency", "should work")] + [SkipBrowserFact(skipFirefox: true)] + public async Task ShouldWork() + { + await Page.SetViewportAsync(new ViewPortOptions { Width = 500, Height = 500 }); + await Page.GoToAsync(TestConstants.ServerUrl + "/grid.html"); + + await Page.EmulateVisionDeficiencyAsync(VisionDeficiency.None); + var screenshot = await Page.ScreenshotDataAsync(); + Assert.True(ScreenshotHelper.PixelMatch("screenshot-sanity.png", screenshot)); + + await Page.EmulateVisionDeficiencyAsync(VisionDeficiency.Achromatopsia); + screenshot = await Page.ScreenshotDataAsync(); + Assert.True(ScreenshotHelper.PixelMatch("vision-deficiency-achromatopsia.png", screenshot)); + + await Page.EmulateVisionDeficiencyAsync(VisionDeficiency.BlurredVision); + screenshot = await Page.ScreenshotDataAsync(); + Assert.True(ScreenshotHelper.PixelMatch("vision-deficiency-blurredVision.png", screenshot)); + + await Page.EmulateVisionDeficiencyAsync(VisionDeficiency.Deuteranopia); + screenshot = await Page.ScreenshotDataAsync(); + Assert.True(ScreenshotHelper.PixelMatch("vision-deficiency-deuteranopia.png", screenshot)); + + await Page.EmulateVisionDeficiencyAsync(VisionDeficiency.Protanopia); + screenshot = await Page.ScreenshotDataAsync(); + Assert.True(ScreenshotHelper.PixelMatch("vision-deficiency-protanopia.png", screenshot)); + + await Page.EmulateVisionDeficiencyAsync(VisionDeficiency.Tritanopia); + screenshot = await Page.ScreenshotDataAsync(); + Assert.True(ScreenshotHelper.PixelMatch("vision-deficiency-tritanopia.png", screenshot)); + + await Page.EmulateVisionDeficiencyAsync(VisionDeficiency.None); + screenshot = await Page.ScreenshotDataAsync(); + Assert.True(ScreenshotHelper.PixelMatch("screenshot-sanity.png", screenshot)); + } + } +} diff --git a/lib/PuppeteerSharp.Tests/Screenshots/golden-chromium/test.png b/lib/PuppeteerSharp.Tests/Screenshots/golden-chromium/test.png new file mode 100644 index 000000000..873db9a07 Binary files /dev/null and b/lib/PuppeteerSharp.Tests/Screenshots/golden-chromium/test.png differ diff --git a/lib/PuppeteerSharp.Tests/WontImplementTests.cs b/lib/PuppeteerSharp.Tests/WontImplementTests.cs index 71fb973fb..411a924f4 100644 --- a/lib/PuppeteerSharp.Tests/WontImplementTests.cs +++ b/lib/PuppeteerSharp.Tests/WontImplementTests.cs @@ -37,6 +37,9 @@ public WontImplementTests(ITestOutputHelper output) : base(output) [PuppeteerTest("EventEmitter.spec.ts", "removeAllListeners", "removes every listener from all events by default")] [PuppeteerTest("EventEmitter.spec.ts", "removeAllListeners", "returns the emitter for chaining")] [PuppeteerTest("EventEmitter.spec.ts", "removeAllListeners", "can filter to remove only listeners for a given event name")] + [PuppeteerTest("emulation.spec.ts", "Page.emulateMediaType", "should throw in case of bad argument")] + [PuppeteerTest("emulation.spec.ts", "Page.emulateMediaFeatures", "should throw in case of bad argument")] + [PuppeteerTest("emulation.spec.ts", "Page.emulateVisionDeficiency", "should throw for invalid vision deficiencies")] [PuppeteerFact] public void TheseTesstWontBeImplemented() { diff --git a/lib/PuppeteerSharp/Messaging/EmulationSetCPUThrottlingRateRequest.cs b/lib/PuppeteerSharp/Messaging/EmulationSetCPUThrottlingRateRequest.cs new file mode 100644 index 000000000..5cfdeba1d --- /dev/null +++ b/lib/PuppeteerSharp/Messaging/EmulationSetCPUThrottlingRateRequest.cs @@ -0,0 +1,7 @@ +namespace PuppeteerSharp.Messaging +{ + internal class EmulationSetCPUThrottlingRateRequest + { + public decimal Rate{ get; set; } + } +} diff --git a/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedVisionDeficiencyRequest.cs b/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedVisionDeficiencyRequest.cs new file mode 100644 index 000000000..de0606c61 --- /dev/null +++ b/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedVisionDeficiencyRequest.cs @@ -0,0 +1,7 @@ +namespace PuppeteerSharp.Messaging +{ + internal class EmulationSetEmulatedVisionDeficiencyRequest + { + public VisionDeficiency Type { get; set; } + } +} diff --git a/lib/PuppeteerSharp/Page.cs b/lib/PuppeteerSharp/Page.cs index 494b07849..57fed1db8 100644 --- a/lib/PuppeteerSharp/Page.cs +++ b/lib/PuppeteerSharp/Page.cs @@ -1895,6 +1895,21 @@ public Task SetBurstModeOffAsync() /// A task that resolves when the message has been sent to Chromium. public Task BringToFrontAsync() => Client.SendAsync("Page.bringToFront"); + /// + /// Simulates the given vision deficiency on the page. + /// + /// + /// await Page.EmulateVisionDeficiencyAsync(VisionDeficiency.Achromatopsia); + /// await Page.ScreenshotAsync("Achromatopsia.png"); + /// + /// The type of deficiency to simulate, or to reset. + /// A task that resolves when the message has been sent to the browser. + public Task EmulateVisionDeficiencyAsync(VisionDeficiency type) + => Client.SendAsync("Emulation.setEmulatedVisionDeficiency", new EmulationSetEmulatedVisionDeficiencyRequest + { + Type = type, + }); + /// /// Changes the timezone of the page. /// @@ -1916,6 +1931,24 @@ public async Task EmulateTimezoneAsync(string timezoneId) } } + /// + /// Enables CPU throttling to emulate slow CPUs. + /// + /// Throttling rate as a slowdown factor (1 is no throttle, 2 is 2x slowdown, etc). + /// A task that resolves when the message has been sent to the browser. + internal Task EmulateCPUThrottlingAsync(decimal? factor = null) + { + if (factor != null && factor < 1) + { + throw new ArgumentException("Throttling rate should be greater or equal to 1", nameof(factor)); + } + + return Client.SendAsync("Emulation.setCPUThrottlingRate", new EmulationSetCPUThrottlingRateRequest + { + Rate = factor ?? 1 + }); + } + internal void OnPopup(Page popupPage) => Popup?.Invoke(this, new PopupEventArgs { PopupPage = popupPage }); internal static async Task CreateAsync( diff --git a/lib/PuppeteerSharp/VisionDeficiency.cs b/lib/PuppeteerSharp/VisionDeficiency.cs new file mode 100644 index 000000000..20473da45 --- /dev/null +++ b/lib/PuppeteerSharp/VisionDeficiency.cs @@ -0,0 +1,49 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace PuppeteerSharp +{ + /// + /// Types of vision deficiency to emulate using + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum VisionDeficiency + { + /// + /// None + /// + [EnumMember(Value = "none")] + None, + + /// + /// Achromatopsia + /// + [EnumMember(Value = "achromatopsia")] + Achromatopsia, + + /// + /// BlurredVision + /// + [EnumMember(Value = "blurredVision")] + BlurredVision, + + /// + /// Deuteranopia + /// + [EnumMember(Value = "deuteranopia")] + Deuteranopia, + + /// + /// Protanopia + /// + [EnumMember(Value = "protanopia")] + Protanopia, + + /// + /// Tritanopia + /// + [EnumMember(Value = "tritanopia")] + Tritanopia, + } +} \ No newline at end of file