@g_package/jest-cucumber-fusion 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.prettierignore +16 -0
  2. package/.prettierrc.json +0 -0
  3. package/LICENSE +201 -0
  4. package/README.md +165 -0
  5. package/codecov +0 -0
  6. package/codecov.SHA256SUM +1 -0
  7. package/codecov.SHA256SUM.sig +16 -0
  8. package/docs/AdditionalConfiguration.md +155 -0
  9. package/docs/GherkinTables.md +61 -0
  10. package/docs/Language.md +76 -0
  11. package/docs/ReusingStepDefinitions.md +110 -0
  12. package/docs/RunningTheExamples.md +16 -0
  13. package/docs/ScenarioOutlines.md +43 -0
  14. package/docs/StepDefinitionArguments.md +37 -0
  15. package/package.json +82 -0
  16. package/src/index.d.ts +25 -0
  17. package/src/index.js +404 -0
  18. package/test/specs/features/basic-scenarios.feature +28 -0
  19. package/test/specs/features/language.feature +41 -0
  20. package/test/specs/features/reuse-definition.feature +13 -0
  21. package/test/specs/features/scenario-outline2.feature +71 -0
  22. package/test/specs/features/scenario-outlines.feature +88 -0
  23. package/test/specs/features/step-definitions/basic-scenarios.steps.js +45 -0
  24. package/test/specs/features/step-definitions/language.steps.js +86 -0
  25. package/test/specs/features/step-definitions/reuse-code.js +17 -0
  26. package/test/specs/features/step-definitions/reuse-definition.steps.js +22 -0
  27. package/test/specs/features/step-definitions/scenario-outline2.steps.js +46 -0
  28. package/test/specs/features/step-definitions/scenario-outlines.steps.js +110 -0
  29. package/test/specs/features/step-definitions/using-dynamic-values.steps.js +70 -0
  30. package/test/specs/features/step-definitions/using-gherkin-tables.steps.js +42 -0
  31. package/test/specs/features/using-dynamic-values.feature +34 -0
  32. package/test/specs/features/using-gherkin-tables.feature +16 -0
  33. package/test/src/bank-account.js +17 -0
  34. package/test/src/online-sales.js +33 -0
  35. package/test/src/rocket.js +13 -0
  36. package/test/src/todo-list.js +20 -0
