diff --git a/lib/PuppeteerSharp.Tests/CookiesTests/CookiesTests.cs b/lib/PuppeteerSharp.Tests/CookiesTests/CookiesTests.cs index a16a8a726..a7668d82a 100644 --- a/lib/PuppeteerSharp.Tests/CookiesTests/CookiesTests.cs +++ b/lib/PuppeteerSharp.Tests/CookiesTests/CookiesTests.cs @@ -77,6 +77,43 @@ public async Task ShouldProperlyReportLaxSameSiteCookie() Assert.That(cookies[0].SameSite, Is.EqualTo(SameSite.Lax)); } + [Test, PuppeteerTest("cookies.spec", "Cookie specs Page.cookies", "should properly report \"Default\" sameSite cookie")] + public async Task ShouldProperlyReportDefaultSameSiteCookie() + { + await Page.GoToAsync(TestConstants.EmptyPage); + await Page.SetCookieAsync(new CookieParam + { + Name = "a", + Value = "b", + SameSite = SameSite.Default, + }); + var cookies = await Page.GetCookiesAsync(); + Assert.That(cookies, Has.Exactly(1).Items); + Assert.That(cookies[0].Name, Is.EqualTo("a")); + + // Different browsers have different sameSite values for the "Default" sameSite. + Assert.That( + new SameSite?[] { SameSite.Default, SameSite.Lax, null }, + Does.Contain(cookies[0].SameSite)); + } + + [Test, PuppeteerTest("cookies.spec", "Cookie specs Page.cookies", "should report \"Default\" sameSite cookie when not specified")] + public async Task ShouldReportDefaultSameSiteCookieWhenNotSpecified() + { + Server.SetRoute("/empty.html", context => + { + context.Response.Headers["Set-Cookie"] = "a=b"; + return Task.CompletedTask; + }); + await Page.GoToAsync(TestConstants.EmptyPage); + var cookies = await Page.GetCookiesAsync(); + Assert.That(cookies, Has.Exactly(1).Items); + if (!TestConstants.IsChrome && !PuppeteerTestAttribute.IsCdp) + { + Assert.That(cookies[0].SameSite, Is.EqualTo(SameSite.Default)); + } + } + [Test, PuppeteerTest("cookies.spec", "Cookie specs Page.cookies", "should get multiple cookies")] public async Task ShouldGetMultipleCookies() { diff --git a/lib/PuppeteerSharp.Tests/CookiesTests/SetCookiesTests.cs b/lib/PuppeteerSharp.Tests/CookiesTests/SetCookiesTests.cs index f653875ff..c1d2cfd9a 100644 --- a/lib/PuppeteerSharp.Tests/CookiesTests/SetCookiesTests.cs +++ b/lib/PuppeteerSharp.Tests/CookiesTests/SetCookiesTests.cs @@ -227,6 +227,22 @@ await page.SetCookieAsync(new CookieParam Assert.That(cookie.PartitionKey, Is.EqualTo(key)); } + [Test, PuppeteerTest("cookies.spec", "Cookie specs Page.setCookie", "should be able to delete \"Default\" sameSite cookie")] + public async Task ShouldBeAbleToDeleteDefaultSameSiteCookie() + { + await Page.GoToAsync(TestConstants.EmptyPage); + await Page.SetCookieAsync(new CookieParam + { + Name = "a", + Value = "b", + SameSite = SameSite.Default, + }); + var cookies = await Page.GetCookiesAsync(); + Assert.That(cookies.Any(c => c.Name == "a"), Is.True); + await Page.DeleteCookieAsync(cookies); + Assert.That(await Page.GetCookiesAsync(), Is.Empty); + } + [Test, PuppeteerTest("cookies.spec", "Cookie specs Page.setCookie", "should not set a cookie on a blank page")] public async Task ShouldNotSetACookieOnABlankPage() { diff --git a/lib/PuppeteerSharp/Bidi/BidiCookieHelper.cs b/lib/PuppeteerSharp/Bidi/BidiCookieHelper.cs index 1521e7bdc..d7d1e93c4 100644 --- a/lib/PuppeteerSharp/Bidi/BidiCookieHelper.cs +++ b/lib/PuppeteerSharp/Bidi/BidiCookieHelper.cs @@ -178,7 +178,8 @@ private static SameSite ConvertSameSiteBidiToPuppeteer(CookieSameSiteValue sameS { CookieSameSiteValue.Strict => SameSite.Strict, CookieSameSiteValue.Lax => SameSite.Lax, - _ => SameSite.None, + CookieSameSiteValue.None => SameSite.None, + _ => SameSite.Default, }; } @@ -189,7 +190,7 @@ private static SameSite ConvertSameSiteBidiToPuppeteer(CookieSameSiteValue sameS SameSite.Strict => CookieSameSiteValue.Strict, SameSite.Lax => CookieSameSiteValue.Lax, SameSite.None => CookieSameSiteValue.None, - _ => null, + _ => CookieSameSiteValue.Default, }; } diff --git a/lib/PuppeteerSharp/Cdp/CdpPage.cs b/lib/PuppeteerSharp/Cdp/CdpPage.cs index 3f88a3e91..057084209 100644 --- a/lib/PuppeteerSharp/Cdp/CdpPage.cs +++ b/lib/PuppeteerSharp/Cdp/CdpPage.cs @@ -214,6 +214,11 @@ public override async Task SetCookieAsync(params CookieParam[] cookies) if (cookies.Length > 0) { + foreach (var cookie in cookies) + { + cookie.SameSite = ConvertSameSiteForCdp(cookie.SameSite); + } + await PrimaryTargetClient .SendAsync("Network.setCookies", new NetworkSetCookiesRequest { Cookies = cookies, }) .ConfigureAwait(false); @@ -987,6 +992,19 @@ protected override async Task PerformScreenshotAsync(ScreenshotType type _ => null, }; + /// + /// Converts a PuppeteerSharp SameSite value to a CDP-compatible value. + /// CDP does not support "Default", so we map it to null (omitted). + /// + private static SameSite? ConvertSameSiteForCdp(SameSite? sameSite) + { + return sameSite switch + { + SameSite.Strict or SameSite.Lax or SameSite.None => sameSite, + _ => null, + }; + } + private void SetupPrimaryTargetListeners() { PrimaryTargetClient.Ready += OnAttachedToTarget; diff --git a/lib/PuppeteerSharp/SameSite.cs b/lib/PuppeteerSharp/SameSite.cs index ffd818424..d8018e196 100644 --- a/lib/PuppeteerSharp/SameSite.cs +++ b/lib/PuppeteerSharp/SameSite.cs @@ -29,5 +29,10 @@ public enum SameSite /// Extended. /// Extended, + + /// + /// Default. The browser applies its default SameSite behavior. + /// + Default, } }