microsoft / playwright-dotnet

.NET version of the Playwright testing and automation library.
https://playwright.dev/dotnet/
MIT License
2.47k stars 235 forks source link

[BUG] ResponseEnd value of 0ms #1731

Closed hakito closed 3 years ago

hakito commented 3 years ago

Context:

Code Snippet

Help us help you! Put down a short code snippet that illustrates your bug and that we can run and debug locally. For example:

browserContext.Response += (sender, response) =>

{
    if (response == null || response.Status < 400)
        return;

    var request = response.Request;

    Debug.WriteLine($"HTTP {response.Status} after {request.Timing.ResponseEnd}ms for {request.Url}");
};

Describe the bug

In this case I get always a ResponseEnd time of 0ms (although the ResponseStart is greater than zero). The documentation describes it as a relative value to StartTime. So I'd expect a value of -1 here in case the response value is not yet available or a value greater than ResponseStart.

mxschmitt commented 3 years ago

The documentation also says, that its available as soon as the request has finished, see here: https://playwright.dev/dotnet/docs/api/class-request/#request-timing

In your case changing Response to ResponseFinished should be the easiest way to fix that. Otherwise you could also wait for await request.FinishedAsync()

hakito commented 3 years ago

Yes, but shouldn't be the value -1 when it's not available?

Btw my first attempt was to use the RequestFinished event to identify slow responses (like in my example above)

browserContext.RequestFinished += (sender, request) =>
{
    var response = request.ResponseAsync().Result;
    if (response == null || response.Status < 400 || request.Timing.ResponseEnd < 100)
        return;

    Debug.WriteLine($"HTTP {response.Status} after {request.Timing.ResponseEnd}ms for {request.Url}");
};

But this does not work because request.ResponseAsync().Result causes a deadlock (although the response has completed).

avodovnik commented 3 years ago

You should never use .Result in your code unless you're absolutely sure you know what's going on.

Can you try changing your code, to do:

browserContext.RequestFinished += async (sender, request) =>
{
    var response = await request.ResponseAsync();
    if (response == null || response.Status < 400 || request.Timing.ResponseEnd < 100)
        return;

    Debug.WriteLine($"HTTP {response.Status} after {request.Timing.ResponseEnd}ms for {request.Url}");
};

IF you're still seeing the deadlock at that point, we need to see a bit more info on what you're doing around it.

hakito commented 3 years ago

Yes this works.