Skip to content

Commit aa63c27

Browse files
Meir017kblok
authored andcommitted
Implemented ElementHandle.XPathAsync (a.k.a. $x) (#212)
1 parent 444be11 commit aa63c27

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.Threading.Tasks;
2+
using Xunit;
3+
4+
namespace PuppeteerSharp.Tests.ElementHandleTests
5+
{
6+
[Collection("PuppeteerLoaderFixture collection")]
7+
public class XPathTests : PuppeteerPageBaseTest
8+
{
9+
[Fact]
10+
public async Task ShouldQueryExistingElement()
11+
{
12+
await Page.GoToAsync(TestConstants.ServerUrl + "/playground.html");
13+
await Page.SetContentAsync("<html><body><div class=\"second\"><div class=\"inner\">A</div></div></body></html>");
14+
var html = await Page.QuerySelectorAsync("html");
15+
var second = await html.XPathAsync("./body/div[contains(@class, 'second')]");
16+
var inner = await second[0].XPathAsync("./div[contains(@class, 'inner')]");
17+
var content = await Page.EvaluateFunctionAsync<string>("e => e.textContent", inner[0]);
18+
Assert.Equal("A", content);
19+
}
20+
21+
[Fact]
22+
public async Task ShouldReturnNullForNonExistingElement()
23+
{
24+
await Page.SetContentAsync("<html><body><div class=\"second\"><div class=\"inner\">B</div></div></body></html>");
25+
var html = await Page.QuerySelectorAsync("html");
26+
var second = await html.XPathAsync("/div[contains(@class, 'third')]");
27+
Assert.Empty(second);
28+
}
29+
}
30+
}

lib/PuppeteerSharp/ElementHandle.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,12 @@ internal async Task<ElementHandle[]> QuerySelectorAllAsync(string selector)
139139
return properties.Values.OfType<ElementHandle>().ToArray();
140140
}
141141

142-
internal async Task<ElementHandle[]> XPathAsync(string expression)
142+
/// <summary>
143+
/// Evaluates the XPath expression relative to the elementHandle. If there's no such element, the method will resolve to <c>null</c>.
144+
/// </summary>
145+
/// <param name="expression">Expression to evaluate <see cref="https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate"/></param>
146+
/// <returns>Task which resolves to an array of <see cref="ElementHandle"/></returns>
147+
public async Task<ElementHandle[]> XPathAsync(string expression)
143148
{
144149
var arrayHandle = await ExecutionContext.EvaluateFunctionHandleAsync(
145150
@"(element, expression) => {

0 commit comments

Comments
 (0)