Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ public async Task ShouldRespectTimeout()
Assert.Equal("waiting for function failed: timeout 10 ms exceeded", exception.Message);
}

[PuppeteerTest("waittask.spec.ts", "Frame.waitForSelector", "should respect timeout")]
[PuppeteerFact]
public async Task ShouldRespectTimeoutReturnNull()
{
var result = await DevToolsContext.WaitForExpressionAsync("false", new WaitForFunctionOptions { Timeout = 10, TimeoutReturnsNull = true });

Assert.Null(result);
}

[PuppeteerTest("waittask.spec.ts", "Frame.waitForSelector", "should have an error message specifically for awaiting an element to be hidden")]
[PuppeteerFact]
public async Task ShouldHaveAnErrorMessageSpecificallyForAwaitingAnElementToBeHidden()
Expand Down
5 changes: 4 additions & 1 deletion lib/PuppeteerSharp/DOMWorld.cs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ internal async Task<JSHandle> WaitForFunctionAsync(string script, WaitForFunctio
options.Polling,
options.PollingInterval,
options.Timeout ?? _timeoutSettings.Timeout,
options.TimeoutReturnsNull,
args);

return await waitTask
Expand All @@ -380,7 +381,8 @@ internal async Task<JSHandle> WaitForExpressionAsync(string script, WaitForFunct
"function",
options.Polling,
options.PollingInterval,
options.Timeout ?? _timeoutSettings.Timeout);
options.Timeout ?? _timeoutSettings.Timeout,
options.TimeoutReturnsNull);

return await waitTask
.Task
Expand Down Expand Up @@ -437,6 +439,7 @@ function hasVisibleBoundingBox() {
polling,
null,
timeout,
options.TimeoutReturnsNull,
new object[] { selectorOrXPath, isXPath, options.Visible, options.Hidden });

var handle = await waitTask.Task.ConfigureAwait(false);
Expand Down
6 changes: 6 additions & 0 deletions lib/PuppeteerSharp/WaitForFunctionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ public class WaitForFunctionOptions
/// </summary>
public int? Timeout { get; set; }

/// <summary>
/// If set to <see langword="true" />, the method will return <see langword="null"/> if the timeout is reached.
/// The default (<see langword="false" />) will throw a <see cref="WaitTaskTimeoutException"/> if the timeout is reached."/>
/// </summary>
public bool TimeoutReturnsNull { get; set; } = false;

/// <summary>
/// An interval at which the <c>pageFunction</c> is executed. defaults to <see cref="WaitForFunctionPollingOption.Raf"/>
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions lib/PuppeteerSharp/WaitForSelectorOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ public class WaitForSelectorOptions
/// </summary>
public int? Timeout { get; set; }

/// <summary>
/// If set to <see langword="true" />, the method will return <see langword="null"/> if the timeout is reached.
/// The default (<see langword="false" />) will throw a <see cref="WaitTaskTimeoutException"/> if the timeout is reached."/>
/// </summary>
public bool TimeoutReturnsNull { get; set; } = false;

/// <summary>
/// Wait for element to be present in DOM and to be visible.
/// </summary>
Expand Down
16 changes: 14 additions & 2 deletions lib/PuppeteerSharp/WaitTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ internal class WaitTask : IDisposable
private readonly int _timeout;
private readonly object[] _args;
private readonly string _title;
private readonly bool _timeoutReturnsNull;
private readonly Task _timeoutTimer;

private readonly CancellationTokenSource _cts;
Expand Down Expand Up @@ -107,6 +108,7 @@ internal WaitTask(
WaitForFunctionPollingOption polling,
int? pollingInterval,
int timeout,
bool timeoutReturnsNull,
object[] args = null)
{
if (string.IsNullOrEmpty(predicateBody))
Expand All @@ -125,6 +127,7 @@ internal WaitTask(
_timeout = timeout;
_args = args ?? Array.Empty<object>();
_title = title;
_timeoutReturnsNull = timeoutReturnsNull;

_cts = new CancellationTokenSource();

Expand All @@ -136,7 +139,7 @@ internal WaitTask(
{
_timeoutTimer = System.Threading.Tasks.Task.Delay(timeout, _cts.Token)
.ContinueWith(
_ => Terminate(new WaitTaskTimeoutException(timeout, title)),
_ => Terminate(_timeoutReturnsNull ? null : new WaitTaskTimeoutException(timeout, title)),
TaskScheduler.Default);
}

Expand Down Expand Up @@ -212,7 +215,16 @@ await _world.EvaluateFunctionAsync<bool>("s => !s", success)
internal void Terminate(Exception exception)
{
_terminated = true;
_taskCompletion.TrySetException(exception);

if (exception == null)
{
_taskCompletion.TrySetResult(null);
}
else
{
_taskCompletion.TrySetException(exception);
}

Cleanup();
}

Expand Down