Skip to content

Commit 7a6a42c

Browse files
Meir017kblok
authored andcommitted
Implement Page.QuerySelectorAllHandleAsync(..). EvaluateFunctionAsync() (a.k.a. Page.$$eval) (#198)
1 parent 5817ee4 commit 7a6a42c

File tree

3 files changed

+50
-5
lines changed

3 files changed

+50
-5
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Threading.Tasks;
2+
using Xunit;
3+
4+
namespace PuppeteerSharp.Tests.Page
5+
{
6+
[Collection("PuppeteerLoaderFixture collection")]
7+
public class EvalManyTests : PuppeteerPageBaseTest
8+
{
9+
[Fact]
10+
public async Task ShouldWork()
11+
{
12+
await Page.SetContentAsync("<div>hello</div><div>beautiful</div><div>world!</div>");
13+
var divsCount = await Page.QuerySelectorAllHandleAsync("div").EvaluateFunctionAsync<int>("divs => divs.length");
14+
Assert.Equal(3, divsCount);
15+
}
16+
}
17+
}

lib/PuppeteerSharp/Extensions.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,29 @@ public static async Task<T> EvaluateFunctionAsync<T>(this Task<ElementHandle> el
2424
var newArgs = new object[args.Length + 1];
2525
newArgs[0] = elementHandle;
2626
args.CopyTo(newArgs, 1);
27-
var result = await elementHandle.Page.EvaluateFunctionAsync<T>(pageFunction, newArgs);
27+
var result = await elementHandle.ExecutionContext.EvaluateFunctionAsync<T>(pageFunction, newArgs);
2828
await elementHandle.DisposeAsync();
2929
return result;
3030
}
31+
32+
/// <summary>
33+
/// Runs <paramref name="pageFunction"/> within the frame and passes it the outcome of <paramref name="arrayHandleTask"/> as the first argument. Use only after <see cref="Page.QuerySelectorAllHandleAsync(string)"/>
34+
/// </summary>
35+
/// <typeparam name="T"></typeparam>
36+
/// <param name="arrayHandleTask">A task that returns an <see cref="JSHandle"/> that represents an array of <see cref="ElementHandle"/> that will be used as the first argument in <paramref name="pageFunction"/></param>
37+
/// <param name="pageFunction">Function to be evaluated in browser context</param>
38+
/// <param name="args">Arguments to pass to <c>pageFunction</c></param>
39+
/// <returns>Task which resolves to the return value of <c>pageFunction</c></returns>
40+
public static async Task<T> EvaluateFunctionAsync<T>(this Task<JSHandle> arrayHandleTask, string pageFunction, params object[] args)
41+
{
42+
var arrayHandle = await arrayHandleTask;
43+
44+
var newArgs = new object[args.Length + 1];
45+
newArgs[0] = arrayHandle;
46+
args.CopyTo(newArgs, 1);
47+
var result = await arrayHandle.ExecutionContext.EvaluateFunctionAsync<T>(pageFunction, newArgs);
48+
await arrayHandle.DisposeAsync();
49+
return result;
50+
}
3151
}
3252
}

lib/PuppeteerSharp/Page.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,24 @@ public async Task TapAsync(string selector)
169169
/// <remarks>
170170
/// Shortcut for <c>page.MainFrame.QuerySelectorAsync(selector)</c>
171171
/// </remarks>
172-
public async Task<ElementHandle> QuerySelectorAsync(string selector)
173-
=> await MainFrame.QuerySelectorAsync(selector);
172+
public Task<ElementHandle> QuerySelectorAsync(string selector)
173+
=> MainFrame.QuerySelectorAsync(selector);
174174

175175
/// <summary>
176176
/// Runs <c>document.querySelectorAll</c> within the page. If no elements match the selector, the return value resolve to <see cref="Array.Empty{T}"/>.
177177
/// </summary>
178178
/// <param name="selector">A selector to query page for</param>
179179
/// <returns>Task which resolves to ElementHandles pointing to the frame elements</returns>
180-
public async Task<ElementHandle[]> QuerySelectorAllAsync(string selector)
181-
=> await MainFrame.QuerySelectorAllAsync(selector);
180+
public Task<ElementHandle[]> QuerySelectorAllAsync(string selector)
181+
=> MainFrame.QuerySelectorAllAsync(selector);
182+
183+
/// <summary>
184+
/// A utility function to based used with <see cref="Extensions.EvaluateFunctionAsync{T}(Task{JSHandle}, string, object[])"/>
185+
/// </summary>
186+
/// <param name="selector">A selector to query page for</param>
187+
/// <returns>Task which resolves to a <see cref="JSHandle"/> of <c>document.querySelectorAll</c> result</returns>
188+
public Task<JSHandle> QuerySelectorAllHandleAsync(string selector)
189+
=> EvaluateFunctionHandleAsync("selector => Array.from(document.querySelectorAll(selector))", selector);
182190

183191
/// <summary>
184192
/// Executes a script in browser context

0 commit comments

Comments
 (0)