Skip to content

Commit 25c5706

Browse files
committed
MQE-1257: MFTF doctor command
1 parent f1299b1 commit 25c5706

File tree

3 files changed

+139
-47
lines changed

3 files changed

+139
-47
lines changed

docs/commands/mftf.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,20 @@ You can include options to set configuration parameter values for your environme
109109
vendor/bin/mftf build:project --MAGENTO_BASE_URL=http://magento.local/ --MAGENTO_BACKEND_NAME=admin214365
110110
```
111111

112+
### `doctor`
113+
114+
#### Description
115+
116+
Diagnose MFTF configuration and setup
117+
118+
#### Usage
119+
120+
```bash
121+
vendor/bin/mftf doctor
122+
```
123+
124+
#### Options
125+
112126
### `generate:tests`
113127

114128
#### Description

src/Magento/FunctionalTestingFramework/Console/DoctorCommand.php

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
6767

6868
// Config application
6969
$verbose = $output->isVerbose();
70+
$this->input = $input;
7071
$this->output = $output;
7172
MftfApplicationConfig::create(
7273
false,
@@ -81,11 +82,31 @@ protected function execute(InputInterface $input, OutputInterface $output)
8182
$cmdStatus = $cmdStatus && !$status ? false : $cmdStatus;
8283

8384
// Check connection to Selenium
84-
$status = $this->checkConnectionToSeleniumServer();
85+
$status = $this->checkContextOnStep(
86+
MagentoWebDriverDoctor::EXCEPTION_CONTEXT_SELENIUM,
87+
'Connecting to Selenium Server'
88+
);
89+
$cmdStatus = $cmdStatus && !$status ? false : $cmdStatus;
90+
91+
// Check opening Magento Admin in web browser
92+
$status = $this->checkContextOnStep(
93+
MagentoWebDriverDoctor::EXCEPTION_CONTEXT_ADMIN,
94+
'Loading Admin page'
95+
);
96+
$cmdStatus = $cmdStatus && !$status ? false : $cmdStatus;
97+
98+
// Check opening Magento Storefront in web browser
99+
$status = $this->checkContextOnStep(
100+
MagentoWebDriverDoctor::EXCEPTION_CONTEXT_STOREFRONT,
101+
'Loading Storefront page'
102+
);
85103
$cmdStatus = $cmdStatus && !$status ? false : $cmdStatus;
86104

87105
// Check access to Magento CLI
88-
$status = $this->checkAccessToMagentoCLI();
106+
$status = $this->checkContextOnStep(
107+
MagentoWebDriverDoctor::EXCEPTION_CONTEXT_CLI,
108+
'Running Magento CLI'
109+
);
89110
$cmdStatus = $cmdStatus && !$status ? false : $cmdStatus;
90111

91112
if ($cmdStatus) {
@@ -96,15 +117,15 @@ protected function execute(InputInterface $input, OutputInterface $output)
96117
}
97118

98119
/**
99-
* Check authentication to Magento Admin
120+
* Check admin account authentication
100121
*
101122
* @return boolean
102123
*/
103124
private function checkAuthenticationToMagentoAdmin()
104125
{
105126
$result = false;
106127
try {
107-
$this->output->writeln("\nChecking authentication to Magento Admin ...");
128+
$this->output->writeln("\nAuthenticating admin account by API ...");
108129
ModuleResolver::getInstance()->getAdminToken();
109130
$this->output->writeln('Successful');
110131
$result = true;
@@ -115,38 +136,20 @@ private function checkAuthenticationToMagentoAdmin()
115136
}
116137

117138
/**
118-
* Check Connection to Selenium Server
119-
*
120-
* @return boolean
121-
*/
122-
private function checkConnectionToSeleniumServer()
123-
{
124-
// Check connection to Selenium through Codeception
125-
$this->output->writeln("\nChecking connection to Selenium Server ...");
126-
$this->runMagentoWebDriverDoctor();
127-
128-
if (isset($this->context[MagentoWebDriverDoctor::EXCEPTION_TYPE_SELENIUM])) {
129-
$this->output->write($this->context[MagentoWebDriverDoctor::EXCEPTION_TYPE_SELENIUM] . "\n");
130-
return false;
131-
} else {
132-
$this->output->writeln('Successful');
133-
return true;
134-
}
135-
}
136-
137-
/**
138-
* Check access to Magento CLI setup
139+
* Check exception context after runMagentoWebDriverDoctor
139140
*
141+
* @param string $exceptionType
142+
* @param string $message
140143
* @return boolean
144+
* @throws TestFrameworkException
141145
*/
142-
private function checkAccessToMagentoCLI()
146+
private function checkContextOnStep($exceptionType, $message)
143147
{
144-
// Check Magento CLI setup
145-
$this->output->writeln("\nChecking access to Magento CLI ...");
148+
$this->output->writeln("\n$message ...");
146149
$this->runMagentoWebDriverDoctor();
147150

148-
if (isset($this->context[MagentoWebDriverDoctor::EXCEPTION_TYPE_MAGENTO_CLI])) {
149-
$this->output->write($this->context[MagentoWebDriverDoctor::EXCEPTION_TYPE_MAGENTO_CLI] . "\n");
151+
if (isset($this->context[$exceptionType])) {
152+
$this->output->write($this->context[$exceptionType] . "\n");
150153
return false;
151154
} else {
152155
$this->output->writeln('Successful');
@@ -158,6 +161,7 @@ private function checkAccessToMagentoCLI()
158161
* Run diagnose through MagentoWebDriverDoctor
159162
*
160163
* @return void
164+
* @throws TestFrameworkException
161165
*/
162166
private function runMagentoWebDriverDoctor()
163167
{

src/Magento/FunctionalTestingFramework/Module/MagentoWebDriverDoctor.php

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,22 @@
1111

1212
/**
1313
* MagentoWebDriverDoctor module extends MagentoWebDriver module and is a light weighted module to diagnose webdriver
14-
* initialization and other setup issues. It uses in memory version of MagentoWebDriver's configuration file
14+
* initialization and other setup issues. It uses in memory version of MagentoWebDriver's configuration file.
1515
*/
1616
class MagentoWebDriverDoctor extends MagentoWebDriver
1717
{
1818
const MAGENTO_CLI_COMMAND = 'list';
19-
const EXCEPTION_TYPE_SELENIUM = 'selenium';
20-
const EXCEPTION_TYPE_MAGENTO_CLI = 'cli';
19+
const EXCEPTION_CONTEXT_SELENIUM = 'selenium';
20+
const EXCEPTION_CONTEXT_ADMIN = 'admin';
21+
const EXCEPTION_CONTEXT_STOREFRONT = 'store';
22+
const EXCEPTION_CONTEXT_CLI = 'cli';
23+
24+
/**
25+
* Remote Web Driver
26+
*
27+
* @var RemoteWebDriver
28+
*/
29+
private $remoteWebDriver = null;
2130

2231
/**
2332
* Go through parent initialization routines and in addition diagnose potential environment issues
@@ -32,56 +41,121 @@ public function _initialize()
3241
$context = [];
3342

3443
try {
35-
$this->checkSeleniumServerReadiness();
44+
$this->connectToSeleniumServer();
3645
} catch (TestFrameworkException $e) {
37-
$context[self::EXCEPTION_TYPE_SELENIUM] = $e->getMessage();
46+
$context[self::EXCEPTION_CONTEXT_SELENIUM] = $e->getMessage();
3847
}
3948

4049
try {
41-
$this->checkMagentoCLI();
42-
} catch (TestFrameworkException $e) {
43-
$context[self::EXCEPTION_TYPE_MAGENTO_CLI] = $e->getMessage();
50+
$adminUrl = rtrim(getenv('MAGENTO_BACKEND_BASE_URL'), '/')
51+
?: rtrim(getenv('MAGENTO_BASE_URL'), '/')
52+
. '/' . getenv('MAGENTO_BACKEND_NAME') . '/admin';
53+
$this->loadPageAtUrl($adminUrl);
54+
} catch (\Exception $e) {
55+
$context[self::EXCEPTION_CONTEXT_ADMIN] = $e->getMessage();
56+
}
57+
58+
try {
59+
$storeUrl = getenv('MAGENTO_BASE_URL');
60+
$this->loadPageAtUrl($storeUrl);
61+
} catch (\Exception $e) {
62+
$context[self::EXCEPTION_CONTEXT_STOREFRONT] = $e->getMessage();
63+
}
64+
65+
try {
66+
$this->runMagentoCLI();
67+
} catch (\Exception $e) {
68+
$context[self::EXCEPTION_CONTEXT_CLI] = $e->getMessage();
69+
}
70+
71+
if (null !== $this->remoteWebDriver) {
72+
$this->remoteWebDriver->close();
4473
}
4574

4675
if (!empty($context)) {
47-
throw new TestFrameworkException('MagentoWebDriverDoctor initialization failed', $context);
76+
throw new TestFrameworkException('Exception occurred in MagentoWebDriverDoctor', $context);
4877
}
4978
}
5079

5180
/**
52-
* Check connectivity to running selenium server
81+
* Check connecting to running selenium server
5382
*
5483
* @return void
5584
* @throws TestFrameworkException
5685
*/
57-
private function checkSeleniumServerReadiness()
86+
private function connectToSeleniumServer()
5887
{
5988
try {
60-
$driver = RemoteWebDriver::create(
89+
$this->remoteWebDriver = RemoteWebDriver::create(
6190
$this->wdHost,
6291
$this->capabilities,
6392
$this->connectionTimeoutInMs,
6493
$this->requestTimeoutInMs,
6594
$this->httpProxy,
6695
$this->httpProxyPort
6796
);
68-
$driver->close();
6997
} catch (\Exception $e) {
7098
throw new TestFrameworkException(
71-
"Can't connect to Webdriver at {$this->wdHost}.\n"
99+
"Failed to connect Selenium WebDriver at: {$this->wdHost}.\n"
72100
. "Please make sure that Selenium Server is running."
73101
);
74102
}
75103
}
76104

77105
/**
78-
* Check Magento CLI setup
106+
* Validate loading a web page at url in the browser controlled by selenium
107+
*
108+
* @param string $url
109+
* @return void
110+
* @throws TestFrameworkException
111+
*/
112+
private function loadPageAtUrl($url)
113+
{
114+
try {
115+
// Open the web page at url first
116+
$this->remoteWebDriver->get($url);
117+
118+
// Execute Javascript to retrieve HTTP response code
119+
$script = ''
120+
. 'var xhr = new XMLHttpRequest();'
121+
. "xhr.open('GET', '" . $url . "', false);"
122+
. 'xhr.send(null); '
123+
. 'return xhr.status';
124+
$status = $this->remoteWebDriver->executeScript($script);
125+
126+
if ($status === 200) {
127+
return;
128+
}
129+
} catch (\Exception $e) {
130+
}
131+
132+
throw new TestFrameworkException(
133+
"Failed to load page at url: $url\n"
134+
. "Please check network connection for the browser running Selenium."
135+
);
136+
}
137+
138+
/**
139+
* Check running Magento CLI command
79140
*
80141
* @return void
81142
* @throws TestFrameworkException
82143
*/
83-
private function checkMagentoCLI()
144+
private function runMagentoCLI()
84145
{
85-
parent::magentoCLI(self::MAGENTO_CLI_COMMAND);
146+
try {
147+
$regex = '~^.*(?<name>Magento CLI).*[\r\n]+(?<usage>Usage:).*~';
148+
$output = parent::magentoCLI(self::MAGENTO_CLI_COMMAND);
149+
preg_match($regex, $output, $matches);
150+
151+
if (isset($matches['name']) && isset($matches['usage'])) {
152+
return;
153+
}
154+
} catch (\Exception $e) {
155+
throw new TestFrameworkException(
156+
"Failed to run Magento CLI command\n"
157+
. "Please reference Magento DevDoc to setup command.php and .htaccess files."
158+
);
159+
}
86160
}
87161
}

0 commit comments

Comments
 (0)