Testcafe-hammerhead: TypeError: Cannot read property 'className' of undefined

Created on 24 Jul 2019  ·  19Comments  ·  Source: DevExpress/testcafe-hammerhead

What is your Test Scenario?

Hello!

I'm having a hard time to click on some old Angular JS components (buttons) when using most recent versions of TestCafe. Here is an example of a button that TestCafe cannot click:

<button class="uiid-onboard-employee-button btn btn-primary mg_r20 wd_160" promise-button="vm.saveAddEmployee()" > {{vm.saveButtonText}} </button>

I can only click on the button above when using TestCafe version 1.1.0, I've tried several versions after this (including latest 1.3.3) but when TestCafe clicks on the button, nothing happens and the following error is thrown in my Chrome Console:

error-when-dealing-with-promise-button - Copy

I noticed that all buttons that I have issues have this promise-button attribute.

What is the Current behavior?

Only TestCafe 1.1.0 can click on the buttons above.

What is the Expected behavior?

I'd expect latest versions of TestCafe to be able to click successfully.

What is your web application and your TestCafe test code?

Your website URL (or attach your complete example):


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



Your complete configuration file (if any):



Your complete test report:



Screenshots:


Steps to Reproduce:

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

Your Environment details:

  • testcafe version:
  • node.js version:
  • command-line arguments:
  • browser name and version:
  • platform and version:
  • other:
Auto-locked shadow UI bug

All 19 comments

Hi @rodrigotolledo

This behavior looks like regression. To find the cause of the problem, we need to have a website on which we can reproduce this behavior. Also, we need test code that leads to errors in the browser console.
Could you please provide such test code and the website (a simplified example or public link)?

Hi @miherlosev

Thanks for your quick reply.

Unfortunately, we couldn't easily create an example to mimic the problem. So I caught up with one of our Developers which helped me to debug the issue a bit more and here are some additional information:

Looks like the problem is somewhere around Kendo UI Validator and hammerhead (apparently nothing to do with the _promise-button_ as we initially thought).

We're using _Kendo UI v2015.2.727_ (http://www.telerik.com/kendo-ui) to validate the input fields in the forms. Kendo validator is going through elements in the page and checking the _className_ which throws the following Console Error (right after TestCafe clicks on the button):

