diff --git a/lib/PuppeteerSharp.Nunit/TestExpectations/TestExpectations.upstream.json b/lib/PuppeteerSharp.Nunit/TestExpectations/TestExpectations.upstream.json index f3898292e..0968fa588 100644 --- a/lib/PuppeteerSharp.Nunit/TestExpectations/TestExpectations.upstream.json +++ b/lib/PuppeteerSharp.Nunit/TestExpectations/TestExpectations.upstream.json @@ -930,7 +930,7 @@ "comment": "Querying by a11y attributes is not standard behavior" }, { - "testIdPattern": "[bfcache.spec] BFCache can navigate to a BFCached page containing an OOPIF and a worker", + "testIdPattern": "[bfcache.spec] *", "platforms": ["darwin", "linux", "win32"], "parameters": ["cdp", "firefox"], "expectations": ["SKIP"], @@ -1622,32 +1622,11 @@ "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)" }, { - "testIdPattern": "[extensions.spec] extensions background_page target type should be available", + "testIdPattern": "[extensions.spec] extensions *", "platforms": ["darwin", "linux", "win32"], "parameters": ["cdp", "firefox"], "expectations": ["SKIP"], - "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)" - }, - { - "testIdPattern": "[extensions.spec] extensions service_worker target type should be available", - "platforms": ["darwin", "linux", "win32"], - "parameters": ["cdp", "firefox"], - "expectations": ["SKIP"], - "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)" - }, - { - "testIdPattern": "[extensions.spec] extensions target.page() should return a background_page", - "platforms": ["darwin", "linux", "win32"], - "parameters": ["cdp", "firefox"], - "expectations": ["SKIP"], - "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)" - }, - { - "testIdPattern": "[extensions.spec] extensions target.page() should return a background_page", - "platforms": ["darwin", "linux", "win32"], - "parameters": ["cdp", "chrome"], - "expectations": ["FAIL", "PASS"], - "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)" + "comment": "Chrome-specific test" }, { "testIdPattern": "[fixtures.spec] Fixtures should close the browser when the node process closes", @@ -3732,25 +3711,11 @@ "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)" }, { - "testIdPattern": "[extensions.spec] extensions background_page target type should be available", + "testIdPattern": "[extensions.spec] extensions *", "platforms": ["darwin", "linux", "win32"], "parameters": ["cdp", "chrome", "chrome-headless-shell"], "expectations": ["SKIP"], - "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)" - }, - { - "testIdPattern": "[extensions.spec] extensions service_worker target type should be available", - "platforms": ["darwin", "linux", "win32"], - "parameters": ["cdp", "chrome", "chrome-headless-shell"], - "expectations": ["SKIP"], - "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)" - }, - { - "testIdPattern": "[extensions.spec] extensions target.page() should return a background_page", - "platforms": ["darwin", "linux", "win32"], - "parameters": ["cdp", "chrome", "chrome-headless-shell"], - "expectations": ["SKIP"], - "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)" + "comment": "No extensions in chrome-headless-shell" }, { "testIdPattern": "[network.spec] network Network Events Page.Events.Request", diff --git a/lib/PuppeteerSharp.TestServer/wwwroot/jscoverage/ranges.html b/lib/PuppeteerSharp.TestServer/wwwroot/jscoverage/ranges.html index a537a7da6..3d02670ae 100644 --- a/lib/PuppeteerSharp.TestServer/wwwroot/jscoverage/ranges.html +++ b/lib/PuppeteerSharp.TestServer/wwwroot/jscoverage/ranges.html @@ -1,2 +1,2 @@ +function unused(){}console.log('used!');if(true===false)console.log('unused!'); diff --git a/lib/PuppeteerSharp.Tests/Assets/service-worker-extension/background.js b/lib/PuppeteerSharp.Tests/Assets/service-worker-extension/background.js deleted file mode 100644 index 8b1a39374..000000000 --- a/lib/PuppeteerSharp.Tests/Assets/service-worker-extension/background.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/lib/PuppeteerSharp.Tests/Assets/service-worker-extension/manifest.json b/lib/PuppeteerSharp.Tests/Assets/service-worker-extension/manifest.json deleted file mode 100644 index 25828b6d2..000000000 --- a/lib/PuppeteerSharp.Tests/Assets/service-worker-extension/manifest.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "Simple extension", - "version": "0.1", - "background": { - "service_worker": "background.js" - }, - "permissions": ["background", "activeTab"], - "manifest_version": 3 -} diff --git a/lib/PuppeteerSharp.Tests/Assets/simple-extension/index.js b/lib/PuppeteerSharp.Tests/Assets/simple-extension/index.js index a0bb3f4ea..c31bbebf3 100644 --- a/lib/PuppeteerSharp.Tests/Assets/simple-extension/index.js +++ b/lib/PuppeteerSharp.Tests/Assets/simple-extension/index.js @@ -1,2 +1,2 @@ -// Mock script for background extension -window.MAGIC = 42; +// Mock script for service worker extension +globalThis.MAGIC = 42; diff --git a/lib/PuppeteerSharp.Tests/Assets/simple-extension/manifest.json b/lib/PuppeteerSharp.Tests/Assets/simple-extension/manifest.json index da2cd082e..39b77fc21 100644 --- a/lib/PuppeteerSharp.Tests/Assets/simple-extension/manifest.json +++ b/lib/PuppeteerSharp.Tests/Assets/simple-extension/manifest.json @@ -2,7 +2,7 @@ "name": "Simple extension", "version": "0.1", "background": { - "scripts": ["index.js"] + "service_worker": "index.js" }, "content_scripts": [{ "matches": [""], @@ -10,5 +10,5 @@ "js": ["content-script.js"] }], "permissions": ["background", "activeTab"], - "manifest_version": 2 + "manifest_version": 3 } diff --git a/lib/PuppeteerSharp.Tests/Browsers/Firefox/FirefoxDataTests.cs b/lib/PuppeteerSharp.Tests/Browsers/Firefox/FirefoxDataTests.cs index 482405690..3093a078e 100644 --- a/lib/PuppeteerSharp.Tests/Browsers/Firefox/FirefoxDataTests.cs +++ b/lib/PuppeteerSharp.Tests/Browsers/Firefox/FirefoxDataTests.cs @@ -10,19 +10,19 @@ public class FirefoxDataTests public void ShouldResolveUrlsForNightly() { Assert.That( - BrowserData.Firefox.ResolveDownloadUrl(Platform.Linux, "111.0a1", null), + BrowserData.Firefox.ResolveDownloadUrl(Platform.Linux, "nightly_111.0a1", null), Is.EqualTo("https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/firefox-111.0a1.en-US.linux-x86_64.tar.bz2")); Assert.That( - BrowserData.Firefox.ResolveDownloadUrl(Platform.MacOS, "111.0a1", null), + BrowserData.Firefox.ResolveDownloadUrl(Platform.MacOS, "nightly_111.0a1", null), Is.EqualTo("https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/firefox-111.0a1.en-US.mac.dmg")); Assert.That( - BrowserData.Firefox.ResolveDownloadUrl(Platform.MacOSArm64, "111.0a1", null), + BrowserData.Firefox.ResolveDownloadUrl(Platform.MacOSArm64, "nightly_111.0a1", null), Is.EqualTo("https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/firefox-111.0a1.en-US.mac.dmg")); Assert.That( - BrowserData.Firefox.ResolveDownloadUrl(Platform.Win32, "111.0a1", null), + BrowserData.Firefox.ResolveDownloadUrl(Platform.Win32, "nightly_111.0a1", null), Is.EqualTo("https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/firefox-111.0a1.en-US.win32.zip")); Assert.That( - BrowserData.Firefox.ResolveDownloadUrl(Platform.Win64, "111.0a1", null), + BrowserData.Firefox.ResolveDownloadUrl(Platform.Win64, "nightly_111.0a1", null), Is.EqualTo("https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/firefox-111.0a1.en-US.win64.zip")); } @@ -96,7 +96,7 @@ public void ShouldResolveExecutablePath() Assert.That( BrowserData.Firefox.RelativeExecutablePath(Platform.MacOS, "111.0a1"), Is.EqualTo(Path.Combine( - "Firefox Nightly.app", + "Firefox.app", "Contents", "MacOS", "firefox" @@ -105,7 +105,7 @@ public void ShouldResolveExecutablePath() Assert.That( BrowserData.Firefox.RelativeExecutablePath(Platform.MacOSArm64, "111.0a1"), Is.EqualTo(Path.Combine( - "Firefox Nightly.app", + "Firefox.app", "Contents", "MacOS", "firefox" @@ -122,11 +122,7 @@ public void ShouldResolveExecutablePath() Assert.That( BrowserData.Firefox.RelativeExecutablePath(Platform.Win32, "111.0a1"), - Is.EqualTo(Path.Combine("firefox", "firefox.exe"))); - - Assert.That( - Path.Combine("firefox", "firefox.exe"), - Is.EqualTo(BrowserData.Firefox.RelativeExecutablePath(Platform.Win64, "111.0a1"))); + Is.EqualTo(Path.Combine("core", "firefox.exe"))); } } } diff --git a/lib/PuppeteerSharp.Tests/CoverageTests/JSCoverageTests.cs b/lib/PuppeteerSharp.Tests/CoverageTests/JSCoverageTests.cs index 8ab0bb8eb..0dbe01bd9 100644 --- a/lib/PuppeteerSharp.Tests/CoverageTests/JSCoverageTests.cs +++ b/lib/PuppeteerSharp.Tests/CoverageTests/JSCoverageTests.cs @@ -110,9 +110,31 @@ public async Task ShouldReportRightRanges() var coverage = await Page.Coverage.StopJSCoverageAsync(); Assert.That(coverage, Has.Exactly(1).Items); var entry = coverage[0]; - Assert.That(entry.Ranges, Has.Exactly(1).Items); - var range = entry.Ranges[0]; - Assert.That(entry.Text.Substring(range.Start, range.End - range.Start), Is.EqualTo("console.log('used!');")); + Assert.That(entry.Ranges, Has.Exactly(2).Items); + var range1 = entry.Ranges[0]; + Assert.That(entry.Text.Substring(range1.Start, range1.End - range1.Start), Is.EqualTo("\n")); + var range2 = entry.Ranges[1]; + Assert.That(entry.Text.Substring(range2.Start, range2.End - range2.Start), Is.EqualTo("console.log('used!');if(true===false)")); + } + + [Test, Retry(2), PuppeteerTest("coverage.spec", "Coverage specs JSCoverage", "should report right ranges for \"per function\" scope")] + public async Task ShouldReportRightRangesForPerFunctionScope() + { + var coverageOptions = new CoverageStartOptions + { + UseBlockCoverage = false, + }; + + await Page.Coverage.StartJSCoverageAsync(coverageOptions); + await Page.GoToAsync(TestConstants.ServerUrl + "/jscoverage/ranges.html"); + var coverage = await Page.Coverage.StopJSCoverageAsync(); + Assert.That(coverage, Has.Exactly(1).Items); + var entry = coverage[0]; + Assert.That(entry.Ranges, Has.Exactly(2).Items); + var range1 = entry.Ranges[0]; + Assert.That(entry.Text.Substring(range1.Start, range1.End - range1.Start), Is.EqualTo("\n")); + var range2 = entry.Ranges[1]; + Assert.That(entry.Text.Substring(range2.Start, range2.End - range2.Start), Is.EqualTo("console.log('used!');if(true===false)console.log('unused!');")); } [Test, Retry(2), PuppeteerTest("coverage.spec", "Coverage specs JSCoverage", "should report scripts that have no coverage")] diff --git a/lib/PuppeteerSharp.Tests/ExtensionsTests/ExtensionsTests.cs b/lib/PuppeteerSharp.Tests/ExtensionsTests/ExtensionsTests.cs index 0d47a7e9f..be4c8a33f 100644 --- a/lib/PuppeteerSharp.Tests/ExtensionsTests/ExtensionsTests.cs +++ b/lib/PuppeteerSharp.Tests/ExtensionsTests/ExtensionsTests.cs @@ -10,7 +10,6 @@ namespace PuppeteerSharp.Tests.ExtensionsTests public class ExtensionsTests : PuppeteerBaseTest { private static readonly string _extensionPath = Path.Combine(AppContext.BaseDirectory, "Assets", "simple-extension"); - private static readonly string _serviceWorkerExtensionPath = Path.Combine(AppContext.BaseDirectory, "Assets", "service-worker-extension"); private static LaunchOptions BrowserWithExtensionOptions() => new() { @@ -22,51 +21,25 @@ public class ExtensionsTests : PuppeteerBaseTest } }; - private static LaunchOptions BrowserWithServiceWorkerExtensionOptions() => new() - { - Headless = false, - Args = new[] - { - $"--disable-extensions-except={_serviceWorkerExtensionPath.Quote()}", - $"--load-extension={_serviceWorkerExtensionPath.Quote()}" - } - }; - - [Test, Retry(2), PuppeteerTest("extensions.spec", "extensions", "background_page target type should be available")] - public async Task BackgroundPageTargetTypeShouldBeAvailable() - { - await using var browserWithExtension = await Puppeteer.LaunchAsync( - BrowserWithExtensionOptions(), - TestConstants.LoggerFactory); - await using (await browserWithExtension.NewPageAsync()) - { - var backgroundPageTarget = await browserWithExtension.WaitForTargetAsync(t => t.Type == TargetType.BackgroundPage); - Assert.That(backgroundPageTarget, Is.Not.Null); - } - } - [Test, Retry(2), PuppeteerTest("extensions.spec", "extensions", "service_worker target type should be available")] public async Task ServiceWorkerTargetTypeShouldBeAvailable() { await using var browserWithExtension = await Puppeteer.LaunchAsync( - BrowserWithServiceWorkerExtensionOptions(), + BrowserWithExtensionOptions(), TestConstants.LoggerFactory); var serviceWorkTarget = await browserWithExtension.WaitForTargetAsync(t => t.Type == TargetType.ServiceWorker); - await using var page = await browserWithExtension.NewPageAsync(); Assert.That(serviceWorkTarget, Is.Not.Null); - } - [Test, Retry(2), PuppeteerTest("extensions.spec", "extensions", "target.page() should return a background_page")] - public async Task TargetPageShouldReturnABackgroundPage() + [Test, Retry(2), PuppeteerTest("extensions.spec", "extensions", "can evaluate in the service worker")] + public async Task CanEvaluateInTheServiceWorker() { await using var browserWithExtension = await Puppeteer.LaunchAsync( BrowserWithExtensionOptions(), TestConstants.LoggerFactory); - var backgroundPageTarget = await browserWithExtension.WaitForTargetAsync(t => t.Type == TargetType.BackgroundPage); - await using var page = await backgroundPageTarget.PageAsync(); - Assert.That(await page.EvaluateFunctionAsync("() => 2 * 3"), Is.EqualTo(6)); - Assert.That(await page.EvaluateFunctionAsync("() => window.MAGIC"), Is.EqualTo(42)); + var serviceWorkerTarget = await browserWithExtension.WaitForTargetAsync(t => t.Type == TargetType.ServiceWorker); + var worker = await serviceWorkerTarget.WorkerAsync(); + Assert.That(await worker.EvaluateFunctionAsync("() => globalThis.MAGIC"), Is.EqualTo(42)); } } } diff --git a/lib/PuppeteerSharp/BrowserData/Chrome.cs b/lib/PuppeteerSharp/BrowserData/Chrome.cs index fcc219223..848410248 100644 --- a/lib/PuppeteerSharp/BrowserData/Chrome.cs +++ b/lib/PuppeteerSharp/BrowserData/Chrome.cs @@ -13,7 +13,7 @@ public static class Chrome /// /// Default chrome build. /// - public static string DefaultBuildId => "132.0.6834.83"; + public static string DefaultBuildId => "137.0.7151.119"; internal static async Task ResolveBuildIdAsync(ChromeReleaseChannel channel) => (await GetLastKnownGoodReleaseForChannel(channel).ConfigureAwait(false)).Version; diff --git a/lib/PuppeteerSharp/BrowserData/Firefox.cs b/lib/PuppeteerSharp/BrowserData/Firefox.cs index 390b7adb5..e08b0676a 100644 --- a/lib/PuppeteerSharp/BrowserData/Firefox.cs +++ b/lib/PuppeteerSharp/BrowserData/Firefox.cs @@ -22,7 +22,7 @@ public static class Firefox private static readonly Dictionary _cachedBuildIds = []; - internal static Task GetDefaultBuildIdAsync() => ResolveBuildIdAsync(FirefoxChannel.Nightly); + internal static Task GetDefaultBuildIdAsync() => Task.FromResult(DefaultBuildId); internal static string ResolveDownloadUrl(Platform platform, string buildId, string baseUrl) { @@ -152,7 +152,7 @@ private static (FirefoxChannel Channel, string BuildId) ParseBuildId(string buil } } - return (FirefoxChannel.Nightly, buildId); + return (FirefoxChannel.Stable, buildId); } private static string[] ResolveDownloadPath(Platform platform, string buildId) diff --git a/lib/PuppeteerSharp/PageCoverage/Coverage.cs b/lib/PuppeteerSharp/PageCoverage/Coverage.cs index 57d933c6a..7ad84296e 100644 --- a/lib/PuppeteerSharp/PageCoverage/Coverage.cs +++ b/lib/PuppeteerSharp/PageCoverage/Coverage.cs @@ -88,7 +88,7 @@ internal static CoverageEntryRange[] ConvertToDisjointRanges(List } // Filter out empty ranges. - return results.Where(range => range.End - range.Start > 1).ToArray(); + return results.Where(range => range.End - range.Start > 0).ToArray(); } internal void UpdateClient(CDPSession client) diff --git a/lib/PuppeteerSharp/PageCoverage/CoverageStartOptions.cs b/lib/PuppeteerSharp/PageCoverage/CoverageStartOptions.cs index 0ca2f19ab..7655366e2 100644 --- a/lib/PuppeteerSharp/PageCoverage/CoverageStartOptions.cs +++ b/lib/PuppeteerSharp/PageCoverage/CoverageStartOptions.cs @@ -24,5 +24,12 @@ public class CoverageStartOptions /// Whether the result includes raw V8 script coverage entries. /// public bool IncludeRawScriptCoverage { get; set; } + + /// + /// Whether to collect coverage information at the block level. + /// If true, coverage will be collected at the block level (this is the default). + /// If false, coverage will be collected at the function level. + /// + public bool UseBlockCoverage { get; set; } = true; } } diff --git a/lib/PuppeteerSharp/PageCoverage/ICoverage.cs b/lib/PuppeteerSharp/PageCoverage/ICoverage.cs index 01fe5a60d..ddbe3dbcf 100644 --- a/lib/PuppeteerSharp/PageCoverage/ICoverage.cs +++ b/lib/PuppeteerSharp/PageCoverage/ICoverage.cs @@ -17,7 +17,9 @@ public interface ICoverage /// /// Starts JS coverage. /// - /// Set of configurable options for coverage. + /// Set of configurable options for coverage defaults to + /// resetOnNavigation : true, reportAnonymousScripts : false, + /// includeRawScriptCoverage : false, useBlockCoverage : true. /// A task that resolves when coverage is started. Task StartJSCoverageAsync(CoverageStartOptions options = null); diff --git a/lib/PuppeteerSharp/PageCoverage/JSCoverage.cs b/lib/PuppeteerSharp/PageCoverage/JSCoverage.cs index 75d65cb24..e0983a833 100755 --- a/lib/PuppeteerSharp/PageCoverage/JSCoverage.cs +++ b/lib/PuppeteerSharp/PageCoverage/JSCoverage.cs @@ -20,6 +20,7 @@ internal class JSCoverage private bool _resetOnNavigation; private bool _reportAnonymousScripts; private bool _includeRawScriptCoverage; + private bool _useBlockCoverage; public JSCoverage(CDPSession client) { @@ -42,6 +43,7 @@ internal Task StartAsync(CoverageStartOptions options) _resetOnNavigation = options.ResetOnNavigation; _reportAnonymousScripts = options.ReportAnonymousScripts; _includeRawScriptCoverage = options.IncludeRawScriptCoverage; + _useBlockCoverage = options.UseBlockCoverage; _enabled = true; _scriptURLs.Clear(); _scriptSources.Clear(); @@ -53,7 +55,7 @@ internal Task StartAsync(CoverageStartOptions options) _client.SendAsync("Profiler.startPreciseCoverage", new ProfilerStartPreciseCoverageRequest { CallCount = _includeRawScriptCoverage, - Detailed = true, + Detailed = _useBlockCoverage, }), _client.SendAsync("Debugger.enable"), _client.SendAsync("Debugger.setSkipAllPauses", new DebuggerSetSkipAllPausesRequest { Skip = true })); diff --git a/lib/PuppeteerSharp/PuppeteerSharp.csproj b/lib/PuppeteerSharp/PuppeteerSharp.csproj index f3c8aca9f..6e3c7137f 100644 --- a/lib/PuppeteerSharp/PuppeteerSharp.csproj +++ b/lib/PuppeteerSharp/PuppeteerSharp.csproj @@ -12,10 +12,10 @@ Headless Browser .NET API PuppeteerSharp - 20.1.3 - 20.1.3 - 20.1.3 - 20.1.3 + 20.2.0 + 20.2.0 + 20.2.0 + 20.2.0 false false embedded