mucsi96 / nightwatch-cucumber

[DEPRECATED] Cucumber.js plugin for Nightwatch.js.
http://mucsi96.github.io/nightwatch-cucumber
MIT License
236 stars 72 forks source link

Programmatical API #121

Closed jeremyrajan closed 8 years ago

jeremyrajan commented 8 years ago

Hi,

Thank you for the great lib! If you could point me in the right direction, if there is a programmatical api for the same. I can use execSync but it seems like in most of the CI', it just hangs. I am using something like this:

const exec = require('sync-exec'); // using lib here because execSync was somtimes acting funny.
const res = exec(`${nwPath} -c ${nwConfig}`, { stdio: [0, 1, 2] });

      if (!res.stderr) {
        return res.status;
      }

      throw res.stderr;

Any ideas?

Thanks a lot :)

mucsi96 commented 8 years ago

I think I already provided a feedback on twitter.

jeremyrajan commented 8 years ago

Hey @mucsi96 thank you! :)

Yes, I did try to play around with it but not to avail. That was the part where i mentioned, I tried exporting the lib/runner. Because looking at it, it does include a lot inner functions inside the grunt task :).

How would you go about it?

Thank you :D

mucsi96 commented 8 years ago

I will check this out and create an example + documentation

jeremyrajan commented 8 years ago

That would great! Thank you :)

mucsi96 commented 8 years ago

Hi @jeremyrajan! I added documentation, test and example with programmatical API https://github.com/mucsi96/nightwatch-cucumber#programmatical-execution

jeremyrajan commented 8 years ago

Hi @mucsi96,

Thats awesome! Thanks a lot. I just tried it and it gives me the error (which I tried with /lib/runner earlier)

const nightwatch = require('nightwatch');
nightwatch.runner({
        config: path.join(__dirname, 'config', 'nightwatch.conf.js'),
        env: 'default',
        filter: '',
        tag: ''
      }, () => {
        console.log('done');
      });

image

Any idea?

jeremyrajan commented 8 years ago

Argh! It was my nvm acting up weird. I reinstalled and it worked like a charm. My goodness, wasted couple of days :(.

I have one problem, though if you could help me clear. Apparently, with a failing test it gets stuck, till timeout.

return new Promise((resolve, reject) => {
        nightwatch.runner({
          config: path.join(__dirname, 'config', 'nightwatch.conf.js'),
          env: 'default',
          filter: '',
          tag: ''
        }, (err, result) => {
          console.log(err);
          console.log(result);
          return resolve(0);
        });
      });

image

Any help will be highly appreciated and thanks again :).

mucsi96 commented 8 years ago

Hi @jeremyrajan!

Cool! I need the code to provide any help. The code block above looks ok :)

jeremyrajan commented 8 years ago

Hi @mucsi96,

Sorry for the delayed response :). Sure, my nightwatch config is

const seleniumServer = require('selenium-server');
const chromedriver = require('chromedriver');
const path = require('path');
const os = require('os');

const TMPDIR = os.tmpdir();
const DATADIR = path.join(TMPDIR, 'sc-chrome-tests');
const featureFiles = [process.env.FEATURE_FILES];
const stepDefinitions = [path.join(__dirname, '..', 'step-definitions')];
const customCommands = path.join(__dirname, '..', 'customCommands');
const hooks = path.join(__dirname, 'hooks.js');

require('nightwatch-cucumber')({
  featureFiles: featureFiles,
  stepDefinitions: stepDefinitions,
  stepTimeout: 30000,
  supportFiles: [hooks]
});

module.exports = {
  custom_commands_path: customCommands,
  disable_colors: false,
  live_output: false,
  output_folder: 'reports',
  page_objects_path: '',

  selenium: {
    host: '127.0.0.1',
    log_path: '',
    port: 4444,
    server_path: seleniumServer.path,
    start_process: true
  },

  test_settings: {
    default: {
      desiredCapabilities: {
        acceptSslCerts: true,
        browserName: 'chrome',
        chromeOptions: {
          args: [
            `--disable-web-security --allow-running-insecure-content --user-data-dir=${DATADIR} --clear-data-reduction-proxy-data-savings --homepage "about:blank"`
          ]
        },
        javascriptEnabled: true,
        proxy: {
          httpProxy: 'localhost:8081',
          proxyType: 'MANUAL',
          sslProxy: 'localhost:8081'
        }
      },
      launch_url: 'http://localhost',
      screenshots: {
        enabled: true,
        on_error: false,
        on_failure: true,
        path: 'screenshots/default'
      },
      selenium: {
        cli_args: {
          'webdriver.chrome.driver': chromedriver.path
        }
      },
      selenium_host: 'localhost',
      selenium_port: 4444,
      silent: true
    }
  }
};

And stepdefinitions file:

const expect = require('chai').expect;
module.exports = function () {
  // All Given methods
  this.Given(/^I open the url "([^"]*)"$/, function (url) {
    this
      .url(url)
      .waitForElementVisible('body', 5000);
  });

// title check
 this.Then(/^I expect the title to contain "([^"]*)"$/, function (checkTitle) {
    this
      .title(function (t) {
        expect(t.value).to.eql(checkTitle);
      });
  });
});

feature file

Feature: Cucumber Step definitions Check
  I should be able to check the various
  step definitions defined.

  Scenario: Basic site health check
    Given I open the url "http://1112.com/"
    Then I expect the title to contain "เดอะ พิซซ่า คอมปะนี 111" # failing test.

And this is what happens if there is a failing test.

image

Gets stuck :(. Not for all though. Only for this one I see it happening.

I have feeling its the hooks.

module.exports = function () {
  // if i use `this` with callback. this !== browser
  this.BeforeStep(function (step, callback) { // with or without callback
    // give this boy some time to load.
    this
      .waitForElementVisible('body', 3000)
      .injectScriptSc(BUNDLE_JS, 'text', () => {
      });
  });
});

Thank you! 
mucsi96 commented 8 years ago

Thank you! I will check it

jeremyrajan commented 8 years ago

@mucsi96 any luck :D ?

mucsi96 commented 8 years ago

I could not reproduce it. test-example.zip

jeremyrajan commented 8 years ago

Hi @mucsi96,

Thank you for looking into it :). Weird, it is happening once in a while in our tests on CircleCi and then it completely hangs. Have you tried it on any CI platforms? Because we are having a very hard timing figuring out oddly failing tests (which pass on our local) and when failed getting timed out.

Would you recommend anything, we can keep in mind because its frustrating sometimes :(.

Would you try through the pro-grammatical runner and see how it goes, please ?

Thanks a lot for your help again!

Cheers, Jeremy

mucsi96 commented 8 years ago

Hi Jeremy!

I think I found the problem. I could reproduce the issue with the following code:

Scenario: Basic site health check
    Given I open the url "https://www.1112.com/"
    Then I expect the title to contain "เดอะ พิซซ่า คอมปะนี 1111"
    Then I again expect the title to contain "เดอะ พิซซ่า คอมปะนี 1112"
this.Then(/^I expect the title to contain "([^"]*)"$/, function (checkTitle) {
    this
      .getTitle(function (t) {
        expect(t.value).to.eql(checkTitle);
      });
  });

  this.Then(/^I again expect the title to contain "([^"]*)"$/, function (checkTitle) {
    this
      .getTitle(function (t) {
        expect(t.value).to.eql(checkTitle);
      });
  });

The first title check step hangs. The problem is that you use chai. chai assertions are throwing errors if the assertion fails. If the chai assertion is in a callback nobody can catch it. This is the bad part of the callbacks. You are allowed only to use nightwatch assertions as they are not thowing errors but adding an extra step to the async task tree what nightwatch is building. So the fixed code look like this:

this.Then(/^I expect the title to contain "([^"]*)"$/, function (checkTitle) {
    this
      .getTitle(function (t) {
        this.assert.equal(t.value, checkTitle);
      });
  });

  this.Then(/^I again expect the title to contain "([^"]*)"$/, function (checkTitle) {
    this
      .getTitle(function (t) {
        this.assert.equal(t.value, checkTitle);
      });
  });
jeremyrajan commented 8 years ago

Hey @mucsi96 ,

Thanks a lot for the check! That does help :).

So, I cant use any other assertion libs and have to stick to https://nodejs.org/api/assert.html? I do have some custom checking and assertions which chai does well. It would great, if there was a workaround :).

Thanks again! Jeremy

mucsi96 commented 8 years ago

No problem. Try to ask on Nightwatch google group

mucsi96 commented 8 years ago

Also Nightwatch assertions != node.js assert I think

jeremyrajan commented 8 years ago

Hey @mucsi96,

Ahh oko! I did try with normal assert and seems to be getting stuck as well :(

And another thing i have noticed is that, the first feature always fails and others work fine. Which is weird :)

image

This is on CircleCi. And happens as before.

Any idea?

Thank you! Jeremy

mucsi96 commented 8 years ago

What do you mean under normal assert? The assert should not throw Error. That is the only requirement. You should use http://nightwatchjs.org/api#assertions

mucsi96 commented 8 years ago

You can also check this https://github.com/nightwatchjs/chai

jeremyrajan commented 8 years ago

I used this.assert. Because I have to evaluate values as well. For ex:

  this.Then(/^I expect basket subtotal to equal "([^"]*)"$/, function (subtotal) {
    const basket = global.impressions.basket;
    const subtotalImp = _.get(basket, 'costs.subtotal');
    this.assert.equal(subtotalImp, subtotal);
  });

I dont have to assert against the browser dom elements expect for hiding or showing them, which is working fine. Its just I have to assert against results. :)