hammerhead.js:6 TypeError: Cannot read property 'className' of undefined
    at o (http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/Scripts/kendo.all.min.js:19:460)
    at init._findMessageContainer (http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/Scripts/kendo.all.min.js:19:7474)
    at init.validateInput (http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/Scripts/kendo.all.min.js:19:6778)
    at init.validate (http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/Scripts/kendo.all.min.js:19:6496)
    at http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/dist/app.js?a997b52e19ed46b80926:2:4592555
    at k.$scope.saveRequest (http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/dist/app.js?a997b52e19ed46b80926:2:4592801)
    at http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/Scripts/angular.min.js:192:533
    at k.promiseButton (http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/Scripts/angular.min.js:55:624)
    at k.scope.start (http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/Scripts/promise_button.js:88:31)
    at intervalTick (http://10.0.75.1:58041/VxuHpIbzU!s!utf-8/https://abc.com/Scripts/promise_button.js:60:19) exception

By putting a debugger, we managed to pinpoint that the failure is happening on the following line of kendo.all.min.js (because _i_ is undefined when accessing _className_):

        function o(t, n) {
            var i, r, o, a, l = e();
            for (o = 0,
            a = t.length; a > o; o++)
                i = __get$(t, o),
                u.test(i.className) && (r = i.getAttribute(s.attr("for")),
                r === n && (l = l.add(i)));
            return l
        }

The component button on our page looks like this:

<button class="uiid-onboard-employee-button btn btn-primary mg_r20 wd_160" promise-button="vm.saveAddEmployee()" > {{vm.saveButtonText}} </button>

The TestCafe code that interacts with the button above does only a simple click (nothing else). Here is the exact code we're using:

public async submit() {
    await t.click(this.submitButton, { speed: this.slowSpeed });
}

Friendly reminder: all works fine with _TestCafe 1.1.0_. Issue occurs with all newest versions.

We'd highly appreciate your help on this as we'd like to use latest version of TestCafe.

Thank you!

@rodrigotolledo

Hello,

I found the "Validator / AngularJS" example, and I don't see any "'className' of undefined" errors under testcafe-hammerhead / [email protected] / Chrome 75 / Windows 10.
testcafe-hammerhead:
Capture
testcafe:
test.js

import { Selector } from 'testcafe';

fixture `Fixture`
    .page `https://demos.telerik.com/kendo-ui/validator/angular`;

test('Click submit button', async t => {
    await t.click(Selector('#fieldlist > li.confirm > button'), { speed: 0.2 });
});

Result

 √ Click submit button


 1 passed (13s)

Could you please provide us with steps to reproduce the issue on our side based on the "Validator / AngularJS" example (or on your own example)?

Hi @Farfurix,

I tried your example above and all works fine here for me on latest TestCafe too.

Unfortunately, I cannot give you access to our Test Environment (and we were not successful generating a code example)

But I'm more than happy to do a quick call/screen-share to walk you through the issue. Can I get a DevExpress email/contact so we can organise a quick screen share? //cc @miherlosev

We really want to get through this issue to be able to use latest TestCafe.

Appreciate your help.

Hi @rodrigotolledo ,

We don't provide such remote service at the moment. Please check if the problem is reproducible in one of the following testcafe versions:

  • v1.1.1-alpha.1;
  • v1.1.1-alpha.2;
  • v1.1.1-rc.1;
  • v1.1.1-rc.2;
  • v1.1.1-rc.3;
  • v1.1.1.

Could you please provide us with the earliest version in which you can reproduce the issue? This will help us localize the changes where the regression was made.

Hi @aleks-pro,

Good idea!

Here are the results of my tests:

  • v1.1.1-alpha.1; WORKS!
  • v1.1.1-alpha.2; WORKS!
  • v1.1.1-rc.1; WORKS!
  • v1.1.1-rc.2; BUG HAPPENS HERE!
  • v1.1.1-rc.3; BUG HAPPENS HERE!
  • v1.1.1; BUG HAPPENS HERE!

Let me know if you need any additional info.

Appreciate your help!

Cheers!

@rodrigotolledo

Thank you for your clarification. We have an assumption: the issue relates to the <input type="file"> form element. Could you please clarify if your validation form contains the <input type="file"> element? It may be some image/file upload area.

For team:
index.html:

<html>
<head></head>
<body>
<form kendo-validator="validator" ng-submit="validate($event)" class="ng-pristine ng-valid" data-role="validator" novalidate="novalidate" __bizdiag="1800080961" __biza="WJ__">
    <ul id="fieldlist">
        <li>
            <label for="fullname" class="required">Your Name</label>
            <input type="file" name="file" id="file">
            <input type="text" id="fullname" name="fullname" class="k-textbox sessioncamexclude" placeholder="Full name" required="" validationmessage="Enter {0}" style="width: 220px;">
        </li>
    </ul>
</form>
<script>
    function test() {
        var form = document.querySelector('form');

        console.log('form.getElementsByTagName(\'*\').length =', form.getElementsByTagName('*').length);
        console.log('form.getElementsByTagName(\'*\') =', form.getElementsByTagName('*'));


        console.log('last element =', form.getElementsByTagName('*')[form.getElementsByTagName('*').length - 1]);
    }

    setTimeout(test, 5000);

</script>
</body>
</html>

Steps to reproduce the undefined HTMLCollection element (get the last hidden input element):

  1. Open the above page in the hammerhead playground (commit: https://github.com/DevExpress/testcafe-hammerhead/commit/b8f786f515c87570b3022b6ee5c01900c845b05f or later)
  2. Set some file to the upload input (you have a 5-second timeout)
  3. See the DevTools console:
last element = undefined

Hi @Farfurix,

Thanks for looking into this issue.

I can confirm we're using <input type="file"> across different parts of our App, including in the pages where we're having issues to click on a button.

Let me know if you need any additional information.

Thanks!

@rodrigotolledo

After we fix the issue, you will be able to pass your test case with an updated testcafe version. Please stay tuned for updates in this thread.

Awesome, @Farfurix!

I'll wait for the fix.

Thank you!

@rodrigotolledo

You are welcome.

Input type="file" broke the automated testing with latest version of the testcafe

Input type="file" broke the automated testing with latest version of the testcafe
 

The problem occurs if there is a form with <input type=file> and the script calls the `form.getElementsByTagName('*') and iterates over the resulting collection.

I can quite easily reproduce.
I have seen the issue in multiple places where using input="file" and using it inside a form.
Eg this fails(no matter the value of ng-if):

<form ng-if="false">
     <input type="file" />
</form>

If I remove the ng-if, it works. But it does not work if I put the ng-if outside in a div.
In another spot I had to remove the form before I could make it work.

Hi all,

Just wondering if we have any idea when this issue will be addressed?

Once this issue is fixed, we will finally be able to upgrade to latest TestCafe. Still stuck with version 1.1.0.

Feel free to hit me up if you need any additional details.

Cheers!

Hi @rodrigotolledo

I cannot provide you with a precise time frame. The current development sprint is already planned. We will consider this issue during planning the next development sprint.

Appreciate your help and effort on fixing this issue @LavrovArtem and @miherlosev!

I can see this change is part of testcafe-hammerhead 14.9.2 release. But testcafe is still pointing to 14.9.1 as per here: https://github.com/DevExpress/testcafe/blob/master/package.json#L117

Just wondering how often you bump up the versions? (so testcafe will use latest hammerhead)

Thanks again!

@rodrigotolledo,
We do not have a precise release schedule for TestCafe. Usually, we release new versions two or three times a month. We are planning to release a new version this week. However, this date can be moved if we find some issues.

This thread has been automatically locked since it is closed and there has not been any recent activity. Please open a new issue for related bugs or feature requests. We recommend you ask TestCafe API, usage and configuration inquiries on StackOverflow.

Was this page helpful?
0 / 5 - 0 ratings