nightwatchjs / nightwatch

Integrated end-to-end testing framework written in Node.js and using W3C Webdriver API. Developed at @browserstack
https://nightwatchjs.org
MIT License
11.83k stars 1.32k forks source link

TypeError: callback.call is not a function when using clearValue() in a login test #1927

Closed mmandic1503 closed 5 years ago

mmandic1503 commented 5 years ago

After I've update to latest v1.0.12, my login tests are starting to fail with this error

An error occurred while running .clearValue() command on <input[ng-model="password"]>: TypeError: callback.call is not a function
      at /home/marko/NCT/node_modules/nightwatch/lib/api/protocol.js:71:39
      at process._tickCallback (internal/process/next_tick.js:68:7)
       at process._tickCallback (internal/process/next_tick.js:68:7)
       at process._tickCallback (internal/process/next_tick.js:68:7)`

I'm using forEach() to loop through json file with credentials. Looks like this:

var loginData = require('../testData/devLoginData.json');
loginWithData() {
            var credential = loginData.credentials;

            credential.forEach((loginData) => {
                var credentialUser = loginData.username;
                var credentialPass = loginData.password;
                var form = this.elements.loginForm.selector;
                var submit = this.elements.submitBnt.selector;
                var errorOk = this.elements.errorOkBtn.selector;
                var user = this.elements.usernameField.selector;
                var pass = this.elements.passwordField.selector;
                var errorModal = this.elements.errorModal.selector;

                this.api
                    .waitForElementVisible(form, 3000)
                    .setValue(user, credentialUser)
                    .setValue(pass, credentialPass)
                    .click(submit)
                    .pause(700)
                    .elements('css selector', errorModal, res => {
                        var error = res.value.length;
                        console.log("Error massage " + error);

                        if (error > 0) {
                            this
                                .waitForElementVisible(errorModal, 3000)
                                .click(errorOk)
                                .clearValue(user)
                                .clearValue(pass)
                        }
                    })
            })
        }
    }]

This is working perfectly on a nightwatch v1.0.11.

My working environment is Linux Ubuntu 18.04.1 LTS 64-bit. My nightwatch config file:

const seleniumServer = require("selenium-server");
const chromedriver = require("chromedriver");
const PKG = require("./package.json"); // so we can get the version of the project
const SCREENSHOT_PATH = "./reports/screenshots/" + PKG.version + "/";

const config = { // we use a nightwatch.conf.js file so we can include comments and helper functions
    "src_folders": [
        "tests/dev" 
    ],
    "output_folder": "./reports", // location where Nightwatch stores test results
    "custom_commands_path": "./customCommands",
    "custom_assertions_path": "./customAssertion",
    "page_objects_path": "./pageObjects",
    "globals_path": "",
    "selenium": {
        "start_process": true,
        "server_path": seleniumServer.path,
        "log_path": "",
        "host": "127.0.0.1",
        "port": 4444,
        "cli_args": {
            "webdriver.chrome.driver": chromedriver.path
        }
    },
    "test_workers": {
        "enabled": false, // enable/disable test workers for the purpos of performing tests in parallel 
        "workers": "auto"
    },
    "test_settings": {
        "default": {
        "launch_url": "http://localhost", 
        "selenium_port": 80,
        "selenium_host": "127.0.0.1",
        "silent": true,
        "screenshots": {
            "enabled": true, // save screenshots taken here
            "path": SCREENSHOT_PATH
        }
    },
    "local": {
        "launch_url": "http://localhost",
        "selenium_port": 4444,
        "selenium_host": "127.0.0.1",
        "silent": true,
        "screenshots": {
          "enabled": true, // save screenshots taken here
          "path": SCREENSHOT_PATH
        }, // this allows us to control the
        "globals": {
          "waitForConditionTimeout": 15000 // on localhost sometimes internet is slow so wait...
        }
      }

}
}
module.exports = config;
beatfactor commented 5 years ago

I'm afraid I can't easily reproduce your issue. Can you post a basic sample test which I could run and which will reproduce the bug? How is loginWithData used?

mmandic1503 commented 5 years ago

Thanks for fast feedback. loginWithData() is custom method I made inside page object, and I'm using it for testing logging in with invalid/valid credentials. I'm calling it in login test like this:

var url = require('../../testData/urls.json')

module.exports = {
    '1 Navigate to login page and perform negative and positive login paths': function (browser) {
        var loginPage = browser.page.loginPage();

        browser
            .windowMaximize()
            .url(url.urlDev)
            .pause(500)
        loginPage.loginWithData()
    }
}

Problem is that it doesn't clear fields properly before it goes to the next credential in array. I'm currently using nightwatch v1.0.11, so I don't have problem with this. But, updating to latest version brakes everything.

gregoryduckworth commented 5 years ago

I get a similar issue when using click() inside a custom function in the page object.

An error occurred while running .click() command on <#setFigOverrideCookie>: TypeError: callback.call is not a function

This is using the latest 1.0.12 version of Nightwatch.

beatfactor commented 5 years ago

@mmandic1503 could you please post also a verbose log of the test run containing the TypeError in 1.0.12?

beatfactor commented 5 years ago

Attaching logs. Hope it helps.

Please add the logs inline in the message, thanks.

mmandic1503 commented 5 years ago

Sorry. Here you go.

24 verbose exit [ 5, true ]
beatfactor commented 5 years ago

Sorry. Here you go.

These are npm logs, not very helpful. Please run the test with:

./node_modules/.bin/nightwatch --env local tests/dev/login.js --verbose
beatfactor commented 5 years ago

Thanks for your patience and help. :)

No problem, yes this is ok, thank you.

beatfactor commented 5 years ago

@mmandic1503 I'm afraid I still cannot reproduce the bug. But you can install v1.0.13 and you should get a better error message. If you do, please post the results here.

cc @gregoryduckworth

beatfactor commented 5 years ago

@mmandic1503 Better make that v1.0.14

mmandic1503 commented 5 years ago

Nightwatch updated to v1.0.14. Here are new logs:

 Starting Selenium Server on port 4444...
 Selenium Server up and running on port 4444 with pid: 8594 (782ms).

[Login] Test Suite
==================
 → Running command: click ('button[type="submit"]')
   Request POST  /wd/hub/session/97a6134404224a65a6f40f245299196d/element
   { using: 'css selector', value: 'button[type="submit"]' }
 → Completed command setValue ('input[ng-model="password"]', 'Password123') (74ms)
   Response 200 POST /wd/hub/session/97a6134404224a65a6f40f245299196d/element (10ms)
   { sessionId: '97a6134404224a65a6f40f245299196d',
     status: 0,
     value: { ELEMENT: '0.2139283641899461-4' } }
   Request POST  /wd/hub/session/97a6134404224a65a6f40f245299196d/element/0.2139283641899461-4/click

   Response 200 POST /wd/hub/session/97a6134404224a65a6f40f245299196d/element/0.2139283641899461-4/click (34ms)
   { sessionId: '97a6134404224a65a6f40f245299196d',
     status: 13,
     value:
      { message:
         'unknown error: Element <button type="submit" class="btn btn-primary ng-binding" ng-disabled="frm.$invalid || disableLoginBtn">...</button> is not clickable at point (959, 365). Other element would receive the click: <div class="sa-icon sa-error animateErrorIcon" style="display: block;">...</div>',
        error:
         [ '  (Session info: chrome=70.0.3538.77)',
           '  (Driver info: chromedriver=2.43.600233 (523efee95e3d68b8719b3a1c83051aa63aa6b10d),platform=Linux 4.15.0-39-generic x86_64)' ] } }
 Error while running .clickElement() protocol action: unknown error: Element <button type="submit" class="btn btn-primary ng-binding" ng-disabled="frm.$invalid || disableLoginBtn">...</button> is not clickable at point (959, 365). Other element would receive the click: <div class="sa-icon sa-error animateErrorIcon" style="display: block;">...</div>

   An error occurred while running .click() command on <button[type="submit"]>: unknown error: Element <button type="submit" class="btn btn-primary ng-binding" ng-disabled="frm.$invalid || disableLoginBtn">...</button> is not clickable at point (959, 365). Other element would receive the click: <div class="sa-icon sa-error animateErrorIcon" style="display: block;">...</div>
       at process._tickCallback (internal/process/next_tick.js:68:7)

 → Running command: pause (700)
 → Completed command click ('button[type="submit"]') (45ms)

 → Running command: elements ('css selector', 'div[class*="showSweetAlert"]', [Function])
   Request POST  /wd/hub/session/97a6134404224a65a6f40f245299196d/elements
   { using: 'css selector', value: 'div[class*="showSweetAlert"]' }
 → Completed command pause (700) (701ms)
   Response 200 POST /wd/hub/session/97a6134404224a65a6f40f245299196d/elements (34ms)
   { sessionId: '97a6134404224a65a6f40f245299196d',
     status: 0,
     value: [ { ELEMENT: '0.2139283641899461-5' } ] }
Error massage 1
 → Completed command elements ('css selector', 'div[class*="showSweetAlert"]', [Function]) (35ms)
   Cannot read property 'then' of undefined
       at new Promise (<anonymous>)
       at process._tickCallback (internal/process/next_tick.js:68:7)
 → Running [afterEach]:
 → Completed [afterEach].

FAILED: 3 errors and  5 passed (5.702s)
   Cannot read property 'then' of undefined
       at new Promise (<anonymous>)
       at process._tickCallback (internal/process/next_tick.js:68:7)
 → Running [after]:
 → Completed [after].

 → Running command: end ([Function])

 → Running command: session ('delete', [Function])
   Request DELETE  /wd/hub/session/97a6134404224a65a6f40f245299196d
   Response 200 DELETE /wd/hub/session/97a6134404224a65a6f40f245299196d (56ms)
   { sessionId: '97a6134404224a65a6f40f245299196d',
     status: 0,
     value: null }
 → Completed command end ([Function]) (62ms)
 → Completed command session ('delete', [Function]) (60ms)
_________________________________________________

TEST FAILURE: 3 errors during execution 0 assertions failed, 5 passed. 7.627s

 ✖ login
 – 1 Navigate to login page and perform negative and positive login paths (5.702s)

  An error occurred while running .click() command on <button[type="submit"]>: unknown error: Element <button type="submit" class="btn btn-primary ng-binding" ng-disabled="frm.$invalid || disableLoginBtn">...</button> is not clickable at point (959, 365). Other element would receive the click: <div class="sa-icon sa-error animateErrorIcon" style="display: block;">...</div>
       at process._tickCallback (internal/process/next_tick.js:68:7)

  An error occurred while running .click() command on <button[type="submit"]>: unknown error: Element <button type="submit" class="btn btn-primary ng-binding" ng-disabled="frm.$invalid || disableLoginBtn">...</button> is not clickable at point (959, 365). Other element would receive the click: <div class="sa-icon sa-error animateErrorIcon" style="display: block;">...</div>
       at process._tickCallback (internal/process/next_tick.js:68:7)

  Cannot read property 'then' of undefined
       at new Promise (<anonymous>)
       at process._tickCallback (internal/process/next_tick.js:68:7)

Hope this one have more info.

Cheers

beatfactor commented 5 years ago

@mmandic1503 could you please retry with v1.0.15? thanks.

mmandic1503 commented 5 years ago

@beatfactor Working on v1.0.15! Thank you.