Testcafe: [hammerhead] Endless refresh loop after auth

Created on 19 Sep 2020  Â·  4Comments  Â·  Source: DevExpress/testcafe

What is your Test Scenario?

Typescript React app behind auth. Pointing local TestCafe to the remote server where the app is built and deployed.

What is the Current behavior?

After logging in, TestCafe hits the page behind auth and gets stuck in an endless refresh loop with the following errors

hammerhead.js:11163 TypeError: Cannot use 'in' operator to search for 'hammerhead|document-title-storage|internal-prop-name' in undefined
    at DocumentTitleStorage.isElementProcessed (hammerhead.js:17552)
    at DocumentTitleStorage.setTitleElementPropertyValue (hammerhead.js:17541)
    at DocumentTitleStorage._setValueForFirstTitleElement (hammerhead.js:17510)
    at DocumentTitleStorage.setTitle (hammerhead.js:17532)
    at HTMLDocument.setter [as title] (hammerhead.js:17383)
    at t.updateTitle (main.5e09327a46e392355656.g.js:2)
    at t.componentDidMount (main.5e09327a46e392355656.g.js:2)
    at ju (vendor.108d472270afdf9ba28a.g.js:85)
    at t.unstable_runWithPriority (vendor.108d472270afdf9ba28a.g.js:93)
    at Ko (vendor.108d472270afdf9ba28a.g.js:85)

What is the Expected behavior?

TestCafe should not exhibit this error.

What is your web application and your TestCafe test code?

Unable to provide the auth for the app, but I am suspecting Hammerhead is having trouble processing bundle in the app code. I am looking for a pointer where to debug next because built code is outside the context of TestCafe. Also, right after installing TestCafe, project cannot be built due to ts errors that did not exist before installing test cafe. Npm remove testcafe and typescript errors are gone!


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

 /* eslint-disable no-console */
const createTestCafe = require('testcafe');

let testcafe = null
const isCiEnv = process.env.CI === 'true'

const exit = async err => {
  console.log('Exiting...')
  if (testcafe) {
    console.log('Closing TestCafe...')
    testcafe.close()
  }
  console.log('Exiting process...')
  process.exit(err ? 1 : 0)
}

console.log('Is CI ENV: ', isCiEnv)
console.log('Creating TestCafe...')

createTestCafe('localhost', 1337, 1338, null, true)
  .then(tc => {
    testcafe = tc
  })
  .then(() => {
    console.log('Creating TestCafe Runner...')
    return testcafe.createRunner()
  })
  .then(runner => {
    console.log('About to start TestCafe Runner...')
    return runner
      .src(['./tools/e2e/fixtures/*.ts'])
      .browsers({
        path: isCiEnv
          ? '/usr/bin/chromium-browser'
          : 'Chrome',
        cmd: isCiEnv
          ? '--no-sandbox --disable-gpu'
          : '--incognito'
      })
      .screenshots('screenshots', true)
      .run({
        selectorTimeout: 25000,
        assertionTimeout: 25000,
        stopOnFirstFail: true,
        debugOnFail: true,
        disablePageCaching: true,
      })
  })
  .then(failedCount => {
    console.log('failed count:', failedCount)
    return exit(failedCount)
  })
  .catch(err => {
    console.error('ERR', err)
    return exit(err)
  })
import { Selector } from 'testcafe';
import { BASE_URL } from '../constants';
import { USERNAME, PASSWORD } from '../env';
import { admin } from '../utils/roles';

fixture.only`Reports`
  .page`${BASE_URL}/d/login.php`

test('Shows table', async t => {
  await t
      // using `useRole` with fixture.page being legacy_dashboard.php will login and redirect back to the login instead back to the legacy_dashboard page
    // .useRole(admin) 
    .debug()
    .typeText('#username', USERNAME)
    .typeText('#password', PASSWORD)
    .click('#login_submit')
    .navigateTo(`${BASE_URL}/d/legacy_dashboard.php`)

  const elementExists = Selector('.manage-alert-page .data-table').exists;
  await t.expect(elementExists).ok();
});


Your complete configuration file (if any):


Since I am suspecting on typescript here, here's tsconfig.json

{
  "compilerOptions": {
    "lib": [
      "es2016",
      "es2015",
      "dom"
    ],
    "module": "commonjs",
    "noImplicitReturns": true,
    "outDir": ".compiled",
    "sourceMap": true,
    "target": "es5",
    "jsx": "react",
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "moduleResolution": "node"
  },
  "include": [
    "./custom-typings/**/*.d.ts",
    "./src/**/*.ts",
    "./src/**/*.tsx",
    "node_modules/@gpsi/**/*"
  ],
  "exclude": [
    "./src/client/"
  ]
}

