Testcafe: Race condition for immediately submitted forms leads to : Cannot read property 'getItem' of null

Created on 8 Oct 2019  路  6Comments  路  Source: DevExpress/testcafe

What is your Test Scenario?

Load of an IFrame that has an immediately submitted form.

What is the Current behavior?

The submitted form invokes the TestCafe driver _onFormSubmit() which gets an error
Cannot read property 'getItem' of null which in turn causes the submit to fail.

What is the Expected behavior?

The submitted form completes successfully

What is聽your web application and聽your TestCafe聽test code?

As there isn't a ready set of code that can be extracted, I debugged TestCafe to find out where the issue is and it appears a simple enough race condition.

driver.js sets up the _onFormSubmit handler synchronously in the constructor

        hammerhead.on(hammerhead.EVENTS.uncaughtJsError, err => this._onJsError(err));
        hammerhead.on(hammerhead.EVENTS.unhandledRejection, err => this._onJsError(err));
        hammerhead.on(hammerhead.EVENTS.consoleMethCalled, e => this._onConsoleMessage(e));
        hammerhead.on(hammerhead.EVENTS.beforeFormSubmit, e => this._onFormSubmit(e));

but although iframe.driver.mustache calls the driver.start() synchronously

    var IframeDriver = window['%testCafeIframeDriver%'];
    var driver       = new IframeDriver({{{testRunId}}}, {
        selectorTimeout:     {{{selectorTimeout}}},
        pageLoadTimeout:     {{{pageLoadTimeout}}},
        dialogHandler:       {{{dialogHandler}}},
        unstableNetworkMode: {{{retryTestPages}}},
        speed:               {{{speed}}}
    });

    driver.start();

the iframe-driver.js implementation loads the contextStorage on a promise

    start () {
        this.nativeDialogsTracker = new IframeNativeDialogTracker(this.dialogHandler);
        this.statusBar            = new IframeStatusBar();

        const initializePromise = this.parentDriverLink
            .establishConnection()
            .then(id => {
                this.contextStorage = new ContextStorage(window, id);

                if (this._failIfClientCodeExecutionIsInterrupted())
                    return;

                const inCommandExecution = this.contextStorage.getItem(this.COMMAND_EXECUTING_FLAG) ||
                                         this.contextStorage.getItem(this.EXECUTING_IN_IFRAME_FLAG);

                if (inCommandExecution) {
                    this.contextStorage.setItem(this.COMMAND_EXECUTING_FLAG, false);
                    this.contextStorage.setItem(this.EXECUTING_IN_IFRAME_FLAG, false);
                    this._onReady(new DriverStatus({ isCommandResult: true }));
                }
            });

        this.readyPromise = Promise.all([this.readyPromise, initializePromise]);
}

meanwhile any event that is triggered before the above promise will have a null contextStorage, and this indeed happens when the _onFormSubmit() is called as it assumes the presence of contextStorage. As you can see, this code is actually only present as a result of Issue #3560

    // HACK: For https://github.com/DevExpress/testcafe/issues/3560
    // We have to cancel every form submit after a test is done
    // to prevent requests to a closed session
    _onFormSubmit (e) {
        if (this.contextStorage.getItem(TEST_DONE_SENT_FLAG))
            e.preventSubmit = true;
   }

To resolve

As the Iframe driver needs the id so can't easily be synchronous, then the _onFormSubmit() (and similar) need a chick that contextStorage isn't null.

Steps to Reproduce:

  1. Create a Web Pge that has an IFRAME
  2. The target of that IFRAME should have a FORM that is submitted immediately
  3. View the console log and see the error produced

Your Environment details:

  • testcafe version: 1.5.0
  • node.js version: v12.3.1
  • command-line arguments: testcafe chrome test.js
  • browser name and version: chrome
  • platform and version: macOS
  • other:
Auto-locked bug

Most helpful comment

@bennymeade
Hi, we will accept that PR after the 1.6.1. version is released

All 6 comments

Fix has been included in this pull request -> https://github.com/DevExpress/testcafe/pull/4364

Thank you for your detailed research. My colleagues will also check your PR as soon as possible.

Hi guys, do you have an ETA on the PR related to this issue making it into a release version?

@bennymeade
Hi, we will accept that PR after the 1.6.1. version is released

Closed by #4364.

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

Related issues

fnlctrl picture fnlctrl  路  3Comments

hinok picture hinok  路  3Comments

inikulin picture inikulin  路  3Comments

devmondo picture devmondo  路  3Comments

madroneropaulo picture madroneropaulo  路  3Comments