1
+ <?php
2
+ /**
3
+ * Copyright © Magento, Inc. All rights reserved.
4
+ * See COPYING.txt for license details.
5
+ */
6
+ namespace Magento \FunctionalTestingFramework \Suite \Handlers ;
7
+
8
+ use Exception ;
9
+ use Magento \FunctionalTestingFramework \ObjectManager \ObjectHandlerInterface ;
10
+ use Magento \FunctionalTestingFramework \ObjectManagerFactory ;
11
+ use Magento \FunctionalTestingFramework \Suite \Objects \SuiteObject ;
12
+ use Magento \FunctionalTestingFramework \Suite \Parsers \SuiteDataParser ;
13
+ use Magento \FunctionalTestingFramework \Test \Handlers \CestObjectHandler ;
14
+ use Magento \FunctionalTestingFramework \Test \Objects \CestObject ;
15
+ use Magento \Ui \Test \Unit \Component \PagingTest ;
16
+
17
+ /**
18
+ * Class SuiteObjectHandler
19
+ */
20
+ class SuiteObjectHandler implements ObjectHandlerInterface
21
+ {
22
+ const SUITE_TAG_NAME = 'suite ' ;
23
+ const INCLUDE_TAG_NAME = 'include ' ;
24
+ const EXCLUDE_TAG_NAME = 'exclude ' ;
25
+ const MODULE_TAG_NAME = 'module ' ;
26
+ const MODULE_TAG_FILE_ATTRIBUTE = 'file ' ;
27
+ const CEST_TAG_NAME = 'cest ' ;
28
+ const CEST_TAG_NAME_ATTRIBUTE = 'name ' ;
29
+ const CEST_TAG_TEST_ATTRIBUTE = 'test ' ;
30
+ const GROUP_TAG_NAME = 'group ' ;
31
+
32
+ /**
33
+ * Singleton instance of suite object handler.
34
+ *
35
+ * @var SuiteObjectHandler
36
+ */
37
+ private static $ SUITE_OBJECT_HANLDER_INSTANCE ;
38
+
39
+ /**
40
+ * Array of suite objects keyed by suite name.
41
+ *
42
+ * @var array
43
+ */
44
+ private $ suiteObjects ;
45
+
46
+ private function __construct ()
47
+ {
48
+ // empty constructor
49
+ }
50
+
51
+ /**
52
+ * Function to enforce singleton design pattern
53
+ *
54
+ * @return ObjectHandlerInterface
55
+ */
56
+ public static function getInstance ()
57
+ {
58
+ if (self ::$ SUITE_OBJECT_HANLDER_INSTANCE == null ) {
59
+ self ::$ SUITE_OBJECT_HANLDER_INSTANCE = new SuiteObjectHandler ();
60
+ self ::$ SUITE_OBJECT_HANLDER_INSTANCE ->initSuiteData ();
61
+ }
62
+
63
+ return self ::$ SUITE_OBJECT_HANLDER_INSTANCE ;
64
+ }
65
+
66
+ /**
67
+ * Function to return a single suite object by name
68
+ *
69
+ * @param string $objectName
70
+ * @return SuiteObject
71
+ */
72
+ public function getObject ($ objectName )
73
+ {
74
+ if (!array_key_exists ($ objectName , $ this ->suiteObjects )) {
75
+ trigger_error ("Suite $ {objectName} is not defined. " , E_USER_ERROR );
76
+ }
77
+ return $ this ->suiteObjects [$ objectName ];
78
+ }
79
+
80
+ /**
81
+ * Function to return all objects the handler is responsible for
82
+ *
83
+ * @return array
84
+ */
85
+ public function getAllObjects ()
86
+ {
87
+ return $ this ->suiteObjects ;
88
+ }
89
+
90
+ private function initSuiteData ()
91
+ {
92
+ $ suiteDataParser = ObjectManagerFactory::getObjectManager ()->create (SuiteDataParser::class);
93
+ $ this ->suiteObjects = $ this ->parseSuiteDataIntoObjects ($ suiteDataParser ->readSuiteData ());
94
+ }
95
+
96
+ private function parseSuiteDataIntoObjects ($ parsedSuiteData )
97
+ {
98
+ $ suiteObjects = [];
99
+ foreach ($ parsedSuiteData [self ::SUITE_TAG_NAME ] as $ parsedSuiteName => $ parsedSuite ) {
100
+ $ includeCests = [];
101
+ $ excludeCests = [];
102
+
103
+ $ groupCestsToInclude = $ parsedSuite [self ::INCLUDE_TAG_NAME ][0 ] ?? [];
104
+ $ groupCestsToExclude = $ parsedSuite [self ::EXCLUDE_TAG_NAME ][0 ] ?? [];
105
+
106
+ if (array_key_exists (self ::CEST_TAG_NAME , $ groupCestsToInclude )) {
107
+ $ includeCests = $ includeCests + $ this ->extractRelevantTests ($ groupCestsToInclude [self ::CEST_TAG_NAME ]);
108
+ }
109
+
110
+ if (array_key_exists (self ::CEST_TAG_NAME , $ groupCestsToExclude )) {
111
+ $ excludeCests = $ excludeCests + $ this ->extractRelevantTests ($ groupCestsToExclude [self ::CEST_TAG_NAME ]);
112
+ }
113
+
114
+ $ includeCests = $ includeCests + $ this ->extractGroups ($ groupCestsToInclude );
115
+ $ excludeCests = $ excludeCests + $ this ->extractGroups ($ groupCestsToExclude );
116
+
117
+
118
+ // get tests by path (dir or file)
119
+ if (array_key_exists (self ::MODULE_TAG_NAME , $ groupCestsToInclude )) {
120
+ $ includeCests = array_merge (
121
+ $ includeCests ,
122
+ $ this ->extractModuleAndFiles ($ groupCestsToInclude [self ::MODULE_TAG_NAME ])
123
+ );
124
+ }
125
+
126
+ if (array_key_exists (self ::MODULE_TAG_NAME , $ groupCestsToExclude )) {
127
+ $ excludeCests = array_merge (
128
+ $ excludeCests ,
129
+ $ this ->extractModuleAndFiles ($ groupCestsToExclude [self ::MODULE_TAG_NAME ])
130
+ );
131
+ }
132
+
133
+ // add all cests if include cests is completely empty
134
+ if (empty ($ includeCests )) {
135
+ $ includeCests = CestObjectHandler::getInstance ()->getAllObjects ();
136
+ }
137
+
138
+ $ suiteObjects [$ parsedSuiteName ] = new SuiteObject ($ parsedSuiteName , $ includeCests , $ excludeCests );
139
+ }
140
+
141
+ return $ suiteObjects ;
142
+ }
143
+
144
+ private function extractRelevantTests ($ suiteTestData )
145
+ {
146
+ $ relevantCests = [];
147
+ foreach ($ suiteTestData as $ cestName => $ cestInfo ) {
148
+ $ relevantCest = CestObjectHandler::getInstance ()->getObject ($ cestName );
149
+
150
+ if (array_key_exists (self ::CEST_TAG_TEST_ATTRIBUTE , $ cestInfo )) {
151
+ $ relevantTest = $ relevantCest ->getTests ()[$ cestInfo [self ::CEST_TAG_TEST_ATTRIBUTE ]] ?? null ;
152
+
153
+ if (!$ relevantTest ) {
154
+ trigger_error (
155
+ "Test " .
156
+ $ cestInfo [self ::CEST_TAG_NAME_ATTRIBUTE ] .
157
+ " does not exist. " ,
158
+ E_USER_NOTICE
159
+ );
160
+ continue ;
161
+ }
162
+
163
+ $ relevantCests [$ cestName ] = new CestObject (
164
+ $ relevantCest ->getName (),
165
+ $ relevantCest ->getAnnotations (),
166
+ [$ relevantTest ->getName () => $ relevantTest ],
167
+ $ relevantCest ->getHooks ()
168
+ );
169
+ } else {
170
+ $ relevantCests [$ cestName ] = $ relevantCest ;
171
+ }
172
+ }
173
+
174
+ return $ relevantCests ;
175
+ }
176
+
177
+ private function extractGroups ($ suiteData )
178
+ {
179
+ $ cestsByGroup = [];
180
+ // get tests by group
181
+ if (array_key_exists (self ::GROUP_TAG_NAME , $ suiteData )) {
182
+ //loop groups and add to the groupCests
183
+ foreach ($ suiteData [self ::GROUP_TAG_NAME ] as $ groupName => $ groupVal ) {
184
+ $ cestsByGroup = $ cestsByGroup + CestObjectHandler::getInstance ()->getCestsByGroup ($ groupName );
185
+ }
186
+ }
187
+
188
+ return $ cestsByGroup ;
189
+ }
190
+
191
+ private function extractModuleAndFiles ($ suitePathData )
192
+ {
193
+ $ cestsByModule = [];
194
+ foreach ($ suitePathData as $ moduleName => $ fileInfo ) {
195
+ if (empty ($ fileInfo )) {
196
+ $ cestsByModule = array_merge ($ cestsByModule , $ this ->resolveModulePathCestNames ($ moduleName ));
197
+ } else {
198
+ $ cestObj = $ this ->resolveFilePathCestName ($ fileInfo [self ::MODULE_TAG_FILE_ATTRIBUTE ], $ moduleName );
199
+ $ cestsByModule [$ cestObj ->getName ()] = $ cestObj ;
200
+ }
201
+ }
202
+
203
+ return $ cestsByModule ;
204
+ }
205
+
206
+ private function resolveFilePathCestName ($ filename , $ moduleName = null )
207
+ {
208
+ $ filepath = $ filename ;
209
+ if (!strstr ($ filepath , DIRECTORY_SEPARATOR )) {
210
+ $ filepath = TESTS_MODULE_PATH .
211
+ DIRECTORY_SEPARATOR .
212
+ $ moduleName .
213
+ DIRECTORY_SEPARATOR .
214
+ 'Cest ' .
215
+ DIRECTORY_SEPARATOR .
216
+ $ filename ;
217
+ }
218
+
219
+ if (!file_exists ($ filepath )) {
220
+ throw new Exception ("Could not find file $ {filename}" );
221
+ }
222
+ $ xml = simplexml_load_file ($ filepath );
223
+ $ cestName = (string )$ xml ->cest ->attributes ()->name ;
224
+
225
+ return CestObjectHandler::getInstance ()->getObject ($ cestName );
226
+ }
227
+
228
+ private function resolveModulePathCestNames ($ moduleName )
229
+ {
230
+ $ cestObjects = [];
231
+ $ xmlFiles = glob (
232
+ TESTS_MODULE_PATH .
233
+ DIRECTORY_SEPARATOR .
234
+ $ moduleName .
235
+ DIRECTORY_SEPARATOR .
236
+ 'Cest ' .
237
+ DIRECTORY_SEPARATOR .
238
+ '*.xml '
239
+ );
240
+
241
+ foreach ($ xmlFiles as $ xmlFile ) {
242
+ $ cestObj = $ this ->resolveFilePathCestName ($ xmlFile );
243
+ $ cestObjects [$ cestObj ->getName ()] = $ cestObj ;
244
+ }
245
+
246
+ return $ cestObjects ;
247
+ }
248
+ }
0 commit comments