Also, this is the html page source:

<!DOCTYPE html><html><head><meta class="charset-hammerhead-shadow-ui" charset="utf-8">
  <link rel="shortcut icon" href="http://localhost:1337/hgrwRCPCw/https://vanja.phx.gpsinsight.com/label/forward_favicon.ico" type="image/x-icon" href-hammerhead-stored-value="/label/forward_favicon.ico">
  <link rel="stylesheet" type="text/css" class="ui-stylesheet-hammerhead-shadow-ui" href="http://localhost:1337/testcafe-ui-styles.css"><script type="text/javascript" class="script-hammerhead-shadow-ui" charset="UTF-8" src="http://localhost:1337/hammerhead.js"></script><script type="text/javascript" class="script-hammerhead-shadow-ui" charset="UTF-8" src="http://localhost:1337/testcafe-core.js"></script><script type="text/javascript" class="script-hammerhead-shadow-ui" charset="UTF-8" src="http://localhost:1337/testcafe-ui.js"></script><script type="text/javascript" class="script-hammerhead-shadow-ui" charset="UTF-8" src="http://localhost:1337/testcafe-automation.js"></script><script type="text/javascript" class="script-hammerhead-shadow-ui" charset="UTF-8" src="http://localhost:1337/testcafe-driver.js"></script><script type="text/javascript" class="script-hammerhead-shadow-ui" charset="UTF-8" src="http://localhost:1337/task.js"></script><script type="text/javascript">/*hammerhead|script|start*/if (typeof window !== 'undefined' && window){window['hammerhead|process-dom-method'] && window['hammerhead|process-dom-method']();if (window.__get$ && typeof __get$ === 'undefined')var __get$Loc = window.__get$Loc,__set$Loc = window.__set$Loc,__set$ = window.__set$,__get$ = window.__get$,__call$ = window.__call$,__get$Eval = window.__get$Eval,__proc$Script = window.__proc$Script,__proc$Html = window.__proc$Html,__get$PostMessage = window.__get$PostMessage,__get$ProxyUrl = window.__get$ProxyUrl,__rest$Array = window.__rest$Array,__rest$Object = window.__rest$Object;} else {if (typeof __get$ === 'undefined')var __get$Loc = function(l){return l},__set$Loc = function(l,v){return l = v},__set$ = function(o,p,v){return o[p] = v},__get$ = function(o,p){return o[p]},__call$ = function(o,p,a){return o[p].apply(o,a)},__get$Eval = function(e){return e},__proc$Script = function(s){return s},__proc$Html = function(h){return h},__get$PostMessage = function(w,p){return arguments.length===1?w.postMessage:p},__get$ProxyUrl = function(u,d){return u},__rest$Array = function(a,i){return Array.prototype.slice.call(a, i)},__rest$Object = function(o,p){var k=Object.keys(o),n={};for(var i=0;i<k.length;++i)if(p.indexOf(k[i])<0)n[k[i]]=o[k[i]];return n};if (typeof importScripts !== "undefined" && /\[native code]/g.test(importScripts.toString()))importScripts(location.origin + "/worker-hammerhead.js");}/*hammerhead|script|processing-header-end*/

    document.SERVER_CONFIGURATION = {"db":"a", "redacted":true};

/*hammerhead|script|end*/</script>
</head>

