Skip to content

Commit

Permalink
Injected: Use handle instead of globals
Browse files Browse the repository at this point in the history
  • Loading branch information
kblok committed Apr 15, 2023
1 parent 32fe8d4 commit 4e87c48
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 319 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
</ItemGroup>
<Target Name="testCertCheck" BeforeTargets="BeforeBuild" Condition="!Exists('testCert.cer')" >
<Target Name="testCertCheck" BeforeTargets="BeforeBuild" Condition="!Exists('testCert.cer')">
<Error Text="Follow https://github.com/hardkoded/puppeteer-sharp/blob/master/CONTRIBUTING.md#getting-setup to setup a development certificate." />
</Target>
</Project>
27 changes: 22 additions & 5 deletions lib/PuppeteerSharp.Tests/InjectedTests/InjectedTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Reflection.Metadata;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using PuppeteerSharp.Tests.Attributes;
using PuppeteerSharp.Xunit;
using Xunit;
Expand All @@ -14,15 +15,31 @@ public InjectedTests(ITestOutputHelper output) : base(output)
{
}

[PuppeteerTest("injected.spec.ts", "InjectedUtil tests", "should work")]
[PuppeteerTest("injected.spec.ts", "PuppeteerUtil tests", "should work")]
[PuppeteerFact]
public async Task ShouldWork()
{
var result = await (Page.MainFrame as Frame)
.SecondaryWorld.EvaluateFunctionAsync<bool>(@"() => {
return typeof InjectedUtil === 'object';
}");
var world = (Page.MainFrame as Frame).PuppeteerWorld;
var result = await world.EvaluateFunctionAsync<bool>(@"
PuppeteerUtil => {
return typeof PuppeteerUtil === 'object';
}",
await world.PuppeteerUtil);
Assert.True(result);
}

[PuppeteerTest("injected.spec.ts", "createFunction tests", "should work")]
[PuppeteerFact]
public async Task CreateFunctionShouldWork()
{
var world = (Page.MainFrame as Frame).PuppeteerWorld;
var result = await (Page.MainFrame as Frame)
.PuppeteerWorld.EvaluateFunctionAsync<int>(@"({createFunction}, fnString) => {
return createFunction(fnString)(4);
}",
await world.PuppeteerUtil,
"() => 4");
Assert.Equal(4, result);
}
}
}
4 changes: 2 additions & 2 deletions lib/PuppeteerSharp.Tests/PuppeteerSharp.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<Folder Include="EmulationTests\" />
<Folder Include="FixturesTests\" />
<Folder Include="HeadfulTests\" />
<Folder Include="InjectedTests\" />
<Folder Include="PuppeteerUtilTests\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PuppeteerSharp.TestServer\PuppeteerSharp.TestServer.csproj" />
Expand All @@ -53,6 +53,6 @@
<None Remove="Emulation\" />
<None Remove="FixturesTests\" />
<None Remove="HeadfulTests\" />
<None Remove="InjectedTests\" />
<None Remove="PuppeteerUtilTests\" />
</ItemGroup>
</Project>
6 changes: 3 additions & 3 deletions lib/PuppeteerSharp/AriaQueryHandlerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ async Task<IElementHandle> QueryOne(IElementHandle element, string selector)
return null;
}

return await ((ElementHandle)element).Frame.SecondaryWorld.AdoptBackendNodeAsync(id).ConfigureAwait(false);
return await ((ElementHandle)element).Frame.PuppeteerWorld.AdoptBackendNodeAsync(id).ConfigureAwait(false);
}

