1212use Codeception \Exception \ModuleRequireException ;
1313use Codeception \Extension ;
1414use Codeception \Module \WebDriver ;
15- use Codeception \TestInterface ;
15+ use Codeception \Step ;
1616use Facebook \WebDriver \Exception \UnexpectedAlertOpenException ;
1717use Magento \FunctionalTestingFramework \Extension \ReadinessMetrics \AbstractMetricCheck ;
1818use Facebook \WebDriver \Exception \TimeOutException ;
@@ -32,8 +32,18 @@ class PageReadinessExtension extends Extension
3232 */
3333 public static $ events = [
3434 Events::TEST_BEFORE => 'beforeTest ' ,
35- Events::STEP_BEFORE => 'beforeStep ' ,
36- Events::STEP_AFTER => 'afterStep '
35+ Events::STEP_BEFORE => 'beforeStep '
36+ ];
37+
38+ /**
39+ * List of action types that should bypass metric checks
40+ * shouldSkipCheck() also checks for the 'Comment' step type, which doesn't follow the $step->getAction() pattern
41+ *
42+ * @var array
43+ */
44+ private $ ignoredActions = [
45+ 'saveScreenshot ' ,
46+ 'wait '
3747 ];
3848
3949 /**
@@ -56,11 +66,18 @@ class PageReadinessExtension extends Extension
5666 private $ readinessMetrics ;
5767
5868 /**
59- * Active test object
69+ * The name of the active test
6070 *
61- * @var TestInterface
71+ * @var string
6272 */
63- private $ test ;
73+ private $ testName ;
74+
75+ /**
76+ * The current URI of the active page
77+ *
78+ * @var string
79+ */
80+ private $ uri ;
6481
6582 /**
6683 * Initialize local vars
@@ -93,17 +110,18 @@ public function getDriver()
93110 */
94111 public function beforeTest (TestEvent $ e )
95112 {
96- $ this ->test = $ e ->getTest ();
97-
98113 if (isset ($ this ->config ['resetFailureThreshold ' ])) {
99114 $ failThreshold = intval ($ this ->config ['resetFailureThreshold ' ]);
100115 } else {
101116 $ failThreshold = 3 ;
102117 }
103118
119+ $ this ->testName = $ e ->getTest ()->getMetadata ()->getName ();
120+ $ this ->uri = null ;
121+
104122 $ metrics = [];
105123 foreach ($ this ->config ['readinessMetrics ' ] as $ metricClass ) {
106- $ metrics [] = new $ metricClass ($ this , $ this -> test , $ failThreshold );
124+ $ metrics [] = new $ metricClass ($ this , $ failThreshold );
107125 }
108126
109127 $ this ->readinessMetrics = $ metrics ;
@@ -119,16 +137,13 @@ public function beforeTest(TestEvent $e)
119137 public function beforeStep (StepEvent $ e )
120138 {
121139 $ step = $ e ->getStep ();
122- if ($ step -> getAction () == ' saveScreenshot ' ) {
140+ if ($ this -> shouldSkipCheck ( $ step ) ) {
123141 return ;
124142 }
125143
126- try {
127- $ this ->test ->getMetadata ()->setCurrent (['uri ' , $ this ->getDriver ()->_getCurrentUri ()]);
128- } catch (\Exception $ exception ) {
129- $ this ->logDebug ('Could not retrieve current URI ' , ['action ' => $ e ->getStep ()->getAction ()]);
130- }
144+ $ this ->checkForNewPage ($ step );
131145
146+ // todo: Implement step parameter to override global timeout configuration
132147 if (isset ($ this ->config ['timeout ' ])) {
133148 $ timeout = intval ($ this ->config ['timeout ' ]);
134149 } else {
@@ -159,46 +174,75 @@ function () use ($metrics) {
159174
160175 /** @var AbstractMetricCheck $metric */
161176 foreach ($ metrics as $ metric ) {
162- $ metric ->finalize ($ step );
177+ $ metric ->finalizeForStep ($ step );
163178 }
164179 }
165180
166181 /**
167- * Checks to see if the step changed the uri and resets failure tracking if so
182+ * Check if the URI has changed and reset metric tracking if so
168183 *
169- * @param StepEvent $e
184+ * @param Step $step
170185 * @return void
171186 */
172- public function afterStep ( StepEvent $ e )
187+ private function checkForNewPage ( $ step )
173188 {
174- $ step = $ e ->getStep ();
175- if ($ step ->getAction () == 'saveScreenshot ' ) {
176- return ;
177- }
178-
179189 try {
180190 $ currentUri = $ this ->getDriver ()->_getCurrentUri ();
191+
192+ if ($ this ->uri !== $ currentUri ) {
193+ $ this ->logDebug (
194+ 'Page URI changed; resetting readiness metric failure tracking ' ,
195+ [
196+ 'step ' => $ step ->__toString (),
197+ 'newUri ' => $ currentUri
198+ ]
199+ );
200+
201+ /** @var AbstractMetricCheck $metric */
202+ foreach ($ this ->readinessMetrics as $ metric ) {
203+ $ metric ->resetTracker ();
204+ }
205+
206+ $ this ->uri = $ currentUri ;
207+ }
181208 } catch (\Exception $ e ) {
182- // $this->debugLog('Could not retrieve current URI', ['action' => $step()->getAction()]);
183- return ;
209+ $ this ->logDebug ('Could not retrieve current URI ' , ['step ' => $ step ->__toString ()]);
184210 }
211+ }
185212
186- $ previousUri = $ this ->test ->getMetadata ()->getCurrent ('uri ' );
213+ /**
214+ * Gets the active page URI from the start of the most recent step
215+ *
216+ * @return string
217+ */
218+ public function getUri ()
219+ {
220+ return $ this ->uri ;
221+ }
187222
188- if ($ previousUri !== $ currentUri ) {
189- $ this ->logDebug (
190- 'Page URI changed; resetting readiness metric failure tracking ' ,
191- [
192- 'action ' => $ step ->getAction (),
193- 'newUri ' => $ currentUri
194- ]
195- );
223+ /**
224+ * Gets the name of the active test
225+ *
226+ * @return string
227+ */
228+ public function getTestName ()
229+ {
230+ return $ this ->testName ;
231+ }
196232
197- /** @var AbstractMetricCheck $metric */
198- foreach ($ this ->readinessMetrics as $ metric ) {
199- $ metric ->setTracker ();
200- }
233+ /**
234+ * Should the given step bypass the readiness checks
235+ * todo: Implement step parameter to bypass specific metrics (or all) instead of basing on action type
236+ *
237+ * @param Step $step
238+ * @return boolean
239+ */
240+ private function shouldSkipCheck ($ step )
241+ {
242+ if ($ step instanceof Step \Comment || in_array ($ step ->getAction (), $ this ->ignoredActions )) {
243+ return true ;
201244 }
245+ return false ;
202246 }
203247
204248 /**
@@ -211,10 +255,9 @@ public function afterStep(StepEvent $e)
211255 private function logDebug ($ message , $ context = [])
212256 {
213257 if ($ this ->verbose ) {
214- $ testMeta = $ this ->test ->getMetadata ();
215258 $ logContext = [
216- 'test ' => $ testMeta -> getName () ,
217- 'uri ' => $ testMeta -> getCurrent ( ' uri ' )
259+ 'test ' => $ this -> testName ,
260+ 'uri ' => $ this -> uri
218261 ];
219262 foreach ($ this ->readinessMetrics as $ metric ) {
220263 $ logContext [$ metric ->getName ()] = $ metric ->getStoredValue ();
0 commit comments