<body><script class="self-removing-script-hammerhead-shadow-ui">(function () {if (window["%hammerhead%"])window["%hammerhead%"].sandbox.node.raiseBodyCreatedEvent();var currentScript = document.currentScript;var scriptsLength;var scripts;if (!currentScript) {var hammerhead;try {hammerhead = parent["%hammerhead%"] || window["%hammerhead%"];}catch (e) {hammerhead = window["%hammerhead%"];}if (hammerhead) {try {scripts       = hammerhead.nativeMethods.documentScriptsGetter.call(document);scriptsLength = hammerhead.nativeMethods.htmlCollectionLengthGetter.call(scripts);}catch (e) {}}scripts       = scripts || document.scripts;scriptsLength = scriptsLength !== void 0 ? scriptsLength : scripts.length;currentScript = scripts[scriptsLength - 1];}currentScript.parentNode.removeChild(currentScript);})();</script>
<div id="app"></div>
<div id="portal-root"></div>
<script>/*hammerhead|script|start*/if (typeof window !== 'undefined' && window){window['hammerhead|process-dom-method'] && window['hammerhead|process-dom-method']();if (window.__get$ && typeof __get$ === 'undefined')var __get$Loc = window.__get$Loc,__set$Loc = window.__set$Loc,__set$ = window.__set$,__get$ = window.__get$,__call$ = window.__call$,__get$Eval = window.__get$Eval,__proc$Script = window.__proc$Script,__proc$Html = window.__proc$Html,__get$PostMessage = window.__get$PostMessage,__get$ProxyUrl = window.__get$ProxyUrl,__rest$Array = window.__rest$Array,__rest$Object = window.__rest$Object;} else {if (typeof __get$ === 'undefined')var __get$Loc = function(l){return l},__set$Loc = function(l,v){return l = v},__set$ = function(o,p,v){return o[p] = v},__get$ = function(o,p){return o[p]},__call$ = function(o,p,a){return o[p].apply(o,a)},__get$Eval = function(e){return e},__proc$Script = function(s){return s},__proc$Html = function(h){return h},__get$PostMessage = function(w,p){return arguments.length===1?w.postMessage:p},__get$ProxyUrl = function(u,d){return u},__rest$Array = function(a,i){return Array.prototype.slice.call(a, i)},__rest$Object = function(o,p){var k=Object.keys(o),n={};for(var i=0;i<k.length;++i)if(p.indexOf(k[i])<0)n[k[i]]=o[k[i]];return n};if (typeof importScripts !== "undefined" && /\[native code]/g.test(importScripts.toString()))importScripts(location.origin + "/worker-hammerhead.js");}/*hammerhead|script|processing-header-end*/
document.CONFIGURATION = {"API_ROOT":"https://vanja.phx.gpsinsight.com/server","WEB_ROOT":"https://vanja.phx.gpsinsight.com","GOOGLE_API_URL":"https://maps.googleapis.com/maps/api/js?v=3.38&libraries=geometry&client=gme-gpsinsightllc&channel=gpsi-a_gps","GPSI_PAGE":"d/manage_alerts.php","PHPSESSID":"","token":"","USERNAME":"","PASSWORD":"","WHY_DID_YOU_RERENDER_ENABLED":true}
/*hammerhead|script|end*/</script>
<link href="http://localhost:1337/hgrwRCPCw/https://vanja.phx.gpsinsight.com/common/css/main.d4b155827a3f18b63ae4.g.css" rel="stylesheet" href-hammerhead-stored-value="/common/css/main.d4b155827a3f18b63ae4.g.css">
<script src="http://localhost:1337/hgrwRCPCw!s!utf-8/https://vanja.phx.gpsinsight.com/common/js/main.38764e98d2c3c48975b9.g.js" src-hammerhead-stored-value="/common/js/main.38764e98d2c3c48975b9.g.js"></script>
<script src="http://localhost:1337/hgrwRCPCw!s!utf-8/https://vanja.phx.gpsinsight.com/common/js/vendor.8dd3fd41cdbd2891f879.g.js" src-hammerhead-stored-value="/common/js/vendor.8dd3fd41cdbd2891f879.g.js"></script>
</body></html>


Your complete test report:

⇒  npm run test:e2e

> [email protected] test:e2e /Users/vanjagavric/Sites/portal-react
> node tools/e2e/index.ts

Is CI ENV:  false
Creating TestCafe...
Creating TestCafe Runner...
About to start TestCafe Runner...
 Running tests in:
 - Chrome 85.0.4183.102 / macOS 10.15.6

 Alerts

----
Chrome 85.0.4183.102 / macOS 10.15.6
DEBUGGER PAUSE ON FAILED TEST:
A JavaScript error occurred on "https://vanja.phx.gpsinsight.com/d/legacy_dashboard.php".
Repeat test actions in the browser and check the console for errors.
If you see this error, it means that the tested website caused it. You can fix it or disable tracking JavaScript errors in TestCafe. To do the
latter, enable the "--skip-js-errors" option.
If this error does not occur, please write a new issue at:
"https://github.com/DevExpress/testcafe/issues/new?template=bug-report.md".

