Skip to content

Commit 9fe3f3d

Browse files
MAGETWO-46837: Extracting metric tracking from test object and adding wait and comment to ignored action types
1 parent 8d7cfe8 commit 9fe3f3d

File tree

5 files changed

+123
-77
lines changed

5 files changed

+123
-77
lines changed

src/Magento/FunctionalTestingFramework/Extension/PageReadinessExtension.php

Lines changed: 85 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use Codeception\Exception\ModuleRequireException;
1313
use Codeception\Extension;
1414
use Codeception\Module\WebDriver;
15-
use Codeception\TestInterface;
15+
use Codeception\Step;
1616
use Facebook\WebDriver\Exception\UnexpectedAlertOpenException;
1717
use Magento\FunctionalTestingFramework\Extension\ReadinessMetrics\AbstractMetricCheck;
1818
use 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 static $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(), PageReadinessExtension::$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();

src/Magento/FunctionalTestingFramework/Extension/ReadinessMetrics/AbstractMetricCheck.php

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use Codeception\Exception\ModuleRequireException;
1010
use Codeception\Module\WebDriver;
1111
use Codeception\Step;
12-
use Codeception\TestInterface;
1312
use Facebook\WebDriver\Exception\UnexpectedAlertOpenException;
1413
use Magento\FunctionalTestingFramework\Extension\PageReadinessExtension;
1514
use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil;
@@ -29,18 +28,26 @@ abstract class AbstractMetricCheck
2928
protected $extension;
3029

3130
/**
32-
* The active test object
31+
* Current state of the value the metric tracks
3332
*
34-
* @var TestInterface
33+
* @var mixed;
3534
*/
36-
protected $test;
35+
protected $currentValue;
3736

3837
/**
39-
* Current state of the value the metric tracks
38+
* Most recent saved state of the value the metric tracks
39+
* Updated when the metric passes or is finalized
4040
*
4141
* @var mixed;
4242
*/
43-
protected $currentValue;
43+
protected $storedValue;
44+
45+
/**
46+
* Current count of sequential identical failures
47+
*
48+
* @var integer;
49+
*/
50+
protected $failCount;
4451

4552
/**
4653
* Number of sequential identical failures before force-resetting the metric
@@ -63,14 +70,12 @@ abstract class AbstractMetricCheck
6370
* Constructor, called from the beforeTest event
6471
*
6572
* @param PageReadinessExtension $extension
66-
* @param TestInterface $test
6773
* @param integer $resetFailureThreshold
6874
* @throws \Exception
6975
*/
70-
public function __construct($extension, $test, $resetFailureThreshold)
76+
public function __construct($extension, $resetFailureThreshold)
7177
{
7278
$this->extension = $extension;
73-
$this->test = $test;
7479
$this->logger = LoggingUtil::getInstance()->getLogger(get_class($this));
7580
$this->verbose = MftfApplicationConfig::getConfig()->verboseEnabled();
7681

@@ -83,7 +88,7 @@ public function __construct($extension, $test, $resetFailureThreshold)
8388
$this->resetFailureThreshold = -1;
8489
}
8590

86-
$this->setTracker();
91+
$this->resetTracker();
8792
}
8893

8994
/**
@@ -141,7 +146,7 @@ public function getName()
141146
public function runCheck()
142147
{
143148
if ($this->doesMetricPass($this->getCurrentValue(true))) {
144-
$this->setTracker($this->getCurrentValue());
149+
$this->setTracker($this->getCurrentValue(), 0);
145150
return true;
146151
}
147152

@@ -157,35 +162,35 @@ public function runCheck()
157162
* @param Step $step
158163
* @return void
159164
*/
160-
public function finalize($step)
165+
public function finalizeForStep($step)
161166
{
162167
try {
163168
$currentValue = $this->getCurrentValue();
164169
} catch (UnexpectedAlertOpenException $exception) {
165170
$this->debugLog(
166171
'An alert is open, bypassing javascript-based metric check',
167-
['action' => $step->getAction()]
172+
['step' => $step->__toString()]
168173
);
169174
return;
170175
}
171176

172177
if ($this->doesMetricPass($currentValue)) {
173-
$this->setTracker($currentValue);
178+
$this->setTracker($currentValue, 0);
174179
} else {
175180
// If failure happened on the same value as before, increment the fail count, otherwise set at 1
176-
if ($currentValue !== $this->getStoredValue()) {
181+
if (!isset($this->storedValue) || $currentValue !== $this->getStoredValue()) {
177182
$failCount = 1;
178183
} else {
179184
$failCount = $this->getFailureCount() + 1;
180185
}
181186
$this->setTracker($currentValue, $failCount);
182187

183-
$this->errorLog('Failed readiness check', ['action' => $step->getAction()]);
188+
$this->errorLog('Failed readiness check', ['step' => $step->__toString()]);
184189

185190
if ($this->resetFailureThreshold >= 0 && $failCount >= $this->resetFailureThreshold) {
186191
$this->debugLog(
187192
'Too many failures, assuming metric is stuck and resetting state',
188-
['action' => $step->getAction()]
193+
['step' => $step->__toString()]
189194
);
190195
$this->resetMetric();
191196
}
@@ -214,7 +219,7 @@ protected function getDriver()
214219
*/
215220
protected function executeJs($script, $arguments = [])
216221
{
217-
return $this->getDriver()->executeJS($script, $arguments);
222+
return $this->extension->getDriver()->executeJS($script, $arguments);
218223
}
219224

220225
/**
@@ -243,7 +248,7 @@ private function getCurrentValue($refresh = false)
243248
*/
244249
public function getStoredValue()
245250
{
246-
return $this->test->getMetadata()->getCurrent($this->getName());
251+
return $this->storedValue;
247252
}
248253

249254
/**
@@ -254,7 +259,7 @@ public function getStoredValue()
254259
*/
255260
public function getFailureCount()
256261
{
257-
return $this->test->getMetadata()->getCurrent($this->getName() . '.failCount');
262+
return $this->failCount;
258263
}
259264

260265
/**
@@ -266,7 +271,7 @@ public function getFailureCount()
266271
private function resetMetric()
267272
{
268273
$this->clearFailureOnPage();
269-
$this->setTracker();
274+
$this->resetTracker();
270275
}
271276

272277
/**
@@ -276,13 +281,18 @@ private function resetMetric()
276281
* @param integer $failCount
277282
* @return void
278283
*/
279-
public function setTracker($value = null, $failCount = 0)
284+
public function setTracker($value, $failCount)
285+
{
286+
unset($this->currentValue);
287+
$this->storedValue = $value;
288+
$this->failCount = $failCount;
289+
}
290+
291+
public function resetTracker()
280292
{
281-
$this->test->getMetadata()->setCurrent([
282-
$this->getName() => $value,
283-
$this->getName() . '.failCount' => $failCount
284-
]);
285293
unset($this->currentValue);
294+
unset($this->storedValue);
295+
$this->failCount = 0;
286296
}
287297

288298
/**
@@ -334,10 +344,9 @@ protected function debugLog($message, $context = [])
334344
*/
335345
private function getLogContext()
336346
{
337-
$testMeta = $this->test->getMetadata();
338347
return [
339-
'test' => $testMeta->getName(),
340-
'uri' => $testMeta->getCurrent('uri'),
348+
'test' => $this->extension->getTestName(),
349+
'uri' => $this->extension->getUri(),
341350
$this->getName() => $this->getStoredValue(),
342351
$this->getName() . '.failCount' => $this->getFailureCount()
343352
];

0 commit comments

Comments
 (0)