1
- const escapeStringRegexp = require ( 'escape-string-regexp' ) ;
2
- const fs = require ( 'fs' ) ;
3
- const Gherkin = require ( '@cucumber/gherkin' ) ;
4
- const Messages = require ( '@cucumber/messages' ) ;
5
- const glob = require ( 'glob' ) ;
6
- const fsPath = require ( 'path' ) ;
1
+ const escapeStringRegexp = require ( 'escape-string-regexp' )
2
+ const fs = require ( 'fs' )
3
+ const Gherkin = require ( '@cucumber/gherkin' )
4
+ const Messages = require ( '@cucumber/messages' )
5
+ const { globSync } = require ( 'glob' )
6
+ const fsPath = require ( 'path' )
7
7
8
- const { getConfig, getTestRoot } = require ( '../utils' ) ;
9
- const Codecept = require ( '../../codecept' ) ;
10
- const output = require ( '../../output' ) ;
11
- const { matchStep } = require ( '../../mocha/bdd' ) ;
8
+ const { getConfig, getTestRoot } = require ( '../utils' )
9
+ const Codecept = require ( '../../codecept' )
10
+ const output = require ( '../../output' )
11
+ const { matchStep } = require ( '../../mocha/bdd' )
12
12
13
- const uuidFn = Messages . IdGenerator . uuid ( ) ;
14
- const builder = new Gherkin . AstBuilder ( uuidFn ) ;
15
- const matcher = new Gherkin . GherkinClassicTokenMatcher ( ) ;
16
- const parser = new Gherkin . Parser ( builder , matcher ) ;
17
- parser . stopAtFirstError = false ;
13
+ const uuidFn = Messages . IdGenerator . uuid ( )
14
+ const builder = new Gherkin . AstBuilder ( uuidFn )
15
+ const matcher = new Gherkin . GherkinClassicTokenMatcher ( )
16
+ const parser = new Gherkin . Parser ( builder , matcher )
17
+ parser . stopAtFirstError = false
18
18
19
19
module . exports = function ( genPath , options ) {
20
- const configFile = options . config || genPath ;
21
- const testsPath = getTestRoot ( configFile ) ;
22
- const config = getConfig ( configFile ) ;
23
- if ( ! config ) return ;
20
+ const configFile = options . config || genPath
21
+ const testsPath = getTestRoot ( configFile )
22
+ const config = getConfig ( configFile )
23
+ if ( ! config ) return
24
24
25
- const codecept = new Codecept ( config , { } ) ;
26
- codecept . init ( testsPath ) ;
25
+ const codecept = new Codecept ( config , { } )
26
+ codecept . init ( testsPath )
27
27
28
28
if ( ! config . gherkin ) {
29
- output . error ( 'Gherkin is not enabled in config. Run `codecept gherkin:init` to enable it' ) ;
30
- process . exit ( 1 ) ;
29
+ output . error ( 'Gherkin is not enabled in config. Run `codecept gherkin:init` to enable it' )
30
+ process . exit ( 1 )
31
31
}
32
32
if ( ! config . gherkin . steps || ! config . gherkin . steps [ 0 ] ) {
33
- output . error ( 'No gherkin steps defined in config. Exiting' ) ;
34
- process . exit ( 1 ) ;
33
+ output . error ( 'No gherkin steps defined in config. Exiting' )
34
+ process . exit ( 1 )
35
35
}
36
36
if ( ! options . feature && ! config . gherkin . features ) {
37
- output . error ( 'No gherkin features defined in config. Exiting' ) ;
38
- process . exit ( 1 ) ;
37
+ output . error ( 'No gherkin features defined in config. Exiting' )
38
+ process . exit ( 1 )
39
39
}
40
40
if ( options . path && ! config . gherkin . steps . includes ( options . path ) ) {
41
- output . error ( `You must include ${ options . path } to the gherkin steps in your config file` ) ;
42
- process . exit ( 1 ) ;
41
+ output . error ( `You must include ${ options . path } to the gherkin steps in your config file` )
42
+ process . exit ( 1 )
43
43
}
44
44
45
- const files = [ ] ;
46
- glob . sync ( options . feature || config . gherkin . features , { cwd : options . feature ? '.' : global . codecept_dir } ) . forEach ( file => {
45
+ const files = [ ]
46
+ globSync ( options . feature || config . gherkin . features , { cwd : options . feature ? '.' : global . codecept_dir } ) . forEach ( file => {
47
47
if ( ! fsPath . isAbsolute ( file ) ) {
48
- file = fsPath . join ( global . codecept_dir , file ) ;
48
+ file = fsPath . join ( global . codecept_dir , file )
49
49
}
50
- files . push ( fsPath . resolve ( file ) ) ;
51
- } ) ;
52
- output . print ( `Loaded ${ files . length } files` ) ;
50
+ files . push ( fsPath . resolve ( file ) )
51
+ } )
52
+ output . print ( `Loaded ${ files . length } files` )
53
53
54
- const newSteps = new Map ( ) ;
54
+ const newSteps = new Map ( )
55
55
56
56
const parseSteps = steps => {
57
- const newSteps = [ ] ;
58
- let currentKeyword = '' ;
57
+ const newSteps = [ ]
58
+ let currentKeyword = ''
59
59
for ( const step of steps ) {
60
60
if ( step . keyword . trim ( ) === 'And' ) {
61
- if ( ! currentKeyword ) throw new Error ( `There is no active keyword for step '${ step . text } '` ) ;
62
- step . keyword = currentKeyword ;
61
+ if ( ! currentKeyword ) throw new Error ( `There is no active keyword for step '${ step . text } '` )
62
+ step . keyword = currentKeyword
63
63
}
64
- currentKeyword = step . keyword ;
64
+ currentKeyword = step . keyword
65
65
try {
66
- matchStep ( step . text ) ;
66
+ matchStep ( step . text )
67
67
} catch ( err ) {
68
- let stepLine ;
68
+ let stepLine
69
69
if ( / [ { } ( ) / ] / . test ( step . text ) ) {
70
70
stepLine = escapeStringRegexp ( step . text )
71
71
. replace ( / \/ / g, '\\/' )
72
72
. replace ( / \" ( .* ?) \" / g, '"(.*?)"' )
73
73
. replace ( / ( \d + \\ \. \d + ) / , '(\\d+\\.\\d+)' )
74
- . replace ( / ( \d + ) / , ' (\\d+) ' ) ;
75
- stepLine = Object . assign ( stepLine , { type : step . keyword . trim ( ) , location : step . location , regexp : true } ) ;
74
+ . replace ( / ( \d + ) / , ' (\\d+) ' )
75
+ stepLine = Object . assign ( stepLine , { type : step . keyword . trim ( ) , location : step . location , regexp : true } )
76
76
} else {
77
77
stepLine = step . text
78
78
. replace ( / \" ( .* ?) \" / g, '{string}' )
79
79
. replace ( / ( \d + \. \d + ) / , '{float}' )
80
- . replace ( / ( \d + ) / , ' {int} ' ) ;
81
- stepLine = Object . assign ( stepLine , { type : step . keyword . trim ( ) , location : step . location , regexp : false } ) ;
80
+ . replace ( / ( \d + ) / , ' {int} ' )
81
+ stepLine = Object . assign ( stepLine , { type : step . keyword . trim ( ) , location : step . location , regexp : false } )
82
82
}
83
- newSteps . push ( stepLine ) ;
83
+ newSteps . push ( stepLine )
84
84
}
85
85
}
86
- return newSteps ;
87
- } ;
86
+ return newSteps
87
+ }
88
88
89
89
const parseFile = file => {
90
- const ast = parser . parse ( fs . readFileSync ( file ) . toString ( ) ) ;
90
+ const ast = parser . parse ( fs . readFileSync ( file ) . toString ( ) )
91
91
for ( const child of ast . feature . children ) {
92
- if ( child . scenario . keyword === 'Scenario Outline' ) continue ; // skip scenario outline
92
+ if ( child . scenario . keyword === 'Scenario Outline' ) continue // skip scenario outline
93
93
parseSteps ( child . scenario . steps )
94
94
. map ( step => {
95
- return Object . assign ( step , { file : file . replace ( global . codecept_dir , '' ) . slice ( 1 ) } ) ;
95
+ return Object . assign ( step , { file : file . replace ( global . codecept_dir , '' ) . slice ( 1 ) } )
96
96
} )
97
- . map ( step => newSteps . set ( `${ step . type } (${ step } )` , step ) ) ;
97
+ . map ( step => newSteps . set ( `${ step . type } (${ step } )` , step ) )
98
98
}
99
- } ;
99
+ }
100
100
101
- files . forEach ( file => parseFile ( file ) ) ;
101
+ files . forEach ( file => parseFile ( file ) )
102
102
103
- let stepFile = options . path || config . gherkin . steps [ 0 ] ;
103
+ let stepFile = options . path || config . gherkin . steps [ 0 ]
104
104
if ( ! fs . existsSync ( stepFile ) ) {
105
- output . error ( `Please enter a valid step file path ${ stepFile } ` ) ;
106
- process . exit ( 1 ) ;
105
+ output . error ( `Please enter a valid step file path ${ stepFile } ` )
106
+ process . exit ( 1 )
107
107
}
108
108
109
109
if ( ! fsPath . isAbsolute ( stepFile ) ) {
110
- stepFile = fsPath . join ( global . codecept_dir , stepFile ) ;
110
+ stepFile = fsPath . join ( global . codecept_dir , stepFile )
111
111
}
112
112
113
113
const snippets = [ ...newSteps . values ( ) ]
@@ -117,18 +117,18 @@ module.exports = function (genPath, options) {
117
117
${ step . type } (${ step . regexp ? '/^' : "'" } ${ step } ${ step . regexp ? '$/' : "'" } , () => {
118
118
// From "${ step . file } " ${ JSON . stringify ( step . location ) }
119
119
throw new Error('Not implemented yet');
120
- });` ;
121
- } ) ;
120
+ });`
121
+ } )
122
122
123
123
if ( ! snippets . length ) {
124
- output . print ( 'No new snippets found' ) ;
125
- return ;
124
+ output . print ( 'No new snippets found' )
125
+ return
126
126
}
127
- output . success ( `Snippets generated: ${ snippets . length } ` ) ;
128
- output . print ( snippets . join ( '\n' ) ) ;
127
+ output . success ( `Snippets generated: ${ snippets . length } ` )
128
+ output . print ( snippets . join ( '\n' ) )
129
129
130
130
if ( ! options . dryRun ) {
131
- output . success ( `Snippets added to ${ output . colors . bold ( stepFile ) } ` ) ;
132
- fs . writeFileSync ( stepFile , fs . readFileSync ( stepFile ) . toString ( ) + snippets . join ( '\n' ) + '\n' ) ;
131
+ output . success ( `Snippets added to ${ output . colors . bold ( stepFile ) } ` )
132
+ fs . writeFileSync ( stepFile , fs . readFileSync ( stepFile ) . toString ( ) + snippets . join ( '\n' ) + '\n' )
133
133
}
134
- } ;
134
+ }
0 commit comments