4
4
* See COPYING.txt for license details.
5
5
*/
6
6
7
+ use Symfony \Component \Yaml \Yaml ;
8
+
7
9
/** This is project's console commands configuration for Robo task runner.
8
10
*
9
11
* @codingStandardsIgnoreStart
@@ -13,6 +15,12 @@ class RoboFile extends \Robo\Tasks
13
15
{
14
16
use Robo \Task \Base \loadShortcuts;
15
17
18
+ public function __construct ()
19
+ {
20
+ require 'tests ' . DIRECTORY_SEPARATOR . 'functional ' . DIRECTORY_SEPARATOR . '_bootstrap.php ' ;
21
+ define ('VENDOR_BIN_PATH ' , PROJECT_ROOT . DIRECTORY_SEPARATOR . 'vendor ' . DIRECTORY_SEPARATOR . 'bin ' . DIRECTORY_SEPARATOR );
22
+
23
+ }
16
24
/**
17
25
* Duplicate the Example configuration files used to customize the Project for customization.
18
26
*
@@ -25,6 +33,66 @@ function cloneFiles()
25
33
$ this ->_exec ('cp -vf tests ' . DIRECTORY_SEPARATOR .'functional.suite.dist.yml tests ' . DIRECTORY_SEPARATOR .'functional.suite.yml ' );
26
34
}
27
35
36
+ /**
37
+ * Finds relative paths between codeception.yml file and MFTF path, and overwrites the default paths.
38
+ *
39
+ * @return void
40
+ */
41
+ private function buildCodeceptionPaths ()
42
+ {
43
+ $ relativePathFunc = function ($ from , $ to )
44
+ {
45
+ $ from = is_dir ($ from ) ? rtrim ($ from , '\/ ' ) . '/ ' : $ from ;
46
+ $ to = is_dir ($ to ) ? rtrim ($ to , '\/ ' ) . '/ ' : $ to ;
47
+ $ from = str_replace ('\\' , '/ ' , $ from );
48
+ $ to = str_replace ('\\' , '/ ' , $ to );
49
+
50
+ $ from = explode ('/ ' , $ from );
51
+ $ to = explode ('/ ' , $ to );
52
+ $ relPath = $ to ;
53
+
54
+ foreach ($ from as $ depth => $ dir ) {
55
+ // find first non-matching dir
56
+ if ($ dir === $ to [$ depth ]) {
57
+ // ignore this directory
58
+ array_shift ($ relPath );
59
+ } else {
60
+ // get number of remaining dirs to $from
61
+ $ remaining = count ($ from ) - $ depth ;
62
+ if ($ remaining > 1 ) {
63
+ // add traversals up to first matching dir
64
+ $ padLength = (count ($ relPath ) + $ remaining - 1 ) * -1 ;
65
+ $ relPath = array_pad ($ relPath , $ padLength , '.. ' );
66
+ break ;
67
+ } else {
68
+ $ relPath [0 ] = './ ' . $ relPath [0 ];
69
+ }
70
+ }
71
+ }
72
+ return implode ('/ ' , $ relPath );
73
+ };
74
+
75
+ //Find travel path from codeception.yml to FW_BP
76
+ $ configYmlPath = dirname (dirname (TESTS_BP )) . DIRECTORY_SEPARATOR ;
77
+ $ relativePath = call_user_func ($ relativePathFunc , $ configYmlPath , FW_BP );
78
+ $ configYmlFile = $ configYmlPath . "codeception.yml " ;
79
+ $ defaultConfigYmlFile = $ configYmlPath . "codeception.dist.yml " ;
80
+
81
+ if (file_exists ($ configYmlFile )) {
82
+ $ ymlContents = file_get_contents ($ configYmlFile );
83
+ } else {
84
+ $ ymlContents = file_get_contents ($ defaultConfigYmlFile );
85
+ }
86
+ $ ymlArray = Yaml::parse ($ ymlContents ) ?? [];
87
+ if (!array_key_exists ("paths " , $ ymlArray )) {
88
+ $ ymlArray ["paths " ] = [];
89
+ }
90
+ $ ymlArray ["paths " ]["support " ] = $ relativePath . 'src/Magento/FunctionalTestingFramework ' ;
91
+ $ ymlArray ["paths " ]["envs " ] = $ relativePath . 'etc/_envs ' ;
92
+ $ ymlText = Yaml::dump ($ ymlArray , 10 );
93
+ file_put_contents ($ configYmlFile , $ ymlText );
94
+ }
95
+
28
96
/**
29
97
* Duplicate the Example configuration files for the Project.
30
98
* Build the Codeception project.
@@ -34,29 +102,110 @@ function cloneFiles()
34
102
function buildProject ()
35
103
{
36
104
$ this ->cloneFiles ();
37
- $ this ->_exec ('vendor ' . DIRECTORY_SEPARATOR .'bin ' . DIRECTORY_SEPARATOR .'codecept build ' );
105
+ $ this ->buildCodeceptionPaths ();
106
+ $ this ->_exec (VENDOR_BIN_PATH .'codecept build ' );
38
107
}
39
108
40
109
/**
41
- * Generate all Tests in PHP.
110
+ * Generate all Tests in PHP OR Generate set of tests via passing array of tests
42
111
*
112
+ * @param array $tests
43
113
* @param array $opts
44
114
* @return void
45
115
*/
46
- function generateTests ($ opts = ['config ' => null , 'force ' => false , 'nodes ' => null ])
116
+ function generateTests (array $ tests , $ opts = [
117
+ 'config ' => null ,
118
+ 'force ' => false ,
119
+ 'nodes ' => null ,
120
+ 'lines ' => 500 ,
121
+ 'tests ' => null
122
+ ])
47
123
{
48
- $ GLOBALS ['GENERATE_TESTS ' ] = true ;
124
+ require 'tests ' . DIRECTORY_SEPARATOR . 'functional ' . DIRECTORY_SEPARATOR . '_bootstrap.php ' ;
125
+ $ testConfiguration = $ this ->createTestConfiguration ($ tests , $ opts );
49
126
50
- if ($ opts ['force ' ])
51
- {
52
- $ GLOBALS ['FORCE_PHP_GENERATE ' ] = true ;
127
+ // maintain backwards compatability for devops by not removing the nodes option yet
128
+ $ lines = $ opts ['lines ' ];
129
+
130
+ // create our manifest file here
131
+ $ testManifest = \Magento \FunctionalTestingFramework \Util \Manifest \TestManifestFactory::makeManifest ($ opts ['config ' ],$ testConfiguration ['suites ' ]);
132
+ \Magento \FunctionalTestingFramework \Util \TestGenerator::getInstance (null , $ testConfiguration ['tests ' ])->createAllTestFiles ($ testManifest );
133
+
134
+ if ($ opts ['config ' ] == 'parallel ' ) {
135
+ $ testManifest ->createTestGroups ($ lines );
53
136
}
54
137
55
- require 'tests ' . DIRECTORY_SEPARATOR . 'functional ' . DIRECTORY_SEPARATOR . '_bootstrap.php ' ;
56
- \Magento \FunctionalTestingFramework \Util \TestGenerator::getInstance ()->createAllTestFiles ($ opts ['config ' ], $ opts ['nodes ' ]);
138
+ \Magento \FunctionalTestingFramework \Suite \SuiteGenerator::getInstance ()->generateAllSuites ($ testManifest );
139
+ $ testManifest ->generate ();
140
+
57
141
$ this ->say ("Generate Tests Command Run " );
58
142
}
59
143
144
+
145
+ /**
146
+ * Function which builds up a configuration including test and suites for consumption of Magento generation methods.
147
+ *
148
+ * @param array $tests
149
+ * @param array $opts
150
+ * @return array
151
+ */
152
+ private function createTestConfiguration ($ tests , $ opts )
153
+ {
154
+ // set our application configuration so we can references the user options in our framework
155
+ Magento \FunctionalTestingFramework \Config \MftfApplicationConfig::create (
156
+ $ opts ['force ' ],
157
+ Magento \FunctionalTestingFramework \Config \MftfApplicationConfig::GENERATION_PHASE ,
158
+ $ opts ['verbose ' ]
159
+ );
160
+
161
+ $ testConfiguration = [];
162
+ $ testConfiguration ['tests ' ] = $ tests ;
163
+ $ testConfiguration ['suites ' ] = [];
164
+
165
+ $ testConfiguration = $ this ->parseTestsConfigJson ($ opts ['tests ' ], $ testConfiguration );
166
+
167
+ // if we have references to specific tests, we resolve the test objects and pass them to the config
168
+ if (!empty ($ testConfiguration ['tests ' ]))
169
+ {
170
+ $ testObjects = [];
171
+
172
+ foreach ($ testConfiguration ['tests ' ] as $ test )
173
+ {
174
+ $ testObjects [$ test ] = Magento \FunctionalTestingFramework \Test \Handlers \TestObjectHandler::getInstance ()->getObject ($ test );
175
+ }
176
+
177
+ $ testConfiguration ['tests ' ] = $ testObjects ;
178
+ }
179
+
180
+ return $ testConfiguration ;
181
+ }
182
+
183
+ /**
184
+ * Function which takes a json string of potential custom configuration and parses/validates the resulting json
185
+ * passed in by the user. The result is a testConfiguration array.
186
+ *
187
+ * @param string $json
188
+ * @param array $testConfiguration
189
+ * @return array
190
+ */
191
+ private function parseTestsConfigJson ($ json , $ testConfiguration ) {
192
+ if ($ json == null ) {
193
+ return $ testConfiguration ;
194
+ }
195
+
196
+ $ jsonTestConfiguration = [];
197
+ $ testConfigArray = json_decode ($ json , true );
198
+
199
+ // stop execution if we have failed to properly parse any json
200
+ if (json_last_error () != JSON_ERROR_NONE ) {
201
+ throw new \Magento \FunctionalTestingFramework \Exceptions \TestFrameworkException ("JSON could not be parsed: " . json_last_error_msg ());
202
+ }
203
+
204
+ $ jsonTestConfiguration ['tests ' ] = $ testConfigArray ['tests ' ] ?? null ;;
205
+ $ jsonTestConfiguration ['suites ' ] = $ testConfigArray ['suites ' ] ?? null ;
206
+ return $ jsonTestConfiguration ;
207
+ }
208
+
60
209
/**
61
210
* Generate a suite based on name(s) passed in as args.
62
211
*
@@ -70,7 +219,6 @@ function generateSuite(array $args)
70
219
throw new Exception ("Please provide suite name(s) after generate:suite command " );
71
220
}
72
221
73
- require 'tests ' . DIRECTORY_SEPARATOR . 'functional ' . DIRECTORY_SEPARATOR . '_bootstrap.php ' ;
74
222
$ sg = \Magento \FunctionalTestingFramework \Suite \SuiteGenerator::getInstance ();
75
223
76
224
foreach ($ args as $ arg ) {
@@ -85,18 +233,18 @@ function generateSuite(array $args)
85
233
*/
86
234
function functional ()
87
235
{
88
- $ this ->_exec (' . ' . DIRECTORY_SEPARATOR . ' vendor ' . DIRECTORY_SEPARATOR . ' bin ' . DIRECTORY_SEPARATOR . ' codecept run functional --skip-group skip ' );
236
+ $ this ->_exec (VENDOR_BIN_PATH . ' codecept run functional ' );
89
237
}
90
238
91
239
/**
92
- * Run all Tests with the specified @group tag, excluding @group 'skip '.
240
+ * Run all Tests with the specified @group tag'.
93
241
*
94
242
* @param string $args
95
243
* @return void
96
244
*/
97
245
function group ($ args = '' )
98
246
{
99
- $ this ->taskExec (' . ' . DIRECTORY_SEPARATOR . ' vendor ' . DIRECTORY_SEPARATOR . ' bin ' . DIRECTORY_SEPARATOR . ' codecept run functional --verbose --steps --skip-group skip --group ' )->args ($ args )->run ();
247
+ $ this ->taskExec (VENDOR_BIN_PATH . ' codecept run functional --verbose --steps --group ' )->args ($ args )->run ();
100
248
}
101
249
102
250
/**
@@ -107,7 +255,7 @@ function group($args = '')
107
255
*/
108
256
function folder ($ args = '' )
109
257
{
110
- $ this ->taskExec (' . ' . DIRECTORY_SEPARATOR . ' vendor ' . DIRECTORY_SEPARATOR . ' bin ' . DIRECTORY_SEPARATOR . 'codecept run functional ' )->args ($ args )->run ();
258
+ $ this ->taskExec (VENDOR_BIN_PATH . 'codecept run functional ' )->args ($ args )->run ();
111
259
}
112
260
113
261
/**
@@ -117,7 +265,7 @@ function folder($args = '')
117
265
*/
118
266
function example ()
119
267
{
120
- $ this ->_exec (' . ' . DIRECTORY_SEPARATOR . ' vendor ' . DIRECTORY_SEPARATOR . ' bin ' . DIRECTORY_SEPARATOR . ' codecept run --group example --skip-group skip ' );
268
+ $ this ->_exec (VENDOR_BIN_PATH . ' codecept run --group example ' );
121
269
}
122
270
123
271
/**
0 commit comments