|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace Group; |
| 4 | + |
| 5 | +use Facebook\WebDriver\Remote\RemoteWebDriver; |
| 6 | +use Magento\FunctionalTestingFramework\DataGenerator\Handlers\PersistedObjectHandler; |
| 7 | +use Magento\FunctionalTestingFramework\DataGenerator\Handlers\CredentialStore; |
| 8 | +use Magento\FunctionalTestingFramework\Module\MagentoWebDriver; |
| 9 | +use Magento\FunctionalTestingFramework\Module\MagentoAssert; |
| 10 | +use Magento\FunctionalTestingFramework\Module\MagentoActionProxies; |
| 11 | +use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException; |
| 12 | +use Codeception\Lib\ModuleContainer; |
| 13 | +use Codeception\Module; |
| 14 | + |
| 15 | +/** |
| 16 | + * Group class is Codeception Extension which is allowed to handle to all internal events. |
| 17 | + * This class itself can be used to listen events for test execution of one particular group. |
| 18 | + * It may be especially useful to create fixtures data, prepare server, etc. |
| 19 | + * |
| 20 | + * INSTALLATION: |
| 21 | + * |
| 22 | + * To use this group extension, include it to "extensions" option of global Codeception config. |
| 23 | + */ |
| 24 | +class ActionsInDifferentModulesSuite extends \Codeception\GroupObject |
| 25 | +{ |
| 26 | + public static $group = 'ActionsInDifferentModulesSuite'; |
| 27 | + private $testCount = 1; |
| 28 | + private $preconditionFailure = null; |
| 29 | + private $currentTestRun = 0; |
| 30 | + private static $HOOK_EXECUTION_INIT = "\n/******** Beginning execution of ActionsInDifferentModulesSuite suite %s block ********/\n"; |
| 31 | + private static $HOOK_EXECUTION_END = "\n/******** Execution of ActionsInDifferentModulesSuite suite %s block complete ********/\n"; |
| 32 | + /** @var MagentoWebDriver */ |
| 33 | + private $webDriver; |
| 34 | + /** @var ModuleContainer */ |
| 35 | + private $moduleContainer; |
| 36 | + |
| 37 | + public function _before(\Codeception\Event\TestEvent $e) |
| 38 | + { |
| 39 | + $this->webDriver = $this->getModule('\Magento\FunctionalTestingFramework\Module\MagentoWebDriver'); |
| 40 | + $this->moduleContainer = $this->webDriver->getModuleContainer(); |
| 41 | + // increment test count per execution |
| 42 | + $this->currentTestRun++; |
| 43 | + $this->executePreConditions(); |
| 44 | + |
| 45 | + if ($this->preconditionFailure != null) { |
| 46 | + //if our preconditions fail, we need to mark all the tests as incomplete. |
| 47 | + $e->getTest()->getMetadata()->setIncomplete("SUITE PRECONDITION FAILED:" . PHP_EOL . $this->preconditionFailure); |
| 48 | + } |
| 49 | + } |
| 50 | + |
| 51 | + private function executePreConditions() |
| 52 | + { |
| 53 | + if ($this->currentTestRun == 1) { |
| 54 | + print sprintf(self::$HOOK_EXECUTION_INIT, "before"); |
| 55 | + |
| 56 | + try { |
| 57 | + if ($this->webDriver->webDriver != null) { |
| 58 | + $this->webDriver->_restart(); |
| 59 | + } else { |
| 60 | + $this->webDriver->_initializeSession(); |
| 61 | + } |
| 62 | + $cli = $this->getModuleForAction("magentoCLISecret")->magentoCLISecret($this->getModuleForAction("getSecret")->getSecret("magento/some/secret"), 60); // stepKey: cli |
| 63 | + print($cli); // stepKey: cli |
| 64 | + $create1Fields['someKey'] = "dataHere"; |
| 65 | + PersistedObjectHandler::getInstance()->createEntity( |
| 66 | + "create1", |
| 67 | + "suite", |
| 68 | + "SecretData", |
| 69 | + [], |
| 70 | + $create1Fields |
| 71 | + ); |
| 72 | + PersistedObjectHandler::getInstance()->createEntity( |
| 73 | + "create2", |
| 74 | + "suite", |
| 75 | + "SecretData", |
| 76 | + [] |
| 77 | + ); |
| 78 | + PersistedObjectHandler::getInstance()->createEntity( |
| 79 | + "create3", |
| 80 | + "suite", |
| 81 | + "SecretData", |
| 82 | + ["create1", "create2"] |
| 83 | + ); |
| 84 | + $this->getModuleForAction("fillSecretField")->fillSecretField("#fill", $this->getModuleForAction("getSecret")->getSecret("magento/some/secret") . "+" . $this->getModuleForAction("getSecret")->getSecret("magento/some/secret")); // stepKey: fillBefore |
| 85 | + $this->getModuleForAction("click")->click(PersistedObjectHandler::getInstance()->retrieveEntityField('create2', 'key2', 'suite')); // stepKey: click |
| 86 | + print("Entering Action Group [return1] ActionGroupReturningValueActionGroup"); |
| 87 | + $grabProducts1Return1 = $this->getModuleForAction("grabMultiple")->grabMultiple("selector"); // stepKey: grabProducts1Return1 |
| 88 | + $this->getModuleForAction("assertCount")->assertCount(1, $grabProducts1Return1); // stepKey: assertCountReturn1 |
| 89 | + $return1 = $this->getModuleForAction("return")->return($grabProducts1Return1); // stepKey: returnProducts1Return1 |
| 90 | + print("Exiting Action Group [return1] ActionGroupReturningValueActionGroup"); |
| 91 | + } catch (\Exception $exception) { |
| 92 | + $this->preconditionFailure = $exception->getMessage(); |
| 93 | + } |
| 94 | + |
| 95 | + // reset configuration and close session |
| 96 | + $this->webDriver->_resetConfig(); |
| 97 | + $this->webDriver->webDriver->close(); |
| 98 | + $this->webDriver->webDriver = null; |
| 99 | + |
| 100 | + print sprintf(self::$HOOK_EXECUTION_END, "before"); |
| 101 | + } |
| 102 | + } |
| 103 | + |
| 104 | + public function _after(\Codeception\Event\TestEvent $e) |
| 105 | + { |
| 106 | + $this->executePostConditions($e); |
| 107 | + } |
| 108 | + |
| 109 | + private function executePostConditions(\Codeception\Event\TestEvent $e) |
| 110 | + { |
| 111 | + if ($this->currentTestRun == $this->testCount) { |
| 112 | + print sprintf(self::$HOOK_EXECUTION_INIT, "after"); |
| 113 | + |
| 114 | + try { |
| 115 | + // Find out if Test in Suite failed, will cause potential failures in suite after |
| 116 | + $cest = $e->getTest(); |
| 117 | + |
| 118 | + //Access private TestResultObject to find stack and if there are any errors (as opposed to failures) |
| 119 | + $testResultObject = call_user_func(\Closure::bind( |
| 120 | + function () use ($cest) { |
| 121 | + return $cest->getTestResultObject(); |
| 122 | + }, |
| 123 | + $cest |
| 124 | + )); |
| 125 | + $errors = $testResultObject->errors(); |
| 126 | + |
| 127 | + if (!empty($errors)) { |
| 128 | + foreach ($errors as $error) { |
| 129 | + if ($error->failedTest()->getTestMethod() == $cest->getName()) { |
| 130 | + // Do not attempt to run _after if failure was in the _after block |
| 131 | + // Try to run _after but catch exceptions to prevent them from overwriting original failure. |
| 132 | + print("LAST TEST IN SUITE FAILED, TEST AFTER MAY NOT BE SUCCESSFUL\n"); |
| 133 | + } |
| 134 | + } |
| 135 | + } |
| 136 | + if ($this->webDriver->webDriver != null) { |
| 137 | + $this->webDriver->_restart(); |
| 138 | + } else { |
| 139 | + $this->webDriver->_initializeSession(); |
| 140 | + } |
| 141 | + print("Entering Action Group [return2] ExtendedActionGroupReturningValueActionGroup"); |
| 142 | + $grabProducts1Return2 = $this->getModuleForAction("grabMultiple")->grabMultiple("selector"); // stepKey: grabProducts1Return2 |
| 143 | + $this->getModuleForAction("assertCount")->assertCount(1, $grabProducts1Return2); // stepKey: assertCountReturn2 |
| 144 | + $return2 = $this->getModuleForAction("return")->return($grabProducts1Return2); // stepKey: returnProducts1Return2 |
| 145 | + $grabProducts2Return2 = $this->getModuleForAction("grabMultiple")->grabMultiple("otherSelector"); // stepKey: grabProducts2Return2 |
| 146 | + $this->getModuleForAction("assertCount")->assertCount(2, $grabProducts2Return2); // stepKey: assertSecondCountReturn2 |
| 147 | + $return2 = $this->getModuleForAction("return")->return($grabProducts2Return2); // stepKey: returnProducts2Return2 |
| 148 | + print("Exiting Action Group [return2] ExtendedActionGroupReturningValueActionGroup"); |
| 149 | + PersistedObjectHandler::getInstance()->deleteEntity( |
| 150 | + "create1", |
| 151 | + "suite" |
| 152 | + ); |
| 153 | + PersistedObjectHandler::getInstance()->deleteEntity( |
| 154 | + "create2", |
| 155 | + "suite" |
| 156 | + ); |
| 157 | + PersistedObjectHandler::getInstance()->deleteEntity( |
| 158 | + "create3", |
| 159 | + "suite" |
| 160 | + ); |
| 161 | + $this->getModuleForAction("deleteEntityByUrl")->deleteEntityByUrl("deleteThis"); // stepKey: deleteThis |
| 162 | + $this->getModuleForAction("fillSecretField")->fillSecretField("#fill", $this->getModuleForAction("getSecret")->getSecret("magento/some/secret")); // stepKey: fillAfter |
| 163 | + $cli2 = $this->getModuleForAction("magentoCLISecret")->magentoCLISecret($this->getModuleForAction("getSecret")->getSecret("magento/some/secret") . "-some/data-" . $this->getModuleForAction("getSecret")->getSecret("magento/some/secret"), 60); // stepKey: cli2 |
| 164 | + print($cli2); // stepKey: cli2 |
| 165 | + } catch (\Exception $exception) { |
| 166 | + print $exception->getMessage(); |
| 167 | + } |
| 168 | + |
| 169 | + PersistedObjectHandler::getInstance()->clearSuiteObjects(); |
| 170 | + |
| 171 | + $this->closeSession($this->webDriver); |
| 172 | + |
| 173 | + print sprintf(self::$HOOK_EXECUTION_END, "after"); |
| 174 | + } |
| 175 | + } |
| 176 | + |
| 177 | + /** |
| 178 | + * Close session method closes current session. |
| 179 | + * If config 'close_all_sessions' is set to 'true' all sessions will be closed. |
| 180 | + * |
| 181 | + * return void |
| 182 | + */ |
| 183 | + private function closeSession(): void |
| 184 | + { |
| 185 | + $webDriverConfig = $this->webDriver->_getConfig(); |
| 186 | + $this->webDriver->_closeSession(); |
| 187 | + if (isset($webDriverConfig['close_all_sessions']) && $webDriverConfig['close_all_sessions'] === "true") { |
| 188 | + $wdHost = sprintf( |
| 189 | + '%s://%s:%s%s', |
| 190 | + $webDriverConfig['protocol'], |
| 191 | + $webDriverConfig['host'], |
| 192 | + $webDriverConfig['port'], |
| 193 | + $webDriverConfig['path'] |
| 194 | + ); |
| 195 | + $availableSessions = RemoteWebDriver::getAllSessions($wdHost); |
| 196 | + foreach ($availableSessions as $session) { |
| 197 | + $remoteWebDriver = RemoteWebDriver::createBySessionID($session['id'], $wdHost); |
| 198 | + $remoteWebDriver->quit(); |
| 199 | + } |
| 200 | + } |
| 201 | + } |
| 202 | + |
| 203 | + /** |
| 204 | + * Return the module for an action. |
| 205 | + * |
| 206 | + * @param string $action |
| 207 | + * @return Module |
| 208 | + * @throws \Exception |
| 209 | + */ |
| 210 | + private function getModuleForAction($action) |
| 211 | + { |
| 212 | + $module = $this->moduleContainer->moduleForAction($action); |
| 213 | + if ($module === null) { |
| 214 | + throw new TestFrameworkException('Invalid action "' . $action . '"' . PHP_EOL); |
| 215 | + } |
| 216 | + return $module; |
| 217 | + } |
| 218 | +} |
0 commit comments