nightwatch icon indicating copy to clipboard operation
nightwatch copied to clipboard

While executing custom command program exits after first assert in Promise.

Open efosoner opened this issue 2 years ago • 4 comments

Describe the bug

While executing custom command (listed below) program exits after first assert in Promise. When assert.elementPresent() changed to waitForElementPresent() and assert.visible() changed to waitForElementVisible() it executes as expected.

Sample test

customClickTest.ts

// Sample test

import {NightwatchBrowser} from 'nightwatch';

module.exports = {
    "Browser Context": async function (browser: NightwatchBrowser) {
        const selectorObject = {
            selector: '//*[@data-test-id="search-form-submit"]',
            locateStrategy: 'xpath'
        };
        const selector = '[data-test-id="search-form-submit"]';
        const nonExistingSelector = '.NoneExisting';
        const pageObject = browser.page.ecosiaPage();

        await browser.url('https://www.ecosia.org/')
        await browser.waitForElementVisible('body')
        await browser.verify.titleContains('Ecosia')
        await browser.assert.elementPresent(selectorObject);
        await browser.assert.visible(selectorObject);
        await browser.click(selectorObject);
        await browser.customClick(selectorObject);
        await browser.customClick(selector);
        await browser.customClick(nonExistingSelector);
    }
};

Sample command

customClick.js

// Sample test

module.exports = class customClick {
  async command(elementSelector) {
    return new Promise(async (resolve) => {
      await this.api.assert.elementPresent(elementSelector);
      await this.api.assert.visible(elementSelector);
      await this.api.click(elementSelector);
      resolve(this.api);
    });
  }
};

Run with command

node ./runner.js ./tests/customClickTest.ts

Verbose output

debug.log

[Custom Click Test] Test Suite
────────────────────────────────────────────────────────────
⠧ Starting ChromeDriver on port 9515...

ℹ Connected to ChromeDriver on port 9515 (1586ms).
  Using: chrome (103.0.5060.114) on WINDOWS.


  Running Browser Context:
───────────────────────────────────────────────────────────────────────────────────────────────────
  ℹ Loaded url https://www.ecosia.org/ in 1429ms
  √ Element <body> was visible after 60 milliseconds.
  √ Testing if the page title contains 'Ecosia' (32ms)
  √ Testing if element <//*[@data-test-id="search-form-submit"]> is present (36ms)
  √ Testing if element <//*[@data-test-id="search-form-submit"]> is visible (65ms)
        ...[DEBUG]: [2022-07-11T12:30:16.350Z] Classic click
  √ Testing if element <//*[@data-test-id="search-form-submit"]> is present (31ms)
Waiting for the debugger to disconnect...

Configuration

nightwatch.json

{
  Default config with specified custom_commands_path
}

Your Environment

Executable Version
nightwatch --version 2.2.2
npm --version 6.14.17
node --version 14.19.3
Browser driver Version
NAME VERSION
chromedriver 103
OS Version
NAME VERSION
Windows 10 19044

efosoner avatar Jul 12 '22 08:07 efosoner

I am able to reproduce this issue. The cause of this issue seems to be something happening in the Nightwatch queue due to the mixing of command and assertions (putting assertions inside a command).

garg3133 avatar Jul 17 '22 16:07 garg3133

@efosoner Can you please confirm that the following is working for you?

module.exports = class customClick {
  async command(elementSelector) {
    return new Promise(async (resolve) => {
      await this.api.waitForElementPresent(elementSelector);
      await this.api.assert.visible(elementSelector);
      await this.api.click(elementSelector);
      resolve(this.api);
    });
  }
};

The above is not working for me but said in the issue description that it is working for you.

When assert.elementPresent() changed to waitForElementPresent() it executes as expected

garg3133 avatar Jul 22 '22 12:07 garg3133

I checked it and I’ve made a mistake. assert.visible should also be changed to waitForElementVisible and only then command starts working as expected. Sorry for misleading description

efosoner avatar Jul 22 '22 22:07 efosoner

Hey @efosoner 👋🏻 , Thanks for raising this issue. We can simplify (omit use of async/await) the test a bit like this:

//test.js

  it('sample custom click',  function(browser) {
    const selectorObject = {
      selector: '//*[@data-test-id="search-form-submit"]',
      locateStrategy: 'xpath'
    };
    const selector = '[data-test-id="search-form-submit"]';
    const nonExistingSelector = '.NoneExisting';

    browser.url('https://www.ecosia.org/');
    browser.waitForElementVisible('body');
    browser.verify.titleContains('Ecosia');
    browser.assert.elementPresent(selectorObject);
    browser.waitForElementVisible(selectorObject);
    browser.click(selectorObject);
    browser.customClick(selectorObject);
    browser.customClick(selector);
    browser.customClick(nonExistingSelector);  
  });

//customClick.js
module.exports = class customClick {
  command(elementSelector) {
    this.api.assert.elementPresent(elementSelector);
    this.api.assert.visible(elementSelector);

    return this.api.click(elementSelector);
  }
};

We use async/await in nightwatch when we want to retrieve values from Nightwatch command for example:

const result = await brower.getCookies()

I've tried this code and it works for me. Hopefully it would work for you as well 🙂

gravityvi avatar Jul 25 '22 12:07 gravityvi

Possibly fixed by #3266 ? @swrdfish can you check if your PR fixes this?

AutomatedTester avatar Nov 08 '22 11:11 AutomatedTester