diff --git a/lib/PuppeteerSharp.Tests/PageTests/EmulateMediaFeaturesTests.cs b/lib/PuppeteerSharp.Tests/PageTests/EmulateMediaFeaturesTests.cs new file mode 100644 index 000000000..45c270f35 --- /dev/null +++ b/lib/PuppeteerSharp.Tests/PageTests/EmulateMediaFeaturesTests.cs @@ -0,0 +1,46 @@ +using System.Threading.Tasks; +using PuppeteerSharp.Media; +using Xunit; +using Xunit.Abstractions; + +namespace PuppeteerSharp.Tests.PageTests +{ + [Collection(TestConstants.TestFixtureCollectionName)] + public class EmulateMediaFeaturesAsyncTests : PuppeteerPageBaseTest + { + public EmulateMediaFeaturesAsyncTests(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public async Task ShouldWork() + { + await Page.EmulateMediaFeaturesAsync(new MediaFeatureValue[] { + new MediaFeatureValue { MediaFeature = MediaFeature.PrefersReducedMotion, Value = "reduce" }, + }); + Assert.True(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-reduced-motion: reduce)').matches")); + Assert.False(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-reduced-motion: no-preference)').matches")); + await Page.EmulateMediaFeaturesAsync(new MediaFeatureValue[] { + new MediaFeatureValue { MediaFeature = MediaFeature.PrefersColorScheme, Value = "light" }, + }); + Assert.True(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: light)').matches")); + Assert.False(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: dark)').matches")); + Assert.False(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: no-preference)').matches")); + await Page.EmulateMediaFeaturesAsync(new MediaFeatureValue[] { + new MediaFeatureValue { MediaFeature = MediaFeature.PrefersColorScheme, Value = "dark" }, + }); + Assert.True(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: dark)').matches")); + Assert.False(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: light)').matches")); + Assert.False(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: no-preference)').matches")); + await Page.EmulateMediaFeaturesAsync(new MediaFeatureValue[] { + new MediaFeatureValue { MediaFeature = MediaFeature.PrefersReducedMotion, Value = "reduce" }, + new MediaFeatureValue { MediaFeature = MediaFeature.PrefersColorScheme, Value = "light" }, + }); + Assert.True(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-reduced-motion: reduce)').matches")); + Assert.False(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-reduced-motion: no-preference)').matches")); + Assert.True(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: light)').matches")); + Assert.False(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: dark)').matches")); + Assert.False(await Page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: no-preference)').matches")); + } + } +} diff --git a/lib/PuppeteerSharp.Tests/PageTests/EmulateMediaTests.cs b/lib/PuppeteerSharp.Tests/PageTests/EmulateMediaTypeTests.cs similarity index 58% rename from lib/PuppeteerSharp.Tests/PageTests/EmulateMediaTests.cs rename to lib/PuppeteerSharp.Tests/PageTests/EmulateMediaTypeTests.cs index 9c3275729..b180ffa42 100644 --- a/lib/PuppeteerSharp.Tests/PageTests/EmulateMediaTests.cs +++ b/lib/PuppeteerSharp.Tests/PageTests/EmulateMediaTypeTests.cs @@ -6,23 +6,23 @@ namespace PuppeteerSharp.Tests.PageTests { [Collection(TestConstants.TestFixtureCollectionName)] - public class EmulateMediaTests : PuppeteerPageBaseTest + public class EmulateMediaTypeTests : PuppeteerPageBaseTest { - public EmulateMediaTests(ITestOutputHelper output) : base(output) + public EmulateMediaTypeTests(ITestOutputHelper output) : base(output) { } [Fact] public async Task ShouldWork() { - Assert.True(await Page.EvaluateExpressionAsync("window.matchMedia('screen').matches")); - Assert.False(await Page.EvaluateExpressionAsync("window.matchMedia('print').matches")); - await Page.EmulateMediaAsync(MediaType.Print); - Assert.False(await Page.EvaluateExpressionAsync("window.matchMedia('screen').matches")); - Assert.True(await Page.EvaluateExpressionAsync("window.matchMedia('print').matches")); - await Page.EmulateMediaAsync(MediaType.None); - Assert.True(await Page.EvaluateExpressionAsync("window.matchMedia('screen').matches")); - Assert.False(await Page.EvaluateExpressionAsync("window.matchMedia('print').matches")); + Assert.True(await Page.EvaluateExpressionAsync("matchMedia('screen').matches")); + Assert.False(await Page.EvaluateExpressionAsync("matchMedia('print').matches")); + await Page.EmulateMediaTypeAsync(MediaType.Print); + Assert.False(await Page.EvaluateExpressionAsync("matchMedia('screen').matches")); + Assert.True(await Page.EvaluateExpressionAsync("matchMedia('print').matches")); + await Page.EmulateMediaTypeAsync(MediaType.None); + Assert.True(await Page.EvaluateExpressionAsync("matchMedia('screen').matches")); + Assert.False(await Page.EvaluateExpressionAsync("matchMedia('print').matches")); } } } diff --git a/lib/PuppeteerSharp/MediaFeature.cs b/lib/PuppeteerSharp/MediaFeature.cs new file mode 100644 index 000000000..28517623f --- /dev/null +++ b/lib/PuppeteerSharp/MediaFeature.cs @@ -0,0 +1,24 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace PuppeteerSharp +{ + /// + /// Meadia Feature. See + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum MediaFeature + { + /// + /// prefers-color-scheme media feature. + /// + [EnumMember(Value = "prefers-color-scheme")] + PrefersColorScheme, + /// + /// prefers-reduced-motion media feature. + /// + [EnumMember(Value = "prefers-reduced-motion")] + PrefersReducedMotion + } +} \ No newline at end of file diff --git a/lib/PuppeteerSharp/MediaFeatureValue.cs b/lib/PuppeteerSharp/MediaFeatureValue.cs new file mode 100644 index 000000000..807683380 --- /dev/null +++ b/lib/PuppeteerSharp/MediaFeatureValue.cs @@ -0,0 +1,20 @@ +using Newtonsoft.Json; + +namespace PuppeteerSharp +{ + /// + /// Media Feature. + /// + public class MediaFeatureValue + { + /// + /// The CSS media feature name. Supported names are `'prefers-colors-scheme'` and `'prefers-reduced-motion'`. + /// + [JsonProperty(PropertyName = "name")] + public MediaFeature MediaFeature { get; set; } + /// + /// The value for the given CSS media feature. + /// + public string Value { get; set; } + } +} \ No newline at end of file diff --git a/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedMediaFeatureRequest.cs b/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedMediaFeatureRequest.cs new file mode 100644 index 000000000..b15616f3f --- /dev/null +++ b/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedMediaFeatureRequest.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using PuppeteerSharp.Media; + +namespace PuppeteerSharp.Messaging +{ + internal class EmulationSetEmulatedMediaFeatureRequest + { + public IEnumerable Features { get; set; } + } +} diff --git a/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedMediaRequest.cs b/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedMediaRequest.cs index b5014e262..b4ae8fa74 100644 --- a/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedMediaRequest.cs +++ b/lib/PuppeteerSharp/Messaging/EmulationSetEmulatedMediaRequest.cs @@ -1,8 +1,9 @@ -using PuppeteerSharp.Media; +using System.Collections.Generic; +using PuppeteerSharp.Media; namespace PuppeteerSharp.Messaging { - internal class EmulationSetEmulatedMediaRequest + internal class EmulationSetEmulatedMediaTypeRequest { public MediaType Media { get; set; } } diff --git a/lib/PuppeteerSharp/Page.cs b/lib/PuppeteerSharp/Page.cs index 1e34861ee..dc2e25286 100644 --- a/lib/PuppeteerSharp/Page.cs +++ b/lib/PuppeteerSharp/Page.cs @@ -1009,8 +1009,77 @@ public Task SetJavaScriptEnabledAsync(bool enabled) /// /// Task. /// Media to set. - public Task EmulateMediaAsync(MediaType media) - => Client.SendAsync("Emulation.setEmulatedMedia", new EmulationSetEmulatedMediaRequest { Media = media }); + [Obsolete("User EmulateMediaTypeAsync instead")] + public Task EmulateMediaAsync(MediaType media) => EmulateMediaTypeAsync(media); + + /// + /// Emulates a media such as screen or print. + /// + /// Media to set. + /// + /// + /// ("() => matchMedia('screen').matches)"); + /// // → true + /// await page.EvaluateFunctionAsync("() => matchMedia('print').matches)"); + /// // → true + /// await page.EmulateMediaTypeAsync(MediaType.Print); + /// await page.EvaluateFunctionAsync("() => matchMedia('screen').matches)"); + /// // → false + /// await page.EvaluateFunctionAsync("() => matchMedia('print').matches)"); + /// // → true + /// await page.EmulateMediaTypeAsync(MediaType.None); + /// await page.EvaluateFunctionAsync("() => matchMedia('screen').matches)"); + /// // → true + /// await page.EvaluateFunctionAsync("() => matchMedia('print').matches)"); + /// // → true + /// ]]> + /// + /// + /// Emulate media type task. + public Task EmulateMediaTypeAsync(MediaType type) + => Client.SendAsync("Emulation.setEmulatedMedia", new EmulationSetEmulatedMediaTypeRequest { Media = type }); + + /// + /// Given an array of media feature objects, emulates CSS media features on the page. + /// + /// Features to apply + /// + /// + /// ("() => matchMedia('(prefers-color-scheme: dark)').matches)"); + /// // → true + /// await page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: light)').matches)"); + /// // → false + /// await page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: no-preference)').matches)"); + /// // → false + /// await page.EmulateMediaFeaturesAsync(new MediaFeature[]{ new MediaFeature { MediaFeature = MediaFeature.PrefersReducedMotion, Value = "reduce" }}); + /// await page.EvaluateFunctionAsync("() => matchMedia('(prefers-reduced-motion: reduce)').matches)"); + /// // → true + /// await page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: no-preference)').matches)"); + /// // → false + /// await page.EmulateMediaFeaturesAsync(new MediaFeature[] + /// { + /// new MediaFeature { MediaFeature = MediaFeature.PrefersColorScheme, Value = "dark" }, + /// new MediaFeature { MediaFeature = MediaFeature.PrefersReducedMotion, Value = "reduce" }, + /// }); + /// await page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: dark)').matches)"); + /// // → true + /// await page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: light)').matches)"); + /// // → false + /// await page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: no-preference)').matches)"); + /// // → false + /// await page.EvaluateFunctionAsync("() => matchMedia('(prefers-reduced-motion: reduce)').matches)"); + /// // → true + /// await page.EvaluateFunctionAsync("() => matchMedia('(prefers-color-scheme: no-preference)').matches)"); + /// // → false + /// ]]> + /// + /// + /// Emulate features task + public Task EmulateMediaFeaturesAsync(IEnumerable features) + => Client.SendAsync("Emulation.setEmulatedMedia", new EmulationSetEmulatedMediaFeatureRequest { Features = features }); /// /// Sets the viewport.