async Task<IElementHandle> WaitFor(IElementHandle root, string selector, WaitForSelectorOptions options)
{
var frame = ((ElementHandle)root).Frame;
var element = (await frame.SecondaryWorld.AdoptHandleAsync(root).ConfigureAwait(false)) as IElementHandle;
var element = (await frame.PuppeteerWorld.AdoptHandleAsync(root).ConfigureAwait(false)) as IElementHandle;

Task<IElementHandle> Func(string selector) => QueryOne(element, selector);

Expand All @@ -50,7 +50,7 @@ async Task<IElementHandle> WaitFor(IElementHandle root, string selector, WaitFor
Function = (Func<string, Task<IElementHandle>>)Func,
};

return await frame.SecondaryWorld.WaitForSelectorInPageAsync(
return await frame.PuppeteerWorld.WaitForSelectorInPageAsync(
@"(_, selector) => globalThis.ariaQuerySelector(selector)",
selector,
options,
Expand Down
4 changes: 2 additions & 2 deletions lib/PuppeteerSharp/CustomQueriesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ private static InternalQueryHandler MakeQueryHandler(CustomQueryHandler handler)
internalHandler.WaitFor = async (IElementHandle root, string selector, WaitForSelectorOptions options) =>
{
var frame = (root as ElementHandle).Frame;
var element = await frame.SecondaryWorld.AdoptHandleAsync(root).ConfigureAwait(false);
var element = await frame.PuppeteerWorld.AdoptHandleAsync(root).ConfigureAwait(false);

return await frame.SecondaryWorld.WaitForSelectorInPageAsync(handler.QueryOne, selector, options).ConfigureAwait(false);
return await frame.PuppeteerWorld.WaitForSelectorInPageAsync(handler.QueryOne, selector, options).ConfigureAwait(false);
};
}

Expand Down
4 changes: 2 additions & 2 deletions lib/PuppeteerSharp/ElementHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ public async Task<Stream> ScreenshotStreamAsync(ScreenshotOptions options)
public async Task<IElementHandle> WaitForSelectorAsync(string selector, WaitForSelectorOptions options = null)
{
var frame = (Frame)ExecutionContext.Frame;
var secondaryContext = await frame.SecondaryWorld.GetExecutionContextAsync().ConfigureAwait(false);
var secondaryContext = await frame.PuppeteerWorld.GetExecutionContextAsync().ConfigureAwait(false);
var adoptedRoot = await secondaryContext.AdoptElementHandleAsync(this).ConfigureAwait(false);
options ??= new WaitForSelectorOptions();
options.Root = adoptedRoot;

var handle = await frame.SecondaryWorld.WaitForSelectorAsync(selector, options).ConfigureAwait(false);
var handle = await frame.PuppeteerWorld.WaitForSelectorAsync(selector, options).ConfigureAwait(false);
await adoptedRoot.DisposeAsync().ConfigureAwait(false);
if (handle == null)
{
Expand Down
5 changes: 5 additions & 0 deletions lib/PuppeteerSharp/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ private async Task<object> FormatArgumentAsync(object arg)
arg = await tcs.Task.ConfigureAwait(false);
}

if (arg is LazyArg lazyArg)
{
arg = await lazyArg(this).ConfigureAwait(false);
}

switch (arg)
{
case BigInteger big:
Expand Down
34 changes: 17 additions & 17 deletions lib/PuppeteerSharp/Frame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public List<IFrame> ChildFrames

internal IsolatedWorld MainWorld { get; private set; }

internal IsolatedWorld SecondaryWorld { get; private set; }
internal IsolatedWorld PuppeteerWorld { get; private set; }

internal CDPSession Client { get; private set; }

Expand Down Expand Up @@ -110,7 +110,7 @@ public async Task<IExecutionContext> GetExecutionContextAsync()
/// <inheritdoc/>
public async Task<IElementHandle> WaitForSelectorAsync(string selector, WaitForSelectorOptions options = null)
{
var handle = await SecondaryWorld.WaitForSelectorAsync(selector, options).ConfigureAwait(false);
var handle = await PuppeteerWorld.WaitForSelectorAsync(selector, options).ConfigureAwait(false);
if (handle == null)
{
return null;
Expand All @@ -125,7 +125,7 @@ public async Task<IElementHandle> WaitForSelectorAsync(string selector, WaitForS
/// <inheritdoc/>
public async Task<IElementHandle> WaitForXPathAsync(string xpath, WaitForSelectorOptions options = null)
{
var handle = await SecondaryWorld.WaitForXPathAsync(xpath, options).ConfigureAwait(false);
var handle = await PuppeteerWorld.WaitForXPathAsync(xpath, options).ConfigureAwait(false);
if (handle == null)
{
return null;
Expand Down Expand Up @@ -163,7 +163,7 @@ public Task<IJSHandle> WaitForExpressionAsync(string script, WaitForFunctionOpti
}

/// <inheritdoc/>
public Task<string[]> SelectAsync(string selector, params string[] values) => SecondaryWorld.SelectAsync(selector, values);
public Task<string[]> SelectAsync(string selector, params string[] values) => PuppeteerWorld.SelectAsync(selector, values);

/// <inheritdoc/>
public Task<IJSHandle> QuerySelectorAllHandleAsync(string selector)
Expand Down Expand Up @@ -199,7 +199,7 @@ public async Task<IElementHandle> AddStyleTagAsync(AddTagOptions options)
content += "//# sourceURL=" + options.Path.Replace("\n", string.Empty);
}

var handle = await SecondaryWorld.EvaluateFunctionHandleAsync(
var handle = await PuppeteerWorld.EvaluateFunctionHandleAsync(
@"async (puppeteerUtil, url, id, type, content) => {
const createDeferredPromise = puppeteerUtil.createDeferredPromise;
const promise = createDeferredPromise();
Expand Down Expand Up @@ -235,7 +235,7 @@ public async Task<IElementHandle> AddStyleTagAsync(AddTagOptions options)
await promise;
return element;
}",
SecondaryWorld.PuppeteerUtil,
PuppeteerWorld.PuppeteerUtil,
options.Url,
options.Id,
options.Type,
Expand Down Expand Up @@ -265,7 +265,7 @@ public async Task<IElementHandle> AddScriptTagAsync(AddTagOptions options)
content += "//# sourceURL=" + options.Path.Replace("\n", string.Empty);
}

var handle = await SecondaryWorld.EvaluateFunctionHandleAsync(
var handle = await PuppeteerWorld.EvaluateFunctionHandleAsync(
@"async (puppeteerUtil, url, id, type, content) => {
const createDeferredPromise = puppeteerUtil.createDeferredPromise;
const promise = createDeferredPromise();
Expand Down Expand Up @@ -300,7 +300,7 @@ public async Task<IElementHandle> AddScriptTagAsync(AddTagOptions options)
await promise;
return script;
}",
SecondaryWorld.PuppeteerUtil,
PuppeteerWorld.PuppeteerUtil,
options.Url,
options.Id,
options.Type,
Expand All @@ -310,28 +310,28 @@ public async Task<IElementHandle> AddScriptTagAsync(AddTagOptions options)
}

/// <inheritdoc/>
public Task<string> GetContentAsync() => SecondaryWorld.GetContentAsync();
public Task<string> GetContentAsync() => PuppeteerWorld.GetContentAsync();

/// <inheritdoc/>
public Task SetContentAsync(string html, NavigationOptions options = null)
=> SecondaryWorld.SetContentAsync(html, options);
=> PuppeteerWorld.SetContentAsync(html, options);

/// <inheritdoc/>
public Task<string> GetTitleAsync() => SecondaryWorld.GetTitleAsync();
public Task<string> GetTitleAsync() => PuppeteerWorld.GetTitleAsync();

/// <inheritdoc/>
public Task ClickAsync(string selector, ClickOptions options = null)
=> SecondaryWorld.ClickAsync(selector, options);
=> PuppeteerWorld.ClickAsync(selector, options);

/// <inheritdoc/>
public Task HoverAsync(string selector) => SecondaryWorld.HoverAsync(selector);
public Task HoverAsync(string selector) => PuppeteerWorld.HoverAsync(selector);

/// <inheritdoc/>
public Task FocusAsync(string selector) => SecondaryWorld.FocusAsync(selector);
public Task FocusAsync(string selector) => PuppeteerWorld.FocusAsync(selector);

/// <inheritdoc/>
public Task TypeAsync(string selector, string text, TypeOptions options = null)
=> SecondaryWorld.TypeAsync(selector, text, options);
=> PuppeteerWorld.TypeAsync(selector, text, options);

internal void AddChildFrame(Frame frame)
{
Expand Down Expand Up @@ -381,7 +381,7 @@ internal void Detach()
{
Detached = true;
MainWorld.Detach();
SecondaryWorld.Detach();
PuppeteerWorld.Detach();
if (ParentFrame != null)
{
((Frame)ParentFrame).RemoveChildFrame(this);
Expand All @@ -399,7 +399,7 @@ internal void UpdateClient(CDPSession client)
this,
FrameManager.TimeoutSettings);

SecondaryWorld = new IsolatedWorld(
PuppeteerWorld = new IsolatedWorld(
Client,
FrameManager,
this,
Expand Down
4 changes: 2 additions & 2 deletions lib/PuppeteerSharp/FrameManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -332,12 +332,12 @@ private async Task OnExecutionContextCreatedAsync(ContextPayload contextPayload,
{
world = frame.MainWorld;
}
else if (contextPayload.Name == UtilityWorldName && !frame.SecondaryWorld.HasContext)
else if (contextPayload.Name == UtilityWorldName && !frame.PuppeteerWorld.HasContext)
{
// In case of multiple sessions to the same target, there's a race between
// connections so we might end up creating multiple isolated worlds.
// We can use either.
world = frame.SecondaryWorld;
world = frame.PuppeteerWorld;
}
}

Expand Down
Loading

0 comments on commit 4e87c48

Please sign in to comment.