webDriver = $this->getModule('\Magento\FunctionalTestingFramework\Module\MagentoWebDriver'); $this->moduleContainer = $this->webDriver->getModuleContainer(); // increment test count per execution $this->currentTestRun++; $this->executePreConditions(); if ($this->preconditionFailure != null) { //if our preconditions fail, we need to mark all the tests as incomplete. $e->getTest()->getMetadata()->setIncomplete("SUITE PRECONDITION FAILED:" . PHP_EOL . $this->preconditionFailure); } } private function executePreConditions() { if ($this->currentTestRun == 1) { $this->testCount = $this->getTestCount(); print sprintf(self::$HOOK_EXECUTION_INIT, "before"); try { if ($this->webDriver->webDriver != null) { $this->webDriver->_restart(); } else { $this->webDriver->_initializeSession(); } print("Comment in Before"); $this->getModuleForAction("amOnPage")->amOnPage("some.url"); // stepKey: before $createFields['someKey'] = "dataHere"; PersistedObjectHandler::getInstance()->createEntity( "create", "suite", "createThis", [], $createFields ); print(""); $this->getModuleForAction("click")->click(PersistedObjectHandler::getInstance()->retrieveEntityField('create', 'data', 'suite')); // stepKey: clickWithData print("Entering Action Group [AC] actionGroupWithTwoArguments"); $this->getModuleForAction("see")->see("John", msq("uniqueData") . "John"); // stepKey: seeFirstNameAC print("Exiting Action Group [AC] actionGroupWithTwoArguments"); } catch (\Exception $exception) { $this->preconditionFailure = $exception->getMessage(); } // reset configuration and close session $this->webDriver->_resetConfig(); $this->webDriver->webDriver->close(); $this->webDriver->webDriver = null; print sprintf(self::$HOOK_EXECUTION_END, "before"); } } public function _after(\Codeception\Event\TestEvent $e) { $this->executePostConditions($e); } private function executePostConditions(\Codeception\Event\TestEvent $e) { if ($this->currentTestRun == $this->testCount) { print sprintf(self::$HOOK_EXECUTION_INIT, "after"); try { // Find out if Test in Suite failed, will cause potential failures in suite after $cest = $e->getTest(); //Access private TestResultObject to find stack and if there are any errors (as opposed to failures) $testResultObject = call_user_func(\Closure::bind( function () use ($cest) { return $cest->getResultAggregator(); }, $cest )); $errors = $testResultObject->errors(); if (!empty($errors)) { foreach ($errors as $error) { if ($error->getTest()->getTestMethod() == $cest->getName()) { // Do not attempt to run _after if failure was in the _after block // Try to run _after but catch exceptions to prevent them from overwriting original failure. print("LAST TEST IN SUITE FAILED, TEST AFTER MAY NOT BE SUCCESSFUL\n"); } } } if ($this->webDriver->webDriver != null) { $this->webDriver->_restart(); } else { $this->webDriver->_initializeSession(); } print("afterBlock"); } catch (\Exception $exception) { print $exception->getMessage(); } PersistedObjectHandler::getInstance()->clearSuiteObjects(); $this->closeSession($this->webDriver); print sprintf(self::$HOOK_EXECUTION_END, "after"); } } /** * Close session method closes current session. * If config 'close_all_sessions' is set to 'true' all sessions will be closed. * * return void */ private function closeSession(): void { $webDriverConfig = $this->webDriver->_getConfig(); $this->webDriver->_closeSession(); if (isset($webDriverConfig['close_all_sessions']) && $webDriverConfig['close_all_sessions'] === "true") { $wdHost = sprintf( '%s://%s:%s%s', $webDriverConfig['protocol'], $webDriverConfig['host'], $webDriverConfig['port'], $webDriverConfig['path'] ); $availableSessions = RemoteWebDriver::getAllSessions($wdHost); foreach ($availableSessions as $session) { try { $remoteWebDriver = RemoteWebDriver::createBySessionID($session['id'], $wdHost); $remoteWebDriver->quit(); } catch (\Exception $exception) { print("Failed trying to quit WebDriver session. Exception message: " . $exception->getMessage() . " Test execution will continue." . PHP_EOL); // Session already closed so nothing to do } } } } /** * Return the module for an action. * * @param string $action * @return Module * @throws \Exception */ private function getModuleForAction($action) { $module = $this->moduleContainer->moduleForAction($action); if ($module === null) { throw new TestFrameworkException('Invalid action "' . $action . '"' . PHP_EOL); } return $module; } /** * Counts how many tests in group. * * @return integer */ private function getTestCount() { $config = $this->getGlobalConfig(); if (empty($config['groups']) || empty($config['groups'][self::$group])) { return $this->testCount; } $pathToGroupDir = TESTS_BP . DIRECTORY_SEPARATOR . array_first($config['groups'][self::$group]); $pathToGroupCests = $pathToGroupDir . "*Cest.php"; $files = glob($pathToGroupCests); if (is_array($files)) { $qty = count($files); print('In a group "' . self::$group . '" suite executor found ' . $qty . ' tests.' . PHP_EOL); return $qty; } return $this->testCount; } }