package/src/index.js ADDED
@@ -0,0 +1,404 @@
1
+ const stepsDefinition = {
2
+ given: {},
3
+ when: {},
4
+ then: {},
5
+ and: {},
6
+ but: {},
7
+ before: null,
8
+ after: null,
9
+ };
10
+
11
+ const addDefinitionFunction = (
12
+ definitionType,
13
+ regexpSentence,
14
+ fnForDefinition
15
+ ) => {
16
+ if (stepsDefinition[definitionType]) {
17
+ if (regexpSentence.constructor === RegExp)
18
+ stepsDefinition[definitionType][regexpSentence.source] = {
19
+ stepRegExp: regexpSentence,
20
+ stepExpression: null,
21
+ stepFn: fnForDefinition,
22
+ };
23
+ else if (typeof regexpSentence === "string")
24
+ stepsDefinition[definitionType][regexpSentence] = {
25
+ stepRegExp: null,
26
+ stepExpression: regexpSentence,
27
+ stepFn: fnForDefinition,
28
+ };
29
+ }
30
+ };
31
+
32
+ const Given = (regexpSentenceOrChainedObject, fnForDefinition) => {
33
+ return defineAndChain(
34
+ "given",
35
+ regexpSentenceOrChainedObject,
36
+ fnForDefinition
37
+ );
38
+ };
39
+ const When = (regexpSentenceOrChainedObject, fnForDefinition) => {
40
+ return defineAndChain("when", regexpSentenceOrChainedObject, fnForDefinition);
41
+ };
42
+ const Then = (regexpSentenceOrChainedObject, fnForDefinition) => {
43
+ return defineAndChain("then", regexpSentenceOrChainedObject, fnForDefinition);
44
+ };
45
+ const And = (regexpSentenceOrChainedObject, fnForDefinition) => {
46
+ return defineAndChain("and", regexpSentenceOrChainedObject, fnForDefinition);
47
+ };
48
+
49
+ const But = (regexpSentenceOrChainedObject, fnForDefinition) => {
50
+ return defineAndChain("but", regexpSentenceOrChainedObject, fnForDefinition);
51
+ };
52
+
53
+ const defineAndChain = (stepType, stepObjectOrSentence, fnForStep) => {
54
+ if (
55
+ !fnForStep &&
56
+ stepObjectOrSentence instanceof Object &&
57
+ Object.prototype.toString.call(stepObjectOrSentence) !==
58
+ "[object RegExp]" &&
59
+ stepObjectOrSentence.stepSentence
60
+ ) {
61
+ addDefinitionFunction(
62
+ stepType,
63
+ stepObjectOrSentence.stepSentence,
64
+ stepObjectOrSentence.stepFnDefinition
65
+ );
66
+
67
+ return stepObjectOrSentence;
68
+ }
69
+
70
+ addDefinitionFunction(stepType, stepObjectOrSentence, fnForStep);
71
+
72
+ return { stepSentence: stepObjectOrSentence, stepFnDefinition: fnForStep };
73
+ };
74
+
75
+ const Before = (fnDefinition) => {
76
+ stepsDefinition.before = fnDefinition;
77
+ };
78
+ const After = (fnDefinition) => {
79
+ stepsDefinition.after = fnDefinition;
80
+ };
81
+
82
+ const Fusion = (featureFileToLoad, optionsToPassToJestCucumber) => {
83
+ const path = require("path");
84
+ const callerSites = require("callsites");
85
+ const callerSiteCaller = callerSites.default()[1].getFileName();
86
+ const dirOfCaller = path.dirname(callerSiteCaller || "");
87
+ const absoluteFeatureFilePath = path.resolve(dirOfCaller, featureFileToLoad);
88
+
89
+ const jestCucumber = require("jest-cucumber");
90
+ const feature = jestCucumber.loadFeature(
91
+ absoluteFeatureFilePath,
92
+ optionsToPassToJestCucumber
93
+ );
94
+
95
+ jestCucumber.defineFeature(feature, (testFn) => {
96
+ if (feature.scenarios.length > 0)
97
+ matchJestTestSuiteWithCucumberFeature(
98
+ feature.scenarios,
99
+ beforeEach,
100
+ afterEach,
101
+ testFn
102
+ );
103
+
104
+ if (feature.scenarioOutlines.length > 0)
105
+ matchJestTestSuiteWithCucumberFeature(
106
+ feature.scenarioOutlines,
107
+ beforeEach,
108
+ afterEach,
109
+ testFn,
110
+ true
111
+ );
112
+ });
113
+ };
114
+
115
+ const matchJestTestSuiteWithCucumberFeature = (
116
+ featureScenariosOrOutline,
117
+ beforeEachFn,
118
+ afterEachFn,
119
+ testFn,
120
+ isOutline
121
+ ) => {
122
+ featureScenariosOrOutline.forEach((currentScenarioOrOutline) => {
123
+ if (stepsDefinition.before) beforeEachFn(stepsDefinition.before);
124
+
125
+ matchJestTestWithCucumberScenario(
126
+ currentScenarioOrOutline.title,
127
+ currentScenarioOrOutline.steps,
128
+ testFn,
129
+ isOutline
130
+ );
131
+
132
+ if (stepsDefinition.after) afterEachFn(stepsDefinition.after);
133
+ });
134
+ };
135
+
136
+ const matchJestTestWithCucumberScenario = (
137
+ currentScenarioTitle,
138
+ currentScenarioSteps,
139
+ testFn,
140
+ isOutline
141
+ ) => {
142
+ testFn(currentScenarioTitle, ({ given, when, then, and, but }) => {
143
+ currentScenarioSteps.forEach((currentStep) => {
144
+ matchJestDefinitionWithCucumberStep(
145
+ { given, when, then, and, but },
146
+ currentStep,
147
+ isOutline
148
+ );
149
+ });
150
+ });
151
+ };
152
+
153
+ const matchJestDefinitionWithCucumberStep = (
154
+ verbFunction,
155
+ currentStep,
156
+ isOutline
157
+ ) => {
158
+ const foundMatchingStep = findMatchingStep(currentStep, isOutline);
159
+ if (!foundMatchingStep) return;
160
+
161
+ // this will be the "given", "when", "then"...functions
162
+ verbFunction[currentStep.keyword](
163
+ foundMatchingStep.stepExpression,
164
+ foundMatchingStep.stepFn
165
+ );
166
+ };
167
+
168
+ const findMatchingStep = (currentStep, isOutline) => {
169
+ const scenarioType = currentStep.keyword;
170
+ const scenarioSentence = currentStep.stepText;
171
+ const foundStep = Object.keys(stepsDefinition[scenarioType]).find(
172
+ (currentStepDefinitionFunction) => {
173
+ return isFunctionForScenario(
174
+ scenarioSentence,
175
+ stepsDefinition[scenarioType][currentStepDefinitionFunction],
176
+ isOutline
177
+ );
178
+ }
179
+ );
180
+ if (!foundStep) return null;
181
+
182
+ return injectVariable(
183
+ scenarioType,
184
+ scenarioSentence,
185
+ foundStep,
186
+ currentStep.stepArgument
187
+ );
188
+ };
189
+
190
+ const isFunctionForScenario = (
191
+ scenarioSentence,
192
+ stepDefinitionFunction,
193
+ isOutline
194
+ ) => {
195
+ if (stepDefinitionFunction.stepRegExp) {
196
+ if (isOutline && /<[\w]*>/.test(scenarioSentence)) {
197
+ return isPotentialStepFunctionForScenario(
198
+ scenarioSentence,
199
+ stepDefinitionFunction.stepRegExp
200
+ );
201
+ } else return scenarioSentence.match(stepDefinitionFunction.stepRegExp);
202
+ }
203
+
204
+ return scenarioSentence === stepDefinitionFunction.stepExpression;
205
+ };
206
+
207
+ const isPotentialStepFunctionForScenario = (
208
+ scenarioDefinition,
209
+ regStepFunc
210
+ ) => {
211
+ //so this one is tricky, to ensure we only find the
212
+ // step definition corresponding to actual steps function in the case of outlined gherkin
213
+ // we have to "disable" the outlining (since it can replace regular expression
214
+ // and then ensure that all "non-outlined" part do respect the regular expression of
215
+ // of the step function
216
+ // FIRST, we clean the string version of the step definition that has outline variable
217
+ const cleanedStepFunc = regStepFunc.source
218
+ .replace(/^\^/, "")
219
+ // .replace( /\\\(/g, '(' )
220
+ // .replace( /\\\)/g, ')')
221
+ // .replace( /\\\^/g, '^')
222
+ // .replace( /\\\$/g, '$')
223
+ .replace(/\$$/, "");
224
+ // .replace( /\([.\\]+[sSdDwWbB*][*?+]?\)|\(\[.*\](?:[+?*]{1}|\{\d\})\)/g, '' )
225
+
226
+ let currentScenarioPart;
227
+ let currentStepFuncLeft = cleanedStepFunc;
228
+ let currentScenarioDefLeft = scenarioDefinition;
229
+
230
+ //we step through each of the scenario outline variables
231
+ // from there, we will try to detect any regexp present in the
232
+ // step definition, so that we can ensure to find the right match
233
+ while (
234
+ (currentScenarioPart = /<[\w]*>/gi.exec(currentScenarioDefLeft)) != null
235
+ ) {
236
+ let fixedPart = currentScenarioPart.input.substring(
237
+ 0,
238
+ currentScenarioPart.index
239
+ );
240
+ let idxCutScenarioPart =
241
+ currentScenarioPart.index + currentScenarioPart[0].length;
242
+
243
+ const regEscapedStepFunc = /\([a-zA-Z0!|,:?*+.^=${}><\\\-]+\)/g.exec(
244
+ currentStepFuncLeft
245
+ .replace(/\\\(/g, "(")
246
+ .replace(/\\\)/g, ")")
247
+ .replace(/\\\^/g, "^")
248
+ .replace(/\\\$/g, "$")
249
+ );
250
+ const regStepFuncLeft = /\([a-zA-Z0!|,:?*+.^=${}><\\\-]+\)/g.exec(
251
+ currentStepFuncLeft
252
+ );
253
+
254
+ if (
255
+ regStepFuncLeft &&
256
+ regEscapedStepFunc.index == currentScenarioPart.index
257
+ ) {
258
+ //if we have a regex inside our step function definition
259
+ // and that regex is at the same position than our Outlined variable
260
+ // we just need to check that the sentence match,
261
+ // so we can "evaluate" the step function and remove the regex in it
262
+ currentStepFuncLeft =
263
+ regEscapedStepFunc.input.substring(0, regEscapedStepFunc.index) +
264
+ currentStepFuncLeft.substring(
265
+ regStepFuncLeft.index + regStepFuncLeft[0].length
266
+ );
267
+ } else if (
268
+ regStepFuncLeft &&
269
+ regStepFuncLeft.index < currentScenarioPart.index
270
+ ) {
271
+ //if we have a regex inside our step function definition
272
+ // but that regex is not at the same position than our outlined variable
273
+ // we need to evaluate the regex against the scenario part
274
+ const strRegexToEvaluate = regStepFuncLeft.input.substring(
275
+ 0,
276
+ regStepFuncLeft.index + regStepFuncLeft[0].length
277
+ );
278
+ const regexToEvaluate = new RegExp(strRegexToEvaluate);
279
+ const regIntermediatePart = regexToEvaluate.exec(
280
+ currentScenarioPart.input
281
+ );
282
+ if (regIntermediatePart) {
283
+ fixedPart = regStepFuncLeft.input.substring(
284
+ 0,
285
+ regStepFuncLeft.index + regStepFuncLeft[0].length
286
+ );
287
+ idxCutScenarioPart = regIntermediatePart[0].length;
288
+ }
289
+ }
290
+
291
+ const partIndex = currentStepFuncLeft.indexOf(fixedPart);
292
+ if (partIndex !== -1) {
293
+ currentStepFuncLeft = currentStepFuncLeft.substring(
294
+ partIndex + fixedPart.length
295
+ );
296
+ currentScenarioDefLeft =
297
+ currentScenarioDefLeft.substring(idxCutScenarioPart);
298
+ } else {
299
+ return false;
300
+ }
301
+ }
302
+
303
+ return (
304
+ (currentScenarioDefLeft === "" && currentStepFuncLeft === "") ||
305
+ evaluateStepFuncEndVsScenarioEnd(
306
+ currentStepFuncLeft,
307
+ currentScenarioDefLeft
308
+ )
309
+ );
310
+ };
311
+
312
+ const evaluateStepFuncEndVsScenarioEnd = (
313
+ stepFunctionDef,
314
+ scenarioDefinition
315
+ ) => {
316
+ if (
317
+ /\(.*(\?\:)?[.\\]*[sSdDwWbB*][*?+]?.*\)|\(\[.*\](?:[+?*]{1}|\{\d\})\)/g.test(
318
+ stepFunctionDef
319
+ )
320
+ ) {
321
+ return new RegExp(stepFunctionDef).test(scenarioDefinition);
322
+ }
323
+
324
+ return stepFunctionDef.endsWith(scenarioDefinition);
325
+ };
326
+
327
+ const injectVariable = (
328
+ scenarioType,
329
+ scenarioSentence,
330
+ stepFunctionDefinition,
331
+ stepArgs
332
+ ) => {
333
+ const stepObject = stepsDefinition[scenarioType][stepFunctionDefinition];
334
+
335
+ if (!stepObject.stepRegExp)
336
+ return {
337
+ stepExpression: scenarioSentence,
338
+ // Forward through a rest-param wrapper so the reported arity is 0.
339
+ // jest-cucumber v4.4.0+ treats an arity mismatch (stepFn.length >
340
+ // matched args) as a request for a done() callback and then blocks
341
+ // on a Promise that never resolves. A rest param has length 0 while
342
+ // still passing along whatever args jest-cucumber provides.
343
+ stepFn: (...args) => stepObject.stepFn(...args),
344
+ };
345
+
346
+ const exprMatches = stepObject.stepRegExp.exec(scenarioSentence);
347
+
348
+ if (!exprMatches || /<.*>/.test(scenarioSentence))
349
+ return {
350
+ stepExpression: stepObject.stepRegExp,
351
+ // See note above: keep arity 0 to avoid jest-cucumber's done-callback
352
+ // heuristic hanging the step (matters for plain scenarios whose text
353
+ // contains "<...>" and for outline template steps).
354
+ stepFn: (...args) => stepObject.stepFn(...args),
355
+ };
356
+
357
+ const dynamicMatchThatAreVariables = [];
358
+
359
+ exprMatches.forEach((match, groupIndex) => {
360
+ if (groupIndex > 0) dynamicMatchThatAreVariables.push(match);
361
+ });
362
+
363
+ if (Array.isArray(stepArgs) && stepArgs.length > 0) {
364
+ dynamicMatchThatAreVariables.push(stepArgs);
365
+ }
366
+
367
+ return {
368
+ stepExpression: stepObject.stepRegExp,
369
+ stepFn: () => stepObject.stepFn(...dynamicMatchThatAreVariables),
370
+ };
371
+ };
372
+
373
+ // const path = require( 'path' )
374
+ //
375
+ // function walkthroughDirectory( directoryName, bRecursive, fnDoForEachFile ) {
376
+ // const filesystem = require( 'fs' )
377
+ // let filenamesOrDirectorynames = filesystem.readdirSync( directoryName )
378
+ //
379
+ // filenamesOrDirectorynames.forEach( ( currentFilenameOrDirectoryname ) => {
380
+ // let currentFilepath = path.join( directoryName, currentFilenameOrDirectoryname )
381
+ // let currentFileStats = filesystem.statSync( currentFilepath )
382
+ // if( bRecursive && currentFileStats.isDirectory() )
383
+ // walkthroughDirectory( currentFilepath, activeLoadings, bRecursive, fnOnLoading )
384
+ //
385
+ // else
386
+ // fnDoForEachFile( currentFilepath )
387
+ // } )
388
+ // }
389
+
390
+ // function FusionAll( dirFeatureFiles, bRecursive ) {
391
+ // const dirFinalDirectory = ( !dirFeatureFiles ? '<rootDir>/test/feature' : dirFeatureFiles )
392
+ //
393
+ // walkthroughDirectory( dirFinalDirectory, bRecursive, Fusion )
394
+ // }
395
+
396
+ module.exports.Before = Before;
397
+ module.exports.After = After;
398
+ module.exports.Given = Given;
399
+ module.exports.When = When;
400
+ module.exports.Then = Then;
401
+ module.exports.And = And;
402
+ module.exports.But = But;
403
+ module.exports.Fusion = Fusion;
404
+ // module.exports.FusionAll = FusionAll
@@ -0,0 +1,28 @@
1
+ Feature: Rocket Launching
2
+
3
+ Scenario: Launching a SpaceX rocket
4
+ Given I am Elon Musk attempting to launch a rocket into space
5
+ When I launch the rocket
6
+ Then the rocket should end up in space
7
+ And the booster(s) should land back on the launch pad
8
+ But nobody should doubt me ever again
9
+
10
+ Scenario: Launching my ASCII rocket
11
+ Given I am Elon Musk attempting to launch a rocket into space
12
+ When I launch the '<rocket>'
13
+ Then the rocket should end up in space
14
+ And the booster(s) should land back on the launch pad
15
+ But nobody should doubt me ever again
16
+
17
+ Scenario: Launching my personal ASCII rocket
18
+ Given I am Elon Musk attempting to launch a rocket into space
19
+ When I launch my personal rocket named '<space poney==>'
20
+ Then the rocket should end up in space
21
+ And the booster(s) should land back on the launch pad
22
+ But nobody should doubt me ever again
23
+
24
+ Scenario: Folding ourselves in 2D
25
+ Given I am Elon Musk attempting to launch a rocket into space
26
+ And my position in 2D space is [ 0, 2 ]
27
+ When I launch the rocket
28
+ Then the rocket should end up in space
@@ -0,0 +1,41 @@
1
+ # language: nl
2
+
3
+ Functionaliteit: Online verkopen
4
+
5
+ Scenario: t-shirt verkopen
6
+ Gegeven ik heb een t-shirt
7
+ Als ik een t-shirt wil verkopen
8
+ Dan ontvang ik €22
9
+ En ben ik blij
10
+ Maar heb ik geen t-shirts over
11
+
12
+ Abstract Scenario: <Object> verkopen
13
+ Gegeven ik heb een: <Object>
14
+ Als ik <Object> verkoop
15
+ Dan zou ik er €<Bedrag> voor moeten krijgen
16
+
17
+ Voorbeelden:
18
+
19
+ | Object | Bedrag |
20
+ | Autographed Neil deGrasse Tyson book | 100 |
21
+ | Rick Astley t-shirt | 22 |
22
+ | An idea to replace EVERYTHING with blockchains | 0 |
23
+
24
+ Scenario: Boek kopen
25
+ Gegeven 'Autographed Neil deGrasse Tyson book' is te koop
26
+ Als ik 'Autographed Neil deGrasse Tyson book' koop
27
+ Dan heb ik €100 uitgegeven
28
+
29
+ Scenario: voorraad bijvullen
30
+ Gegeven mijn voorraad bevat:
31
+ | Object |
32
+ | Autographed Neil deGrasse Tyson book |
33
+ | Rick Astley t-shirt |
34
+ Als ik de volgende producten toevoeg:
35
+ | Object |
36
+ | Smurfen stripboek |
37
+ Dan zitten er 3 objecten in mijn voorraad, bestaant uit:
38
+ | Object |
39
+ | Autographed Neil deGrasse Tyson book |
40
+ | Rick Astley t-shirt |
41
+ | Smurfen stripboek |
@@ -0,0 +1,13 @@
1
+ Feature: Rocket reuse
2
+
3
+ Scenario: Reusing a SpaceX rocket
4
+ Given I am Elon Musk and I launched a rocket in space already
5
+ When I relaunch the rocket
6
+ Then the rocket end up in space again
7
+ And I drop my mic
8
+
9
+ Scenario: Reading the critics
10
+ Given I am Elon Musk and I launched a rocket in space already
11
+ When I relaunch the rocket
12
+ Then the mission was said to be 'a success'
13
+ And the mission was said to be 'a wonder'
@@ -0,0 +1,71 @@
1
+ Feature: Scenario Outline verification
2
+
3
+ Scenario Outline: Simple Scenario Outline. Buy item: <Item>
4
+ This scenario use Before fusion hook (see scenario-outline2.steps.js)
5
+ This hook is remove all items from list of onlineSales if number of items >=2.
6
+ This scenario also demonstrate case dependancy in scenario outline:
7
+ if you are using some global variable it is not clear between scenarious.
8
+
9
+ Given I have <nItems> items for sale
10
+ When I bought "<Item>"
11
+ Then I have <aItems> items for sale
12
+
13
+ Examples:
14
+ | nItems | Item | aItems |
15
+ | 0 | Mist written by Stephen King | 1 |
16
+ | 1 | Metallica. ReLoad. | 2 |
17
+
18
+ Scenario Outline: Complex Scenario Outline. <nItems>
19
+ Given I have <nItems> items for sale
20
+ When I bought the following items:
21
+ | Item |
22
+ | Mist written by Stephen King |
23
+ | Metallica. ReLoad. |
24
+
25
+ Then I have <aItems> items for sale
26
+
27
+ Examples:
28
+ | nItems | aItems |
29
+ | 0 | 2 |
30
+
31
+ Scenario: Complex Scenario
32
+ This scenario is necessary to make sure that related steps are working without examples.
33
+
34
+ Given I have 0 items for sale
35
+
36
+ When I bought the following items:
37
+ | Item |
38
+ | Mist written by Stephen King |
39
+ | Metallica. ReLoad. |
40
+ | Sabaton. Great War |
41
+
42
+ Then I have 3 items for sale
43
+
44
+ Then I want to sell 2 items if they in list
45
+ | Item |
46
+ | Sabaton. Great War |
47
+ | Cucumber for dummies |
48
+
49
+ Scenario Outline: Using examples in sentance and in table
50
+
51
+ Given I have 0 items for sale
52
+
53
+ When I bought the following items:
54
+ | Item |
55
+ | Mist written by Stephen King |
56
+ | Metallica. ReLoad. |
57
+ | Sabaton. Great War |
58
+
59
+ Then I have 3 items for sale
60
+
61
+ Then I want to sell <nSale> items if they in list
62
+ | Item |
63
+ | Sabaton. Great War |
64
+ | <SaleItemName> |
65
+
66
+ Then I have <NItems> items for sale
67
+
68
+ Examples:
69
+ | nSale | SaleItemName | NItems |
70
+ | 2 | Cucumber for dummies | 2 |
71
+ | 3 | Mist written by Stephen King | 1 |
@@ -0,0 +1,88 @@
1
+ Feature: Online sales
2
+
3
+ Scenario Outline: Selling an <Item>
4
+ Given I have a(n) <Item>
5
+ When I sell the <Item>
6
+ Then I should get $<Amount>
7
+
8
+ Examples:
9
+
10
+ | Item | Amount |
11
+ | Autographed Neil deGrasse Tyson book | 100 |
12
+ | Rick Astley t-shirt | 22 |
13
+ | An idea to replace EVERYTHING with blockchains | 0 |
14
+
15
+
16
+ Scenario Outline: Selling all of one
17
+ Given I want to sell all my <Item>
18
+ When I sell all my <Item> at the price of $<Amount> CAD
19
+ Then I should still get $<Amount>
20
+
21
+ Examples:
22
+
23
+ | Item | Amount |
24
+ | Autographed Neil deGrasse Tyson book | 100 |
25
+ | Rick Astley t-shirt | 22 |
26
+ | An idea to replace EVERYTHING with blockchains | 0 |
27
+
28
+
29
+ Scenario: Selling a thing
30
+ Given I have an Item named '<ThatCouldLookLikeAnOutlineVariable>'
31
+ When I sell <ThatCouldLookLikeAnOutlineVariable With Spaces in it>
32
+ Then I get $<Amount>
33
+
34
+
35
+ Scenario Outline: Additional regexp in outline line
36
+ Given I want to sell all my <Item>
37
+ When I sell all my <Item> at the price of $100 CAD
38
+ Then I should still get $<Amount>
39
+
40
+ Examples:
41
+ | Item | Amount |
42
+ | Autographed Neil deGrasse Tyson book | 100 |
43
+ | Rick Astley t-shirt | 100 |
44
+
45
+
46
+ Scenario Outline: Additional regexp in outline line with non-string variables for <Item>
47
+ Given I want to sell all my <Item>
48
+ When I sell all my <Item> with a starting price of $<StartingPrice> at the rebate price of $100
49
+ Then I should still get $<Amount>
50
+
51
+ Examples:
52
+ | Item | StartingPrice | Amount |
53
+ | Autographed Neil deGrasse Tyson book | 100 | 100 |
54
+ | Rick Astley t-shirt | 22 | 100 |
55
+ #
56
+ #
57
+ Scenario Outline: Additional regexp in outline line with non-string variables and static one in the middle for <Item>
58
+ Given I want to sell all my <Item>
59
+ When I sell all my <Item> with a starting price of $100 at the rebate price of $<RebatePrice>
60
+ Then I should still get $<Amount>
61
+
62
+ Examples:
63
+ | Item | RebatePrice | Amount |
64
+ | Autographed Neil deGrasse Tyson book | 20 | 20 |
65
+ | Rick Astley t-shirt | 50 | 50 |
66
+
67
+
68
+ Scenario Outline: Additional regepx in outline line with non-string variable at the end for <Item>
69
+ Given I want to sell all my <Item>
70
+ When I sell all my <Item> with a starting price of $100 at the rebate price of $<RebatePrice>
71
+ Then the 1st item 1st price has a price amount of <Amount> which is a 'Number'
72
+
73
+ Examples:
74
+ | Item | RebatePrice | Amount |
75
+ | Autographed Neil deGrasse Tyson book | 20 | 20 |
76
+ | Rick Astley t-shirt | 50 | 50 |
77
+ # Ability: this ones are not currently possible
78
+ ##
79
+ # Scenario Outline: Additional mix regexp and non-regexp in outline line with non-string variables and static one in the middle for <Item>
80
+ # Given I want to sell all my <Item>
81
+ # When I sell all my <Item> with a starting price <Description> price of <RebatePrice>$ <Currency> which is nice
82
+ # Then I should still get $<Amount>
83
+ #
84
+ # Examples:
85
+ # | Item | Description | RebatePrice | Amount | Currency |
86
+ # | Autographed Neil deGrasse Tyson book | of $100 at the fantastic | 20 | 20 | USD |
87
+ # | Rick Astley t-shirt | of $100 at the fantastic | 50 | 50 | CAD |
88
+ # | Rick Astley t-shirt | of $100 at the rebate | 50 | 50 | CAD |
@@ -0,0 +1,45 @@
1
+ const { Given, When, Then, And, But, Fusion } = require("../../../../src");
2
+
3
+ const { Rocket } = require("../../../src/rocket");
4
+
5
+ let rocket;
6
+
7
+ Given("I am Elon Musk attempting to launch a rocket into space", () => {
8
+ rocket = new Rocket();
9
+ });
10
+
11
+ When("I launch the rocket", () => {
12
+ rocket.launch();
13
+ });
14
+
15
+ When("I launch the '<rocket>'", () => {
16
+ rocket.launch();
17
+ });
18
+
19
+ When(/^I launch my personal rocket named '(.*)'$/, (nameRocket) => {
20
+ expect(nameRocket).toBeDefined();
21
+ rocket.launch();
22
+ });
23
+
24
+ Then("the rocket should end up in space", () => {
25
+ expect(rocket.isInSpace).toBe(true);
26
+ });
27
+
28
+ /// Complex Regex : at position (\[(?: *\d+(?: |, |,)*)+\]) with no value
29
+ And(
30
+ /^my position in 2D space is (\[(?: *\d+(?: |, |,)*)+\])$/,
31
+ (arrayPosition) => {
32
+ const isAnArray = JSON.parse(arrayPosition);
33
+ expect(isAnArray).toBeInstanceOf(Array);
34
+ }
35
+ );
36
+
37
+ And(/^the booster\(s\) should land back on the launch pad$/, () => {
38
+ expect(rocket.boostersLanded).toBe(true);
39
+ });
40
+
41
+ But("nobody should doubt me ever again", () => {
42
+ expect("people").not.toBe("haters");
43
+ });
44
+
45
+ Fusion("../basic-scenarios.feature");