Releases: hardkoded/puppeteer-sharp
v1.2
New Features
- New RequestChain property
- Chromium updated to r543305
New APIs
- ccf6e01 Request.RedirectChain
- 21ad44f ElementHandle.ContentFrameAsync
- https://github.com/kblok/puppeteer-sharp/commit/5323e8f647f9405e08247f915cc18d5cd7745c58 AddTagOptions.Type. Allowing the user to declare script tags (using Page.AddScriptTagAsync) as modules.
Changes
v1.1
New Features
- New Chromium version r536395
- Service workers support
- Cache Support
- New WaitFor options
- New BrowserFetcher utility
- Dump IO implementation
New APIs
- Page.SetCacheEnabledAsync
- Page.DOMContentLoaded
- Page.WaitForXPathAsync
- ResponseData.FromServiceWorker
- ExecutionContext.Frame
- Frame.EvaluateExpressionHandleAsync
- Frame.EvaluateFunctionHandleAsync
- Frame.WaitForSelectorAsync
- Frame.WaitForXPathAsync
- Frame.WaitForSelectorOrXPathAsync
Breaking Changes
Downloader changes
The Downloader
class was renamed to BrowserFetcher
. BrowserFetcher
has the following API:
- DefaultRevision
- DownloadsFolder
- DownloadHost
- Platform
- DownloadProgressChanged
- CanDownloadAsync(int revision)
- LocalRevisions()
- Remove(int revision)
- RevisionInfo(int revision)
- DownloadAsync(int revision)
- GetExecutablePath(int revision)
- GetExecutablePath(Platform platform, string folderPath)
If you were using Downloader
like this:
await Downloader.CreateDefault().DownloadRevisionAsync(chromiumRevision);
It should be changed to :
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
Puppeteer.LaunchAsync breaking change
In order to simplify the API, the revision argument was removed from the LaunchAsync
method. So this piece of code:
Puppeteer.LaunchAsync(launcherOptions, Downloader.DefaultRevision);
Should be changed to:
Puppeteer.LaunchAsync(launcherOptions);
If you need to launch Puppeteer using another revision you should handle that using the ExecutablePath
option:
var myRevisionInfo = await new BrowserFetcher().DownloadAsync(myRevision);
var browser = Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
ExecutablePath = myRevisionInfo.ExecutablePath
});
v1
The day has come. Puppeteer Sharp is fully compatible with Puppeteer V1!
New Features
- Request.RespondAsync support.
- CSS and JS Coverage.
- Request Interception.
New APIs
- Request.RespondAsync
- Page.Coverage.StartJSCoverageAsync
- Page.Coverage.StopJSCoverageAsync
- Page.Coverage.StartCSSCoverageAsync
- Page.Coverage.StopCSSCoverageAsync
- Page.ScreenshotDataAsync
- Page.PdfDataAsync
- Page.SetRequestInterceptionAsync
- Page.GoBackAsync
- Page.GoForwardAsync
- Page.QueryObjectsAsync
- ElementHandle.ScreenshotDataAsync
- ElementHandle.PdfDataAsync
- Browser.WebSocketEndpoint
- Browser.Process
Namespace Changes
- PuppeteerSharp.ClickOptions => PuppeteerSharp.Input.ClickOptions
- PuppeteerSharp.Key => PuppeteerSharp.Input.Key
- PuppeteerSharp.Keyboard => PuppeteerSharp.Input.Keyboard
- PuppeteerSharp.KeyDefinition => PuppeteerSharp.Input.KeyDefinition
- PuppeteerSharp.KeyDefinitions => PuppeteerSharp.Input.KeyDefinitions
- PuppeteerSharp.Mouse => PuppeteerSharp.Input.Mouse
- PuppeteerSharp.MouseButton => PuppeteerSharp.Input.MouseButton
- PuppeteerSharp.MoveOptions => PuppeteerSharp.Input.MoveOptions
- PuppeteerSharp.PressOption => PuppeteerSharp.Input.PresspPtions
- PuppeteerSharp.Touchscreen => PuppeteerSharp.Input.TouchScreen
- PuppeteerSharp.Clip => PuppeteerSharp.Media.Clip
- PuppeteerSharp.MarginOptions => PuppeteerSharp.Media.MarginOptions
- PuppeteerSharp.MediaType => PuppeteerSharp.Media.MediaType
- PuppeteerSharp.PaperFormat => PuppeteerSharp.Media.PaperFormat
- PuppeteerSharp.ScreenOrientation => PuppeteerSharp.Media.ScreenOrientation
- PuppeteerSharp.ScreenOrientationType => PuppeteerSharp.Media.ScreenOrientationType
- PuppeteerSharp.DeviceDescriptor => PuppeteerSharp.Mobile.DeviceDescriptor
- PuppeteerSharp.DeviceDescriptors => PuppeteerSharp.Mobile.DeviceDescriptors
- PuppeteerSharp.DeviceDescriptorName => PuppeteerSharp.Mobile.DeviceDescriptorName
v0.8 ElementHandle Support
- 0.8.0: ElementHandle
- Features:
- ElementHandle support
- API Changes
- Page.SetViewport renamed to Page.SetViewportAsync
- JSHandle.AsElement was dropped. Use JSHandle as ElementHandle instead
- JSHandle.JsonValue renamed to JSHandle.JsonValueAsync
- New APIs
- Page.WaitForNavigationAsync
- ElementHandle.QuerySelectorAsync
- ElementHandle.QuerySelectorAllAsync
- ElementHandle.XPathAsync
- ElementHandle.ScreenshotAsync
- ElementHandle.ScreenshotStreamAsync
- ElementHandle.ClickAsync
- ElementHandle.HoverAsync
- ElementHandle.BoundingBoxAsync
- JSHandle.GetPropertyAsync
- JSHandle.GetPropertiesAsync
- Features:
v0.7 Page Improvements
We are shipping Puppeteer Sharp v0.7 with many cool new features: Element selectors and evaluation over elements. But our big challenge on v0.7 was one of the hard things in computer science: Naming Things.
Puppeteer has these 5 cool functions:
$(selector)
: It callsdocument.querySelector
and returns anElementHandle
.$$(selector)
: It callsdocument.querySelectorAll
and returns anElementHandle
array.$eval(selector, function)
: It callsdocument.querySelector
and executes a function passing the element as an argument.$$eval(selector, function)
: It callsdocument.querySelectorAll
and executes a function passing the element array as an argument.$x(xpathExpression)
: It callsdocument.evaluate
and returns anElementHandle
array.
What do all these methods have in common? Hint: You can solve this using a string.Substring()
.
Yes, you guessed it right! They all have that $
symbol. And guess what? exactly, we can't name a method $
in C#.
So, in order to give these functions a clear and "csharpy" name, we decided to call them in this way:
page.$(selector)
=>page.QuerySelectorAsync(selector)
page.$$(selector)
=>page.QuerySelectorAllAsync(selector)
page.$eval(selector, function)
=>page.QuerySelectorAsync(selector).EvaluateFunctionAsync(function)
page.$$eval(selector, function)
=>page.QuerySelectorAllHandleAsync(selector).EvaluateFunctionAsync(function)
page.$(selector)
=>page.XPathAsync(selector)
These methods may be more verbose, but this naming convention makes them clearer and hopefully, easier to learn.
This is the complete list of new APIs we implemented in this version:
- Page.XPathAsync
- Page.QuerySelectorAsync
- Page.QuerySelectorAllAsync
- Page.QuerySelectorAllHandleAsync
- Page.SelectAsync
- Page.ExposeFunctionAsync
- Page.EvaluateOnNewDocumentAsync
- Page.AddScriptTagAsync
- Page.AddStyleTagAsync
- Page.PageError
- JSHandle.EvaluateFunctionAsync
- ElementHandle.EvaluateFunctionAsync
v0.6 Input simulation
-
Features
- Input simulation
-
New APIs
- ElementHandle.HoverAsync
- ElementHandle.ClickAsync
- ElementHandle.UploadFileAsync
- ElementHandle.TapAsync
- ElementHandle.FocusAsync
- ElementHandle.TypeAsync
- ElementHandle.PressAsync
- Keyboard.DownAsync
- Keyboard.UpAsync
- Keyboard.SendCharacterAsync
- Keyboard.TypeAsync
- Keyboard.PressAsync
- Mouse.MoveAsync
- Mouse.ClickAsync
- Mouse.DownAsync
- Mouse.UpAsync
- TouchScreen.TapAsync
- Page.ClickAsync
- Page.HoverAsync
- Page.FocusAsync
- Page.TypeAsync
v0.5 Frames, Network Events and Tracing
Features
- Network Events
- Tracing
- Frames
Fixes
- Fixed Browse.Close on Azure Functions
New APIs
- Request.ContinueAsync
- Request.RespondAsync
- Request.AbortAsync
- Response.BufferAsync
- Response.TextAsync
- Response.JsonAsync
- Session.TracingComplete
- Session.DetachAsync
- Page.Tracing.StartAsync
- Page.Tracing.StopAsync
- Page.EvaluateOnNewDocumentAsync
- Page.Coverage
- Page.WaitForFunctionAsync
- Browser.Targets
- Browser.PagesAsync
- Frame.WaitForSelectorAsync
- Target.CreateCDPSession
v0.4 Pages!
v0.4 includes more than 25 Page APIs such as:
Full Page.GoToAsync/ReloadAsync support
Emulate/EmulateMedia/SetViewport/SetUserAgent
Get and Set cookies
SetContent
Evaluate javascript functions and expressions
WaitFor expressions
await page.GoToAsync("http://www.mysite.com");
//Do you need to wait for your javascript framework to load content?
//You got it!
await page.WaitForSelectorAsync("div.main-content");
///Emulate media print? Sure!
await Page.EmulateMediaAsync(MediaType.Print);
//Or an iPhone?
await Page.EmulateAsync(iPhone);
///Inject a cookie
await page.SetCookieAsync(new CookieParam
{
Name = "gridcookie",
Value = "GRID",
Path = "/grid.html"
});
//Or even HTML!
await page.SetContentAsync("<div>hello</div>");
//How about executing javascript functions?
await page.EvaluateFunctionAsync<int>("(a) => 5 + a", myValueForA);
Extra goodies
We added support for remote browser connections. This will allow Puppeteer Sharp to be used in docker containers or Azure Functions.
var options = new ConnectOptions()
{
BrowserWSEndpoint = $"wss://browserproviderwhomightwanttosponsortheproject.io"
};
var url = "https://www.google.com/";
using (var browser = await PuppeteerSharp.Puppeteer.ConnectAsync(options))
{
using (var page = await browser.NewPageAsync())
{
await page.GoToAsync(url);
await page.PdfAsync("wot.pdf");
}
}
These are the new available APIs:
- Page.GoToAsync
- Page.ReloadAsync
- Page.EmulateMediaAsync
- Page.SetViewport
- Page.EmulateAsync
- Page.SetUserAgentAsync
- Page.MetricsAsync
- Page.Dialog
- Page.Error
- Page.RequestCreated
- Page.GetCookiesAsync
- Page.SetCookieAsync
- Page.SetExtraHttpHeadersAsync
- Page.AuthenticateAsync
- Page.SetJavaScriptEnabledAsync
- Page.SetContentAsync
- Page.EvaluateFunctionAsync
- Page.EvaluateExpressionAsync
- Page.GetTitleAsync
- Page.SetOfflineModeAsync
- Page.CloseAsync
- Page.Console
- Page.WaitForTimeoutAsync
- Page.WaitForFunctionAsync
- Puppeteer.ConnectAsync
- Browser.Disconnect();
Bug Fixes
v0.3 Launcher Improvements
- Fixed Process leak.
- User data dir support.
var userDataDir = Launcher.GetTemporaryDirectory();
var options = TestConstants.DefaultBrowserOptions();
options.UserDataDir = userDataDir;
var launcher = new Launcher();
var browser = await launcher.LaunchAsync(options, TestConstants.ChromiumRevision);
- Browser and Page now implements IDisposable.
var options = TestConstants.DefaultBrowserOptions();
using (var browser = await PuppeteerSharp.Puppeteer.LaunchAsync(options, TestConstants.ChromiumRevision))
using (var page = await browser.NewPageAsync())
{
var response = await page.GoToAsync("https://www.google.com");
}