theintern / intern

A next-generation code testing stack for JavaScript.
https://theintern.io/
Other
4.36k stars 310 forks source link

Using Cucumber.js with Intern #81

Closed winko closed 4 years ago

winko commented 11 years ago

Hi! Is it possible to use Cucumber.js ( https://github.com/cucumber/cucumber-js ) together with intern? I would like to write my functional tests as features in pure Gherkin Syntax. What I have to do if I want to use Cucumber.js? Regards!

csnover commented 11 years ago

Is this an enhancement request, or are you asking for support? If you are asking for support, please read information on getting support. If this is an enhancement request I will schedule it into the milestone schedule.

csnover commented 11 years ago

I’m treating this as an enhancement request. We’ll add a Cucumber interface for 1.4.

diegopamio commented 10 years ago

It looks like it wasn't included in 1.4, am I right?

jason0x43 commented 10 years ago

You are correct. It's been pushed back a couple of releases.

deonjo commented 10 years ago

This would be incredibly helpful and a well used feature if implemented.

jason0x43 commented 10 years ago

I added basic support for Cucumber in the cucumber branch. I created an intern-cucumber-example test project if anyone wants to try it out.

deonjo commented 10 years ago

Hi jason0x43, how do I run the inter-cucumber-example tests? I tried running both: intern-runner config=tests/intern intern-client config=tests/intern

and came across the error: Error: Failed to load module intern/lib/interfaces/cucumber from /Users/bwang/.virtualenvs/env/lib/node_modules/intern/lib/interfaces/cucumber.js (parent: intern/lib/interfaces/cucumber!16!*) at /Users/bwang/.virtualenvs/env/lib/node_modules/intern/node_modules/dojo/dojo.js:757:12 at fs.js:207:20 at Object.oncomplete (fs.js:107:15)

jason0x43 commented 10 years ago

You should be able to clone that project, run npm install, then run ./node_modules/.bin/intern-client config=tests/intern (intern-runner also works).

jason0x43 commented 10 years ago

You need to be using the intern dependency specified in the project's package.json, which is what you get when you run npm install. A global install of intern won't work (unless you've globally installed the cucumber branch).

deonjo commented 10 years ago

Hi Jason, The code that you wrote as an example is really good. Pretty thorough. I just had a couple of comments and notes:

  1. (just a friendly watch out) I think, you included your sauce lab key in the example. you might want to regenerate it
  2. Was trying to run the example functional tests. They all seem to halt on "Then". I would comment out the "Then" and the tests would run, but when I put them back in they would halt. The test would not terminate.
  3. A question about the architecture. How would I go about implementing a global steps/functional file that several feature files would inherit steps from?
jason0x43 commented 10 years ago
  1. The sauce key in Intern's .travis.yml (if that's the one you mean) file is there intentionally.
  2. My bad -- I hadn't pushed my latest update to the cucumber branch, and it was missing a function.
  3. I added an example of how support code can be shared between test modules to the example repo.
jason0x43 commented 10 years ago

Oh, you mean that sauce key. (I was looking in the wrong repo.) Thanks for the heads up.

wmayervfc commented 8 years ago

This feature is something my team is very interested in using. Is this still in planning for development?

zmorris commented 7 years ago

It seems that jason0x43 got very close to making this work, but unfortunately I can't get https://github.com/jason0x43/intern-cucumber-example to work now. Are there plans to integrate this into intern? It seems like the new BDD aspect of intern should know how to handle running the feature files, or else it's only BDD-style but doesn't have the benefit of separating user stories and steps. If someone has an example of using cucumber-js as a plugin, that could help too, thanx!

dylans commented 7 years ago

@zmorris it's on the roadmap for Intern 4. In the interim, https://github.com/theintern/intern/issues/650 has a good solution for use with Intern 3.x, though it basically calls out to Cucumber rather than supporting gherkin syntax within Intern.

zmorris commented 7 years ago

Thanks for your quick reply. I tried using https://github.com/jason0x43/intern-cucumber-example with a package.json of:

{
    "name": "intern-cucumber-example",
    "dependencies": {
        "intern": "git://github.com/rhpijnacker/intern.git#3d73693feec63d012b5e76e3a28d8e413a103f40",
        "dojo": "~1.9.0"
    }
}

which loads the last commit on https://github.com/theintern/intern/pull/650 PR. Changing loader to loadOptions in tests/intern.js to avoid the deprecation warning, I'm able to call:

yarn
node_modules/.bin/intern-client config=tests/intern

But I get no output. I've tried typing gibberish into the test files and it throws an error, so I think it is able to find the intern object 'intern!cucumber!tests/features/fib' for exercising the feature files, but it just doesn't do anything.

I was hoping I might be able to feel my way through getting it working, but without an example, I can't really get anywhere. Does someone happen to have a features/steps example I can try? Thanx!

UPDATE: I managed to get something working, I evidently just had to ask the universe:

Copy:

node_modules/intern/tests/unit/lib/interfaces/cucumber.js

to:

tests/cucumber.js

And change the top lines from '../../../..', to 'intern', except for main which is inferred:

define([
    'intern!object',
    'intern/chai!assert',
    'intern!cucumber',
    'intern',
    'intern/lib/executors/Executor',
    'intern/lib/Suite',
    'intern/lib/Test'
], function (registerSuite, assert, registerCucumber, main, Executor, Suite, Test) {

Then change tests/intern.js to look like:

suites: [ 'tests/cucumber' ],

Here is the output:

$ yarn
yarn install v0.21.3
warning intern-cucumber-example: No license field
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.36s.
$ node_modules/.bin/intern-client config=tests/intern
PASS: intern/lib/interfaces/cucumber - test sanity checking (0ms)
PASS: intern/lib/interfaces/cucumber - registering a cucumber creates one empty child suite (0ms)
PASS: intern/lib/interfaces/cucumber - one scenario gives one test case (43ms)
PASS: intern/lib/interfaces/cucumber - a scenario outline gives multiple test cases (10ms)
PASS: intern/lib/interfaces/cucumber - it is possible to pass multiple step definition functions (4ms)
PASS: intern/lib/interfaces/cucumber - in functional tests "remote" is part of the World (6ms)
PASS: intern/lib/interfaces/cucumber - failing steps should give error (7ms)
PASS: intern/lib/interfaces/cucumber - missing Given step definition should give error (4ms)
PASS: intern/lib/interfaces/cucumber - ambigous step definitions should give error (7ms)
PASS: intern/lib/interfaces/cucumber - syntax errors in feature source should give error (5ms)
0/10 tests failed
0/10 tests failed

So this is at least a starting point. I may end up writing a loading loop to find all feature files in a directory and call registerCucumber() with each of their contents, unless someone knows how to pass the feature files to the cucumber interface another way (jason0x43 passed it in the define as 'intern!cucumber!tests/features/fib').

Hope this helps someone.

P.S. The reason I used 3d73693feec63d012b5e76e3a28d8e413a103f40 above was to future-proof the dependency, which will work until the repo gets taken down (it's not a permanent solution).

zmorris commented 7 years ago

Apologies, the above workaround may not be necessary. Running npm install after cloning intern-cucumber-example did not work for me, as I received an error similar to https://github.com/theintern/intern/issues/81#issuecomment-41084715 but I happened to try yarn and then npm install and it worked! I am learning node from a c++/php background so I don't know why it suddenly worked, here is the full output:

My-Computer:intern-cucumber-example me$ npm install
npm WARN excluding symbolic link query -> vendors/jquery/src/
npm WARN deprecated buffer-browserify@0.0.5: Package not maintained. Recent browserify uses https://github.com/feross/buffer
npm WARN deprecated minimatch@0.4.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated minimatch@0.3.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN excluding symbolic link query -> vendors/jquery/src/
npm WARN prefer global istanbul@0.2.16 should be installed with -g

> intern@2.1.0-pre install /Users/me/Desktop/intern-cucumber-example/node_modules/intern
> node support/fixdeps.js

intern-cucumber-example@ /Users/me/Desktop/intern-cucumber-example
├── dojo@1.9.11 
└─┬ intern@2.1.0-pre 
  ├─┬ chai@1.9.1 
  │ ├── assertion-error@1.0.0 
  │ └─┬ deep-eql@0.1.3 
  │   └── type-detect@0.1.1 
  ├─┬ cucumber@0.4.2 
  │ ├─┬ browserify@1.15.5 
  │ │ ├─┬ buffer-browserify@0.0.5 
  │ │ │ └── base64-js@0.0.2 
  │ │ ├── commondir@0.0.2 
  │ │ ├── crypto-browserify@0.4.0 
  │ │ ├── deputy@0.0.4 
  │ │ ├─┬ detective@0.2.1 
  │ │ │ └── esprima@0.9.9 
  │ │ ├─┬ http-browserify@0.1.14 
  │ │ │ ├── Base64@0.1.4 
  │ │ │ └─┬ concat-stream@1.0.1 
  │ │ │   └─┬ bops@0.0.6 
  │ │ │     └── to-utf8@0.0.1 
  │ │ ├── nub@0.0.0 
  │ │ ├── optimist@0.3.7 
  │ │ ├── resolve@0.2.8 
  │ │ ├── syntax-error@0.0.1 
  │ │ └─┬ vm-browserify@0.0.4 
  │ │   └── indexof@0.0.1 
  │ ├─┬ coffee-script@1.7.1 
  │ │ └── mkdirp@0.3.5 
  │ ├── cucumber-html@0.2.3 
  │ ├── gherkin@2.12.2 
  │ ├─┬ nopt@2.1.2 
  │ │ └── abbrev@1.1.0 
  │ ├─┬ pogo@0.5.1 
  │ │ ├── uglify-js@2.2.4 
  │ │ └── underscore@1.4.4 
  │ ├── underscore@1.5.2 
  │ ├── underscore.string@2.3.3 
  │ └── walkdir@0.0.7 
  ├─┬ digdug@1.0.0 
  │ ├─┬ decompress@0.2.3 
  │ │ ├── adm-zip@0.4.7 
  │ │ ├─┬ extname@0.1.5 
  │ │ │ └─┬ ext-list@0.2.0 
  │ │ │   └─┬ got@0.2.0 
  │ │ │     └── object-assign@0.3.1 
  │ │ ├── get-stdin@0.1.0 
  │ │ ├─┬ map-key@0.1.5 
  │ │ │ └── lodash@2.4.2 
  │ │ ├── nopt@2.2.1 
  │ │ ├─┬ rimraf@2.6.1 
  │ │ │ └─┬ glob@7.1.1 
  │ │ │   ├── fs.realpath@1.0.0 
  │ │ │   ├─┬ inflight@1.0.6 
  │ │ │   │ └── wrappy@1.0.2 
  │ │ │   ├─┬ minimatch@3.0.3 
  │ │ │   │ └─┬ brace-expansion@1.1.6 
  │ │ │   │   ├── balanced-match@0.4.2 
  │ │ │   │   └── concat-map@0.0.1 
  │ │ │   ├── once@1.4.0 
  │ │ │   └── path-is-absolute@1.0.1 
  │ │ ├─┬ stream-combiner@0.0.4 
  │ │ │ └── duplexer@0.1.1 
  │ │ ├─┬ tar@0.1.20 
  │ │ │ ├── block-stream@0.0.9 
  │ │ │ ├─┬ fstream@0.1.31 
  │ │ │ │ ├─┬ graceful-fs@3.0.11 
  │ │ │ │ │ └── natives@1.1.0 
  │ │ │ │ └── mkdirp@0.5.1 
  │ │ │ └── inherits@2.0.3 
  │ │ └─┬ tempfile@0.1.3 
  │ │   └── uuid@1.4.2 
  │ └── dojo@2.0.0-alpha1 
  ├── dojo@2.0.0-dev 
  ├─┬ istanbul@0.2.16 
  │ ├── abbrev@1.0.9 
  │ ├── async@0.9.2 
  │ ├─┬ escodegen@1.3.3 
  │ │ ├── esprima@1.1.1 
  │ │ ├── estraverse@1.5.1 
  │ │ └── esutils@1.0.0 
  │ ├── esprima@1.2.5 
  │ ├─┬ fileset@0.1.8 
  │ │ ├─┬ glob@3.2.11 
  │ │ │ └── minimatch@0.3.0 
  │ │ └─┬ minimatch@0.4.0 
  │ │   ├── lru-cache@2.7.3 
  │ │   └── sigmund@1.0.1 
  │ ├─┬ handlebars@1.3.0 
  │ │ └─┬ uglify-js@2.3.6 
  │ │   └── async@0.2.10 
  │ ├─┬ js-yaml@3.8.2 
  │ │ ├─┬ argparse@1.0.9 
  │ │ │ └── sprintf-js@1.0.3 
  │ │ └── esprima@3.1.3 
  │ ├─┬ mkdirp@0.5.1 
  │ │ └── minimist@0.0.8 
  │ ├── nopt@3.0.6 
  │ ├── resolve@0.7.4 
  │ ├── which@1.0.9 
  │ └── wordwrap@0.0.3 
  ├─┬ leadfoot@1.0.1 
  │ └── dojo@2.0.0-alpha1 
  └─┬ source-map@0.1.33 
    └── amdefine@1.0.1 

npm WARN intern-cucumber-example@ No repository field.
npm WARN intern-cucumber-example@ No license field.
My-Computer:intern-cucumber-example me$ ./node_modules/.bin/intern-client config=tests/intern
Error: Failed to load module intern/node_modules/cucumber/release/cucumber from /Users/me/Desktop/intern-cucumber-example/node_modules/intern/node_modules/cucumber/release/cucumber.js (parent: intern/lib/interfaces/cucumber)
    at ReadFileContext.callback (/Users/me/Desktop/intern-cucumber-example/node_modules/intern/node_modules/dojo/dojo.js:757:12)
    at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:365:13)
My-Computer:intern-cucumber-example me$ yarn
yarn install v0.21.3
info No lockfile found.
warning intern-cucumber-example: No license field
[1/4] 🔍  Resolving packages...
warning intern > istanbul > fileset > minimatch@0.4.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
warning intern > cucumber > browserify > buffer-browserify@0.0.5: Package not maintained. Recent browserify uses https://github.com/feross/buffer
warning intern > istanbul > fileset > glob > minimatch@0.3.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...
success Saved lockfile.
✨  Done in 2.09s.
My-Computer:intern-cucumber-example me$ ./node_modules/.bin/intern-client config=tests/intern
Error: Failed to load module intern/node_modules/cucumber/release/cucumber from /Users/me/Desktop/intern-cucumber-example/node_modules/intern/node_modules/cucumber/release/cucumber.js (parent: intern/lib/interfaces/cucumber)
    at ReadFileContext.callback (/Users/me/Desktop/intern-cucumber-example/node_modules/intern/node_modules/dojo/dojo.js:757:12)
    at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:365:13)
My-Computer:intern-cucumber-example me$ npm install
npm WARN excluding symbolic link query -> vendors/jquery/src/
npm WARN deprecated minimatch@0.4.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated minimatch@0.3.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN excluding symbolic link query -> vendors/jquery/src/
npm WARN gentlyRm not removing /Users/me/Desktop/intern-cucumber-example/node_modules/fstream/node_modules/.bin/mkdirp as it wasn't installed by /Users/me/Desktop/intern-cucumber-example/node_modules/fstream/node_modules/mkdirp
npm WARN prefer global istanbul@0.2.16 should be installed with -g

> intern@2.1.0-pre install /Users/me/Desktop/intern-cucumber-example/node_modules/intern
> node support/fixdeps.js

- minimatch@0.3.0 node_modules/glob/node_modules/minimatch
- abbrev@1.1.0 node_modules/istanbul/node_modules/nopt/node_modules/abbrev
- minimatch@3.0.3 node_modules/rimraf/node_modules/minimatch
- glob@7.1.1 node_modules/rimraf/node_modules/glob
- chai@1.9.1 node_modules/intern/node_modules/chai
intern-cucumber-example@ /Users/me/Desktop/intern-cucumber-example
└─┬ intern@2.1.0-pre 
  ├── cucumber@0.4.2 
  ├─┬ digdug@1.0.0 
  │ ├─┬ decompress@0.2.3 
  │ │ ├── adm-zip@0.4.7 
  │ │ ├─┬ extname@0.1.5 
  │ │ │ └─┬ ext-list@0.2.0 
  │ │ │   └─┬ got@0.2.0 
  │ │ │     └── object-assign@0.3.1 
  │ │ ├── get-stdin@0.1.0 
  │ │ ├─┬ map-key@0.1.5 
  │ │ │ └── lodash@2.4.2 
  │ │ ├── nopt@2.2.1 
  │ │ ├─┬ rimraf@2.6.1 
  │ │ │ └─┬ glob@7.1.1 
  │ │ │   ├── fs.realpath@1.0.0 
  │ │ │   ├─┬ inflight@1.0.6 
  │ │ │   │ └── wrappy@1.0.2 
  │ │ │   ├─┬ minimatch@3.0.3 
  │ │ │   │ └─┬ brace-expansion@1.1.6 
  │ │ │   │   ├── balanced-match@0.4.2 
  │ │ │   │   └── concat-map@0.0.1 
  │ │ │   ├── once@1.4.0 
  │ │ │   └── path-is-absolute@1.0.1 
  │ │ ├─┬ stream-combiner@0.0.4 
  │ │ │ └── duplexer@0.1.1 
  │ │ ├─┬ tar@0.1.20 
  │ │ │ ├── block-stream@0.0.9 
  │ │ │ ├─┬ fstream@0.1.31 
  │ │ │ │ ├─┬ graceful-fs@3.0.11 
  │ │ │ │ │ └── natives@1.1.0 
  │ │ │ │ └── mkdirp@0.5.1 
  │ │ │ └── inherits@2.0.3 
  │ │ └─┬ tempfile@0.1.3 
  │ │   └── uuid@1.4.2 
  │ └── dojo@2.0.0-alpha1 
  ├── dojo@2.0.0-dev 
  ├─┬ istanbul@0.2.16 
  │ ├── abbrev@1.0.9 
  │ ├── async@0.9.2 
  │ ├─┬ escodegen@1.3.3 
  │ │ ├── esprima@1.1.1 
  │ │ ├── estraverse@1.5.1 
  │ │ └── esutils@1.0.0 
  │ ├── esprima@1.2.5 
  │ ├─┬ fileset@0.1.8 
  │ │ ├─┬ glob@3.2.11 
  │ │ │ └── minimatch@0.3.0 
  │ │ └─┬ minimatch@0.4.0 
  │ │   ├── lru-cache@2.7.3 
  │ │   └── sigmund@1.0.1 
  │ ├─┬ handlebars@1.3.0 
  │ │ └─┬ uglify-js@2.3.6 
  │ │   └── async@0.2.10 
  │ ├─┬ js-yaml@3.8.2 
  │ │ ├─┬ argparse@1.0.9 
  │ │ │ └── sprintf-js@1.0.3 
  │ │ └── esprima@3.1.3 
  │ ├─┬ mkdirp@0.5.1 
  │ │ └── minimist@0.0.8 
  │ ├── nopt@3.0.6 
  │ ├── resolve@0.7.4 
  │ └── which@1.0.9 
  └─┬ leadfoot@1.0.1 
    └── dojo@2.0.0-alpha1 

npm WARN intern-cucumber-example@ No repository field.
npm WARN intern-cucumber-example@ No license field.
My-Computer:intern-cucumber-example me$ ./node_modules/.bin/intern-client config=tests/intern
PASS: main - Fibonacci test - reset (6ms)
PASS: main - Fibonacci test - nexting (8ms)
2/2 tests passed
PASS: main - Square test - reset (3ms)
PASS: main - Square test - one next (2ms)
PASS: main - Square test - two nexts (2ms)
PASS: main - Square test - four nexts (4ms)
4/4 tests passed
PASS: main - Assertions - assert_equal (1ms)
PASS: main - Assertions - assert_not_equal (1ms)
2/2 tests passed
8/8 tests passed

-------------|-----------|-----------|-----------|-----------|
File         |   % Stmts |% Branches |   % Funcs |   % Lines |
-------------|-----------|-----------|-----------|-----------|
   app/      |       100 |       100 |       100 |       100 |
      fib.js |       100 |       100 |       100 |       100 |
-------------|-----------|-----------|-----------|-----------|
All files    |       100 |       100 |       100 |       100 |
-------------|-----------|-----------|-----------|-----------|

I thought perhaps the difference was dojo@1.9.11 going to dojo@2.0.0-alpha1 but I tried changing the package to "dojo": "dojo@2.0.0-alpha1" and it still didn't work with just npm install. I'm kind of out of my element here so maybe someone with a keener eye can figure out why yarn then npm install magically fixes it.

Anyway, this provides a starting point. I think that maybe the best thing to do is pull out these cucumber examples from the PRs into their own object class that inherit's from intern's object and provides BDD's Given(), When(), Then() commands similar to what jason0x43's does. I am not certain about the feature file loader though, because other testing frameworks tend to scan a directory of feature stories and a directory of step definitions and derive a suite from them.

I'm also thinking that the true power of Intern is this ability to adapt other testing frameworks under a common convention of naming each test and specifying the steps inside of a suite. If you could write object interfaces for the testing frameworks on https://www.browserstack.com/support?tag=automate and https://watirmelon.blog/2015/12/08/comparison-of-javascript-browser-automation-and-test-specification-libraries/ you would really have something. The biggest pain of all of these frameworks is having to repeat yourself writing domain-specific language implementations of tests and then translators between human tasks/accessor functions in page objects. With a consolidated way of trying all these approaches, maybe a better way would evolve out of them.

Does anyone have an example of writing an object that calls something like cucumber.js? The learning curve for reporters and executors and stuff is pretty steep. Anyway, hope this helps someone.

dylans commented 7 years ago

I'm also thinking that the true power of Intern is this ability to adapt other testing frameworks under a common convention of naming each test and specifying the steps inside of a suite.

@zmorris To answer a small point from your comment, I often describe Intern's most important feature is that it's a really good glue architecture for combining things that are difficult to combine together normally, in a consistent, flexible, and coherent manner. It's also what I feel Dojo does pretty well, in particular the forthcoming Dojo 2. I would love to address those additions and a number of other things that we don't yet integrate with, as well as finally having a solid answer for Cucumber support!

zmorris commented 7 years ago

@dylans on that note, I decided to make a local object class that calls cucumber.js, like what jason0x43 and rhpijnacker have done except not as a pull request:

https://github.com/theintern/intern/blob/cucumber/lib/interfaces/cucumber.js https://github.com/rhpijnacker/intern/blob/master/lib/interfaces/cucumber.js

Then I will have page objects import that, treating it like the BDD object you have now. The trickiest part turned out to be loading cucumber.js, because I'm not super familiar with how Node.js modules work. I lost about half a day trying every permutation of define(['cucumber'], ...) with 'intern', 'dojo', '/' and '!' in the string and adding it as { name: 'cucumber', location: 'node_modules/cucumber' } and permutations of 'map' etc in intern.js. It was having a lot of issues where it couldn't find cucumber/main or the main of other classes. For anyone curious, you can specify main in loaderOptions like:

https://github.com/amdjs/amdjs-api/blob/master/CommonConfig.md#packages-

{ name: 'xyz', location: 'xyz', main:'main' }

but I found that it generally didn't work. I finally stumbled onto this explanation of how dojo works:

http://stackoverflow.com/a/21887408/539149

So using intern's dojo to load cucumber.js in the last line of define() like so:

define([
    'intern!../Suite',
    'intern!../Test',
    'intern',
    'dojo/aspect',
    'require',
    'dojo/topic',
    'dojo/Deferred',
    'dojo/has!host-node?dojo/node!fs:dojo/request',
    'intern/dojo/node!cucumber'
], function (Suite, Test, main, aspect, require, topic, Deferred, requestor, Lexer) {

in my local object worked perfectly, and I was able to remove references to cucumber from intern.js. Here is my local package.json:

{
    "name": "intern-cucumber",
    "dependencies": {
        "cucumber": "^1.3.1",
        "dojo": "^1.12.2",
        "intern": "^3.4.2"
    }
}

I still haven't figured out how to use intern's version of dojo when I need to call it directly, for example as 'intern!dojo/aspect' or 'intern!dojo!aspect' so unfortunately I still have dojo added locally. I also couldn't get dojo 2.0.0-alpha.7 to work locally so my version differs from intern's. If anyone knows how to do that, it would be great to get rid of my local dojo dependency.

If you could add a note about loading modules in the Intern documentation, it would be super helpful.

So after all that, I have cucumber imported but can't get it to work :-/ I think the issue is that since there is no global.window, cucumber isn't setting up its context correctly or something. I don't know if I have to set cucumber up somehow in the runner instead of the object either. I prefer jason0x43's calling convention but since it's 3 years out of date I don't know if I can get it working. It would be so great though to have objects that call other testing frameworks so people could migrate to Intern.

zmorris commented 7 years ago

I couldn't get the cucumber branch of intern to work so I started over with a new project, here is my package.json:

{
    "name": "intern-cucumber",
    "dependencies": {
        "cucumber": "^1.3.1",
        "dojo": "2.0.0-alpha.7",
        "intern": "^3.4.2"
    }
}

I then downloaded:

https://github.com/rhpijnacker/intern/blob/master/lib/interfaces/cucumber.js to /cucumber.js

changed top lines to:

define([
    'dojo/aspect',
    'dojo/Promise',
    'require',
    'intern',
    'intern!../Suite',
    'intern!../Test',
    'dojo/has!host-node?dojo/node!fs:dojo/request',
    'intern/dojo/node!cucumber'
], function (aspect, Promise, require, main, Suite, Test, requestor, cucumber) {

downloaded:

https://github.com/rhpijnacker/intern/blob/master/tests/unit/lib/interfaces/cucumber.js to /tests/cucumber.js

changed top lines to:

define([
    'intern!object',
    'intern/chai!assert',
    '../cucumber',
    'intern',
    'intern/lib/executors/Executor',
    'intern/lib/Suite',
    'intern/lib/Test'
], function (registerSuite, assert, registerCucumber, main, Executor, Suite, Test) {

here is my tests/intern.js:

define({
    proxyPort: 9000,
    proxyUrl: 'http://10.0.1.105:9000/',
    capabilities: {
        'selenium-version': '2.42.0'
    },
    environments: [
        { browserName: 'chrome' }
    ],
    maxConcurrency: 3,
    tunnel: 'NullTunnel',
    loaderOptions: {
        packages: [
            { name: 'app', location: 'app' },
            { name: 'tests', location: 'tests' },
            { name: 'dojo', location: 'node_modules/dojo' },
        ]
    },
    suites: [ 'tests/cucumber' ],
    functionalSuites: [ 'tests/functional' ],
    excludeInstrumentation: /(?:node_modules|tests)\//
});

Here is my output:

$ yarn
yarn install v0.21.3
warning intern-testing: No license field
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.37s.
$ node_modules/.bin/intern-client config=tests/intern
PASS: intern/lib/interfaces/cucumber - test sanity checking (1ms)
PASS: intern/lib/interfaces/cucumber - registering a cucumber creates one empty child suite (0ms)
FAIL: intern/lib/interfaces/cucumber - one scenario gives one test case (3ms)
TypeError: Cannot read property 'then' of undefined
  at next  <node_modules/intern/lib/Suite.js:438:14>
  at <node_modules/intern/lib/Suite.js:457:6>
  at new Promise  <node_modules/intern/browser_modules/dojo/Promise.ts:411:3>
  at runTests  <node_modules/intern/lib/Suite.js:363:12>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:393:15>
  at runCallbacks  <node_modules/intern/browser_modules/dojo/Promise.ts:11:11>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:317:4>
  at run  <node_modules/intern/browser_modules/dojo/Promise.ts:237:7>
  at <node_modules/intern/browser_modules/dojo/nextTick.ts:44:3>
  at _combinedTickCallback  <internal/process/next_tick.js:67:7>
FAIL: intern/lib/interfaces/cucumber - a scenario outline gives multiple test cases (1ms)
TypeError: Cannot read property 'then' of undefined
  at next  <node_modules/intern/lib/Suite.js:438:14>
  at <node_modules/intern/lib/Suite.js:457:6>
  at new Promise  <node_modules/intern/browser_modules/dojo/Promise.ts:411:3>
  at runTests  <node_modules/intern/lib/Suite.js:363:12>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:393:15>
  at runCallbacks  <node_modules/intern/browser_modules/dojo/Promise.ts:11:11>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:317:4>
  at run  <node_modules/intern/browser_modules/dojo/Promise.ts:237:7>
  at <node_modules/intern/browser_modules/dojo/nextTick.ts:44:3>
  at _combinedTickCallback  <internal/process/next_tick.js:67:7>
FAIL: intern/lib/interfaces/cucumber - it is possible to pass multiple step definition functions (1ms)
TypeError: Cannot read property 'then' of undefined
  at next  <node_modules/intern/lib/Suite.js:438:14>
  at <node_modules/intern/lib/Suite.js:457:6>
  at new Promise  <node_modules/intern/browser_modules/dojo/Promise.ts:411:3>
  at runTests  <node_modules/intern/lib/Suite.js:363:12>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:393:15>
  at runCallbacks  <node_modules/intern/browser_modules/dojo/Promise.ts:11:11>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:317:4>
  at run  <node_modules/intern/browser_modules/dojo/Promise.ts:237:7>
  at <node_modules/intern/browser_modules/dojo/nextTick.ts:44:3>
  at _combinedTickCallback  <internal/process/next_tick.js:67:7>
FAIL: intern/lib/interfaces/cucumber - in functional tests "remote" is part of the World (1ms)
TypeError: Cannot read property 'then' of undefined
  at next  <node_modules/intern/lib/Suite.js:438:14>
  at <node_modules/intern/lib/Suite.js:457:6>
  at new Promise  <node_modules/intern/browser_modules/dojo/Promise.ts:411:3>
  at runTests  <node_modules/intern/lib/Suite.js:363:12>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:393:15>
  at runCallbacks  <node_modules/intern/browser_modules/dojo/Promise.ts:11:11>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:317:4>
  at run  <node_modules/intern/browser_modules/dojo/Promise.ts:237:7>
  at <node_modules/intern/browser_modules/dojo/nextTick.ts:44:3>
  at _combinedTickCallback  <internal/process/next_tick.js:67:7>
FAIL: intern/lib/interfaces/cucumber - failing steps should give error (0ms)
TypeError: Cannot read property 'then' of undefined
  at next  <node_modules/intern/lib/Suite.js:438:14>
  at <node_modules/intern/lib/Suite.js:457:6>
  at new Promise  <node_modules/intern/browser_modules/dojo/Promise.ts:411:3>
  at runTests  <node_modules/intern/lib/Suite.js:363:12>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:393:15>
  at runCallbacks  <node_modules/intern/browser_modules/dojo/Promise.ts:11:11>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:317:4>
  at run  <node_modules/intern/browser_modules/dojo/Promise.ts:237:7>
  at <node_modules/intern/browser_modules/dojo/nextTick.ts:44:3>
  at _combinedTickCallback  <internal/process/next_tick.js:67:7>
FAIL: intern/lib/interfaces/cucumber - missing Given step definition should give error (4ms)
TypeError: Cannot read property 'hasPassed' of undefined
  at <tests/cucumber.js:194:28>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:393:15>
  at runCallbacks  <node_modules/intern/browser_modules/dojo/Promise.ts:11:11>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:317:4>
  at run  <node_modules/intern/browser_modules/dojo/Promise.ts:237:7>
  at <node_modules/intern/browser_modules/dojo/nextTick.ts:44:3>
  at _combinedTickCallback  <internal/process/next_tick.js:67:7>
  at process._tickCallback  <internal/process/next_tick.js:98:9>
FAIL: intern/lib/interfaces/cucumber - ambigous step definitions should give error (0ms)
TypeError: Cannot read property 'then' of undefined
  at next  <node_modules/intern/lib/Suite.js:438:14>
  at <node_modules/intern/lib/Suite.js:457:6>
  at new Promise  <node_modules/intern/browser_modules/dojo/Promise.ts:411:3>
  at runTests  <node_modules/intern/lib/Suite.js:363:12>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:393:15>
  at runCallbacks  <node_modules/intern/browser_modules/dojo/Promise.ts:11:11>
  at <node_modules/intern/browser_modules/dojo/Promise.ts:317:4>
  at run  <node_modules/intern/browser_modules/dojo/Promise.ts:237:7>
  at <node_modules/intern/browser_modules/dojo/nextTick.ts:44:3>
  at _combinedTickCallback  <internal/process/next_tick.js:67:7>
PASS: intern/lib/interfaces/cucumber - syntax errors in feature source should give error (1ms)
7/10 tests failed
7/10 tests failed

--------------|----------|----------|----------|----------|----------------|
File          |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
--------------|----------|----------|----------|----------|----------------|
 testing/     |    34.74 |     4.35 |    55.56 |    34.74 |                |
  cucumber.js |    34.74 |     4.35 |    55.56 |    34.74 |... 404,415,417 |
--------------|----------|----------|----------|----------|----------------|
All files     |    34.74 |     4.35 |    55.56 |    34.74 |                |
--------------|----------|----------|----------|----------|----------------|

The first two tests passed but then it failed due to a promise issue. I tried going in and console.log() the heck out of node_modules/intern/lib/Suite.js but I can't figure out why current is undefined on line 438 in current.then(function () {. Everything looks basically identical between the rhpijnacker fork and my local project except for file location. I think that current = runWithCatch(); is returning undefined on line 414 but I don't really know why.

If you can help me fix this last thing, I'm hopeful I can adapt this to look very much like https://github.com/jason0x43/intern-cucumber-example by adapting parts from the cucumber branch so the Given(), When(), Then() calls are in the test suite and it loads feature files. But I just can't seem to figure out the promises issue. Thanks for all your help so far.

jordangarvey commented 6 years ago

Hi @zmorris, wondering if you managed to get this working? Been trying to find any latest news on using Cucumber with Intern but the trail seems to end here, but am really interested in being able to use it.

zmorris commented 6 years ago

@jordangarvey Sorry for my late response, I just found out about https://github.com/notifications/participating haha. I had the same problem and implementing a solution would have required digging further into the Intern internals than I could muster. I ended up going with WebDriverIO running Mocha/Chai and Yadda on top of that.

The core problem here (that I've seen repeated over and over again in nearly all testing frameworks) is that BDD should have been a layer over TDD, not an alternative. So we shouldn't need a separate runner for Gherkin/Cucumber. We should be able to call out to a features/steps loader from within our unit tests, running TDD and/or BDD suites in one pass and printing all results through the same reporter, which is precisely what Yadda does.

To me, this is why BDD never caught on at nearly the level that it should have. The main aha moment for me is that BDD is for setting up context for the tests. This is perhaps more important than the human-readable aspect of it. Context and mocking turn out to be the primary challenges with things like acceptance testing, and TDD generally only addresses mocking, which severely limits it in practice.

rhpijnacker commented 6 years ago

@jordangarvey, @zmorris Maybe you want to check out https://github.com/rhpijnacker/intern-cucumber. This is a re-implementation of the earlier integration of cucumber-js for intern 4. The module is now available as a separate npm package and is loaded as a plugin. The company I work for has used the previous integration for a few years now and is moving to intern 4. This prompted us to do the rewrite.

dsb3ar commented 5 years ago

I am having trouble with implementing Before, BeforeAll, After and AfterAll using TypeScript. @rhpijnacker has advised TypeScript does not expose the After, AfterAll, Before and BeforeAll properties and to make changes to .d.ts file with these methods but I need more info on what the parameters are. Also should these be implemented as a hook or within the step definition file. It would also be helpful to know if tags and hooks are part of intern-cucumber and how these are run on the command line. Any help would be gratefully appreciated. Here is what my plugin.d.ts originally looked like:

export interface World {

} export type StepDefinitionCode = (this: World, ...stepArgs: any[]) => any; export type StepDefinitionInitializer = () => void;

export default function registerCucumber( name: string, featureSource: string, ...stepDefinitionInitializers: StepDefinitionInitializer[] ): void;

export function Given(pattern: RegExp | string, code: StepDefinitionCode): void; export function Then(pattern: RegExp | string, code: StepDefinitionCode): void; export function When(pattern: RegExp | string, code: StepDefinitionCode): void;

export interface CucumberInterface { registerCucumber( name: string, featureSource: string, ...stepDefinitionInitializers: any[] ): void;

Given(pattern: RegExp | string, code: StepDefinitionCode): void;
Then(pattern: RegExp | string, code: StepDefinitionCode): void;
When(pattern: RegExp | string, code: StepDefinitionCode): void;

}

rhpijnacker commented 5 years ago

@dsb3ar I based the typescript typings on https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/cucumber/v3/index.d.ts. So you may want to have a look at how Before and After are defined there.

smokbel1 commented 5 years ago

@zmorris Are you using Yadda with intern? I've been trying to get intern working with cucumber for ages and I've had no luck. I'm having trouble using cucumber as a plugin or loader, as I am working with karma as well, as my test runner, so adding intern plugins or loaders has been difficult since I already have a karma config file... if cucumber or yadda were already an interface option for me, this would work. Any ideas on how to implement this myself?

jason0x43 commented 4 years ago

I'm closing this (finally) given the existence of https://github.com/rhpijnacker/intern-cucumber. An external plugin seem like the best place for this functionality for now.