JavaScript error details:
TypeError: Cannot use 'in' operator to search for 'hammerhead|document-title-storage|internal-prop-name' in undefined
    at DocumentTitleStorage.isElementProcessed (http://localhost:1337/hammerhead.js:17552:45)
 ✖ Shows table (screenshots:
 /Users/vanjagavric/Sites/portal-react/screenshots/2020-09-18_22-01-23/test-1/Chrome_85.0.4183.102_macOS_10.15.6/errors/1.png)

   1) A JavaScript error occurred on "https://vanja.phx.gpsinsight.com/d/legacy_dashboard.php".
      Repeat test actions in the browser and check the console for errors.
      If you see this error, it means that the tested website caused it. You can fix it or disable tracking JavaScript errors in TestCafe.
      To do the latter, enable the "--skip-js-errors" option.
      If this error does not occur, please write a new issue at:
      "https://github.com/DevExpress/testcafe/issues/new?template=bug-report.md".

      JavaScript error details:
      TypeError: Cannot use 'in' operator to search for 'hammerhead|document-title-storage|internal-prop-name' in undefined
          at DocumentTitleStorage.isElementProcessed (http://localhost:1337/hammerhead.js:17552:45)
          at DocumentTitleStorage.setTitleElementPropertyValue (http://localhost:1337/hammerhead.js:17541:22)
          at DocumentTitleStorage._setValueForFirstTitleElement (http://localhost:1337/hammerhead.js:17510:18)
          at DocumentTitleStorage.setTitle (http://localhost:1337/hammerhead.js:17532:18)
          at HTMLDocument.setter [as title] (http://localhost:1337/hammerhead.js:17383:55)
          at t.updateTitle (https://vanja.phx.gpsinsight.com/common/js/main.38764e98d2c3c48975b9.g.js:2:567307)
          at t.componentDidMount (https://vanja.phx.gpsinsight.com/common/js/main.38764e98d2c3c48975b9.g.js:2:566966)
          at kl (https://vanja.phx.gpsinsight.com/common/js/vendor.8dd3fd41cdbd2891f879.g.js:58:103683)
          at t.unstable_runWithPriority (https://vanja.phx.gpsinsight.com/common/js/vendor.8dd3fd41cdbd2891f879.g.js:66:3606)
          at Uo (https://vanja.phx.gpsinsight.com/common/js/vendor.8dd3fd41cdbd2891f879.g.js:58:46635)

      Browser: Chrome 85.0.4183.102 / macOS 10.15.6
      Screenshot:
      /Users/vanjagavric/Sites/portal-react/screenshots/2020-09-18_22-01-23/test-1/Chrome_85.0.4183.102_macOS_10.15.6/errors/1.png

         15 |    // .useRole(admin) 
         16 |    .debug()
         17 |    .typeText('#username', '')
         18 |    .typeText('#password', '')
         19 |    .click('#login_submit')
       > 20 |    .navigateTo(`${BASE_URL}/d/legacy_dashboard.php`)
         21 |
         22 |  const elementExists = Selector('.manage-alert-page .data-table').exists;
         23 |  await t.expect(elementExists).ok();
         24 |});
         25 |

         at <anonymous> (/Users/vanjagavric/Sites/portal-react/tools/e2e/fixtures/alerts.ts:20:6)
         at <anonymous> (/Users/vanjagavric/Sites/portal-react/tools/e2e/fixtures/alerts.ts:8:71)
         at __awaiter (/Users/vanjagavric/Sites/portal-react/tools/e2e/fixtures/alerts.ts:4:12)
         at test (/Users/vanjagavric/Sites/portal-react/tools/e2e/fixtures/alerts.ts:12:31)



 1/1 failed (14s)


Screenshots:


Steps to Reproduce:

  1. Go to my website ...
  2. Execute this command...
  3. See the error...

Your Environment details:

  • testcafe version: 1.9.3
  • node.js version: v10.17.0
  • command-line arguments: node tools/e2e/index.ts
  • browser name and version: Chrome 85.0.4183.102
  • platform and version: macOS 10.15.6
  • other:
level 2 Need research bug

Most helpful comment

@iamvanja

Hello,

v1.9.4 is available now at npm and Docker Hub.

All 4 comments

Hi @iamvanja

I checked the shared stack trace and found a problem with TestCafe.
We will try to find the cause of the issue and fix it as soon as possible.

Thanks so much!

@miherlosev Do you know when is expected release of 1.9.4?

@iamvanja

Hello,

v1.9.4 is available now at npm and Docker Hub.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

inikulin picture inikulin  Â·  3Comments

multivoltage picture multivoltage  Â·  3Comments

AndreyBelym picture AndreyBelym  Â·  3Comments

fnlctrl picture fnlctrl  Â·  3Comments

devmondo picture devmondo  Â·  3Comments