testcafe-hammerhead: http2 connection resets not handled

What is your Scenario?

Using hammerhead with testcafe fails randomly with ERR_HTTP2_GOAWAY_SESSION errors if host supports http2. See https://github.com/DevExpress/testcafe/issues/6234 Before http2 support was added we did not see any network errors like this. So I suspect it is related to the new http2 integration.

What is the Current behavior?

Unhandled promise rejections if ERR_HTTP2_GOAWAY_SESSION was received. http2 session is not recreated and connection reset is not handled (unlike http1, see https://github.com/DevExpress/testcafe-hammerhead/blob/master/src/request-pipeline/connection-reset-guard.ts)

What is the Expected behavior?

Establish new connection to ensure further requests are working.

What isΒ your public web site URL?

Your website URL (or attach your complete example):

Your complete app code (or attach your test files):
 
Screenshots:

Steps to Reproduce:

Running many testcafe tests against a server which handles http1 and http2 requests.

Your Environment details:

  • node.js version:
  • browser name and version:
  • platform and version:
  • other:

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 5
  • Comments: 19 (2 by maintainers)

Commits related to this issue

Most upvoted comments

We will include this fix in the next minor release - v1.15.2. In the meantime, you can use v1.15.2-rc.1, which contains the fix.

I can confirm that with 1.15.2-rc.1 the issue does not occur anymore! Thanks! Looking forward to 1.15.2

If a release for this would be possible, I would highly appreciate it! This has been blocking us for quite some time πŸ˜ƒ If not, we’ll just wait until someone with write access has time πŸ˜ƒ

I was able to create a reproducible case, here you go:

import { Selector } from 'testcafe';
fixture `Many tests`
    .page `https://console.ory.sh`;
for(let i = 0; i < 500; i++) {
    test(`Test No. ${i}`, async t => {
        await t
            .navigateTo('https://console.ory.sh/login')
            .click('a[href="/registration"]')
            .click(Selector('h4').withText('Become an early access member.'))
            .click('a[href="/login"]')
    });
}

I believe the problem comes from navigateTo

$ NODE_TLS_REJECT_UNAUTHORIZED=0 testcafe --config-file .testcaferc.record.json

 Many tests
(node:62838) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node --trace-warnings ...` to show where the warning was created)
 βœ“ Test No. 0  (15s)
 βœ“ Test No. 1  (15s)
 βœ“ Test No. 2  (13s)
 βœ“ Test No. 3  (13s)
 βœ“ Test No. 4  (12s)
 βœ“ Test No. 5  (13s)
 βœ“ Test No. 6  (12s)
 βœ“ Test No. 7  (12s)
 βœ“ Test No. 8  (12s)
 βœ“ Test No. 9  (14s)
 βœ“ Test No. 10  (13s)
 βœ“ Test No. 11  (12s)
 βœ“ Test No. 12  (12s)
 βœ“ Test No. 13  (12s)
 βœ“ Test No. 14  (12s)
 βœ“ Test No. 15  (13s)
 βœ“ Test No. 16  (11s)
 βœ“ Test No. 17  (11s)
 βœ“ Test No. 18  (11s)
 βœ“ Test No. 19  (11s)
 βœ“ Test No. 20  (12s)
 βœ“ Test No. 21  (11s)
 βœ“ Test No. 22  (12s)
 βœ“ Test No. 23  (13s)
 βœ“ Test No. 24  (11s)
 βœ“ Test No. 25  (12s)
 βœ– Test No. 26  (11s)

   1) Unhandled promise rejection:
      
      Error [ERR_HTTP2_GOAWAY_SESSION]: New streams cannot be created after receiving a GOAWAY
      at new NodeError (node:internal/errors:363:5)
      at ClientHttp2Session.request (node:internal/http2/core:1705:13)
      at DestinationRequest._sendRealThroughHttp2 (/Users/foobar/workspace/go/src/github.com/ory-corp/cloud/test/e2e/node_modules/testcafe-hammerhead/lib/request-pipeline/destination-request/index.js:47:32)
      at DestinationRequest._send (/Users/foobar/workspace/go/src/github.com/ory-corp/cloud/test/e2e/node_modules/testcafe-hammerhead/lib/request-pipeline/destination-request/index.js:99:18)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)

      Browser: Firefox 89.0 / macOS 10.15


 Many tests Duration (3m 00s)

 94/120 failed (3m 00s)
 Total time (3m 08s)
  • Testcafe version: 1.14.2
  • Node version: v16.3.0 & v14

testcaferc.record.json

{
  "screenshots": {
    "path": "screenshots"
  },
  "videoOptions": {
    "failedOnly": false,
    "pathPattern": "${FIXTURE}/${TEST}/${DATE}-${TIME}-${FILE_INDEX}.mp4"
  },
  "videoEncodingOptions": {
    "vcodec": "libx264",
    "preset": "veryfast"
  },
  "quarantine": false,
  "browsers": "firefox:headless",
  "videoPath": "videos",
  "disableScreenshots": false,
  "stopOnFirstFail": true,
  "speed": 1,
  "selectorTimeout": 20000,
  "assertionTimeout": 10000,
  "pageLoadTimeout": 20000,
  "pageRequestTimeout": 30000,
  "retryTestPages": true,
  "disableMultipleWindows": true,
  "src": ["tests/github.ts"],
  "skipJsErrors": true,
  "reporter": "spec-time",
  "concurrency": 2,
  "hostname": "localhost"
}