v19.0.0
Welcome System.Text.Json and AOT support!
What's new
Full AOT Support.
v19 comes with one of the most significant changes made to this library. We are moving away from Newtonsoft JSON in favor of System.Text.Json. The motivation behind this change is that it would get us closer to AOT support.
If you are using your own classes to interact with the browser through EvaluateFunctionAsync
or similar, you will have to provide your own JsonSerializerContext
to puppeteer using the static Puppeteer.ExtraJsonSerializerContext
property.
For instance.
Puppeteer.ExtraJsonSerializerContext = DemoJsonSerializationContext.Default;
await using var browser = await Puppeteer.LaunchAsync();
await using var page = await browser.NewPageAsync();
var result = await page.EvaluateFunctionAsync<TestClass>("test => test", new TestClass { Name = "Dario"});
Console.WriteLine($"Name evaluated to {result.Name}");
The serializer would look like this:
public class TestClass
{
public string Name { get; set; }
}
[JsonSerializable(typeof(TestClass))]
public partial class DemoJsonSerializationContext : JsonSerializerContext
{}
For more information about JsonSerializerContext
see How to use source generation in System.Text.Json.
Breaking changes
JSON is critical for PuppeteerSharp. It's how we communicate with the browser, so changing the library used to perform this communication is quite risky.
Newtonsoft JSON classes were also used in our API, so your code might have some breaking changes.
Newtonsoft's JToken
was replaced with JsonElement
JToken
was the default type for functions like EvaluationFunctionAsync
, EvaluateExpressionAsync
or JsonAsync
, when the generic function was not used.
Before:
var objectPopulated = await Page.EvaluateExpressionAsync("var obj = {a:1}; obj;");
Assert.AreEqual(1, objectPopulated["a"]);
Now:
var objectPopulated = await Page.EvaluateExpressionAsync("var obj = {a:1}; obj;");
Assert.AreEqual(1, objectPopulated.Value.GetProperty("a").GetInt32());
Use JsonElement
instead of object
I found that it's easy to consume JsonElement
instead of objects
that are really JsonElement
s.
Before
var result = await Page.EvaluateExpressionAsync<object[]>("result");
Assert.AreEqual("Meta", result[0]);
Assert.AreEqual("MetaLeft", result[1]);
Assert.AreEqual(true, result[2]);
After
var result = await Page.EvaluateExpressionAsync<JsonElement[]>("result");
Assert.AreEqual("Meta", result[0].GetString());
Assert.AreEqual("MetaLeft", result[1].GetString());
Assert.AreEqual(true, result[2].GetBoolean());
Aria selector changes
Previously, Puppeteer incorrectly normalized whitespaces in ARIA selectors in a way that did not not allow distinguishing between the following two HTML structures:
<p> text<p>
<p><span> </span><span> </span>text<p>
In the first case, the spaces are not part of the element's textual content, and the element should be found via aria/text.
In the second case, the spaces are part of the p element and the query aria/\u00A0\u00A0text
should find it while aria/text
should not. The whitespace normalization in Puppeteer would previously prevent searching for the element with whitespaces in the textual content.
Related: the step 2.F of https://www.w3.org/TR/accname-1.2/#computation-steps defines how child elements contribute to the parent element's computed name.
If you need the old behavior, apply selector.replace(/ +/g, ' ').trim()
to your ARIA selector.
IgnoreHTTPErrors was renamed to AcceptInsecureCerts
This change will get us closer to WebDriver Bidi Support.