2

The Problem

I am attempting to run a Cucumber test using a Karma test runner in my Npm project using the karma-cucumber-js adapter. However, when running my test, I find the following error in my console:

START:
PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR
  ReferenceError: Can't find variable: __adapter__
  at features/Test.steps.js:80

For more context, I am in the middle of a platform migration. We had a complex system in place previously that essentially used karma 1.7.x, cucumber 1.2.x, karma-cucumber-js 0.3.3, and Node 0.8.x. I am trying to set up a simple npm project with the same exact versions (except now I'm using Node 8.x as I am not allowed to use 0.8.x). We have a suite of thousands of old tests that we'd like to minimize modifications for, and it would be easiest to get the karma-cucumber-js plugin working due to how tightly coupled our test system is with both karma and cucumber.

Things I've Tried

I played around with the dependent karma-cucumber-js source code a bit by tweaking the code in my package's node_modules directory as an attempt to better understand the issue at hand. I was able to bypass the issue above by modifying these lines in adapter.js to globalize the adapter variable in the window as follows:

var __adapter__;
(function (win) {
    var adapter = new karma.CucumberAdapter(__karma__);
    __adapter__ = adapter;
    __karma__.start = adapter.getStart();
    win.__adapter__ = __adapter__;
})(window);

Which lead to the next error:

PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR
  ReferenceError: Can't find variable: Cucumber
  at node_modules/karma-cucumber-js/src/adapter.js:242

Which I worked around by adding the following line of code to the top of that very file after 'use strict':

var Cucumber = require('../../cucumber/release/cucumber.js');

Which lead to this issue:

PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR
  ReferenceError: Can't find variable: CucumberHTML
  at node_modules/karma-cucumber-js/src/adapter.js:177

And the workaround was to manually require that file adapter.js as well:

var CucumberHTML = require('../../cucumber-html/src/main/resources/cucumber/formatter/formatter.js');

With this "hack" in place, the cucumber tests are now able to run successfully:

START:
PhantomJS 2.1.1 (Mac OS X 0.0.0) LOG: 'Found features: /base/features/Test.feature'
PhantomJS 2.1.1 (Mac OS X 0.0.0) LOG: 'Tags: '
  Is it Friday yet?
    Friday is Friday
      ✔ Given today is Friday
      ✔ When I ask whether it's Friday yet
      ✔ Then I should be told "TGIF"

Finished in 0.002 secs / 0.002 secs @ 19:36:12 GMT-0700 (PDT)

SUMMARY:
✔ 3 tests completed

The underlying issue seems to be that [these Typescript variables][4] declared at the end of the karma-cucumber-js packages are, for some reason, not available to use. Which I believe is due to a webpack wiring issue.

Some other things I've tried:

  • Using other karma-cucumber adapters (there are 2 others), no luck.
  • Playing around with karma/phantomjs/cucumber version combinations
  • Using Firefox and Chrome in replacement of PhantomJS

My questions

  1. I need help understanding why this webpack setup is not working. How can I fix this?
  2. Are there any steps I'm missing or alternative approaches I should be taking to debug and resolve the issue at hand?

I've included some of the project code below, thank you for your time!

Project Code

package.json:

{
  "name": "npm-pretty-much-local-example",
  "version": "1.0.0",
  "scripts": {
    "wp": "webpack",
    "wpd": "webpack --debug",
    "test": "./node_modules/karma/bin/karma start"
  },
  "devDependencies": {
    "@babel/core": "^7.7.2",
    "@babel/preset-env": "^7.7.1",
    "@babel/preset-react": "^7.7.0",
    "babel-loader": "^8.0.0",
    "@babel/preset-typescript": "^7.7.x",
    "babel-generator": "^6.26.1",
    "babel-core": "^6.26.3",
    "cucumber": "^1.2.x",
    "jquery": "^3.4.1",
    "karma": "^1.7.x",
    "karma-cucumber-js": "^0.3.3",
    "karma-mocha-reporter": "^2.0.5",
    "karma-phantomjs-launcher": "^1.0.x",
    "karma-webpack": "^1.7.x",
    "socket.io": "^1.4.x",
    "webpack": "^3.7.1",
    "setimmediate": "^1.0.5",
    "karma-typescript-preprocessor": "^0.4.0"
  },
  "dependencies": {}
}

webpack.config.js:

const path = require('path');

module.exports = {
  context: path.resolve('.'),
  entry: './src/index.js',
  output: {
    filename: "./dist/output.js"
  },
  resolve: {
    extensions: ['.js'],
    modules: [
      path.resolve('./src'),
      path.resolve('./node_modules')
    ]
  }
};

Test.feature:

@Test
Feature: Is it Friday yet?
  Everybody wants to know when it's Friday

  Scenario: Friday is Friday
    Given today is Friday
    When I ask whether it's Friday yet
    Then I should be told "TGIF"

Test.steps.js:

function isItFriday(today) {
    if (today === "Friday") {
        return "TGIF";
    } else {
        return "Nope";
    }
}
 
// TODO: why is this not defined, and how was __adapter__ defined in the first place?
__adapter__.addStepDefinitions(function (scenario) {
    scenario.Given('today is {string}', function (givenDay) {
        this.today = givenDay;
    });
 
    scenario.When('I ask whether it\'s Friday yet', function () {
        this.actualAnswer = isItFriday(this.today);
    });
 
    scenario.Then('I should be told {string}', function (expectedAnswer) {
        return this.actualAnswer === expectedAnswer;
    });
});

src/index.js

var dummyVar = "";
Community
  • 1
  • 1
AV2KL
  • 21
  • 3

0 Answers0