Skip to content

Commit 6c34dab

Browse files
authored
Merge branch 'develop' into MQE-1302
2 parents 58810eb + 85b44c3 commit 6c34dab

22 files changed

+214
-75
lines changed

dev/tests/static/Magento/Sniffs/Commenting/FunctionCommentSniff.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ protected function processReturn(File $phpcsFile, $stackPtr, $commentStart)
6868
$phpcsFile->addError($error, $return, 'MissingReturnType');
6969
} else {
7070
// Support both a return type and a description.
71-
$split = preg_match('`^((?:\|?(?:array\([^\)]*\)|[\\\\a-z0-9\[\]]+))*)( .*)?`i', $content, $returnParts);
71+
preg_match('`^((?:\|?(?:array\([^\)]*\)|[\\\\a-z0-9\[\]]+))*)( .*)?`i', $content, $returnParts);
7272
if (isset($returnParts[1]) === false) {
7373
return;
7474
}
@@ -78,7 +78,7 @@ protected function processReturn(File $phpcsFile, $stackPtr, $commentStart)
7878
// Check return type (can be multiple, separated by '|').
7979
$typeNames = explode('|', $returnType);
8080
$suggestedNames = array();
81-
foreach ($typeNames as $i => $typeName) {
81+
foreach ($typeNames as $typeName) {
8282
$suggestedName = Common::suggestType($typeName);
8383
if (in_array($suggestedName, $suggestedNames) === false) {
8484
$suggestedNames[] = $suggestedName;

dev/tests/verification/Resources/ActionGroupWithSectionAndDataAsArguments.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ class ActionGroupWithSectionAndDataAsArgumentsCest
2727
*/
2828
public function ActionGroupWithSectionAndDataAsArguments(AcceptanceTester $I)
2929
{
30-
$I->waitForElementVisible("#element .John");
30+
$I->waitForElementVisible("#element .John", 10);
3131
}
3232
}

dev/tests/verification/Resources/BasicFunctionalTest.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class BasicFunctionalTestCest
126126
$I->moveMouseOver(".functionalTestSelector");
127127
$I->openNewTab();
128128
$I->pauseExecution();
129-
$I->performOn("#selector", function(\WebDriverElement $el) {return $el->isDisplayed();});
129+
$I->performOn("#selector", function(\WebDriverElement $el) {return $el->isDisplayed();}, 10);
130130
$I->pressKey("#page", "a");
131131
$I->pressKey("#page", ['ctrl', 'a'],'new');
132132
$I->pressKey("#page", ['shift', '111'],'1','x');
@@ -165,7 +165,7 @@ class BasicFunctionalTestCest
165165
$I->waitForElement(".functionalTestSelector", 30);
166166
$I->waitForElementNotVisible(".functionalTestSelector", 30);
167167
$I->waitForElementVisible(".functionalTestSelector", 30);
168-
$I->waitForElementChange("#selector", function(\WebDriverElement $el) {return $el->isDisplayed();});
168+
$I->waitForElementChange("#selector", function(\WebDriverElement $el) {return $el->isDisplayed();}, 10);
169169
$I->waitForJS("someJsFunction", 30);
170170
$I->waitForText("someInput", 30, ".functionalTestSelector");
171171
}

dev/tests/verification/Resources/SectionReplacementTest.txt

+2
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,7 @@ class SectionReplacementTestCest
6868
$I->click("#stringLiteral1-" . PersistedObjectHandler::getInstance()->retrieveEntityField('createdData', 'firstname', 'test') . " .Doe" . msq("uniqueData"));
6969
$I->click("#element .1#element .2");
7070
$I->click("#element .1#element .{$data}");
71+
$I->click("(//div[@data-role='slide'])[1]/a[@data-element='link'][contains(@href,'')]");
72+
$I->click("(//div[@data-role='slide'])[1]/a[@data-element='link'][contains(@href,' ')]");
7173
}
7274
}

dev/tests/verification/Resources/functionalSuiteHooks.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class functionalSuiteHooks extends \Codeception\GroupObject
3030

3131
if ($this->preconditionFailure != null) {
3232
//if our preconditions fail, we need to mark all the tests as incomplete.
33-
$e->getTest()->getMetadata()->setIncomplete($this->preconditionFailure);
33+
$e->getTest()->getMetadata()->setIncomplete("SUITE PRECONDITION FAILED:" . PHP_EOL . $this->preconditionFailure);
3434
}
3535
}
3636

dev/tests/verification/TestModule/Section/SampleSection.xml

+1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@
1818
<element name="threeOneDuplicateParamElement" type="button" selector="#{{var1}}-{{var2}} .{{var1}} [{{var3}}]" parameterized="true"/>
1919
<element name="timeoutElement" type="button" selector="#foo" timeout="30"/>
2020
<element name="mergeElement" type="button" selector="#unMerge"/>
21+
<element name="anotherTwoParamsElement" type="button" selector="(//div[@data-role='slide'])[{{arg1}}]/a[@data-element='link'][contains(@href,'{{arg2}}')]" parameterized="true"/>
2122
</section>
2223
</sections>

dev/tests/verification/TestModule/Test/SectionReplacementTest.xml

+3
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,8 @@
5050

5151
<click stepKey="selectorReplaceTwoParamElements" selector="{{SampleSection.oneParamElement('1')}}{{SampleSection.oneParamElement('2')}}"/>
5252
<click stepKey="selectorReplaceTwoParamMixedTypes" selector="{{SampleSection.oneParamElement('1')}}{{SampleSection.oneParamElement({$data})}}"/>
53+
54+
<click stepKey="selectorParamWithEmptyString" selector="{{SampleSection.anotherTwoParamsElement('1', '')}}"/>
55+
<click stepKey="selectorParamWithASpace" selector="{{SampleSection.anotherTwoParamsElement('1', ' ')}}"/>
5356
</test>
5457
</tests>

etc/config/.env.example

+9-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#*** Set the base URL for your Magento instance ***#
55
MAGENTO_BASE_URL=http://devdocs.magento.com/
66

7+
#*** Uncomment if you are running Admin Panel on separate domain (used with MAGENTO_BACKEND_NAME) ***#
8+
# MAGENTO_BACKEND_BASE_HOST=http://admin.example.com/
9+
710
#*** Set the Admin Username and Password for your Magento instance ***#
811
MAGENTO_BACKEND_NAME=admin
912
MAGENTO_ADMIN_USERNAME=admin
@@ -23,8 +26,9 @@ MAGENTO_ADMIN_PASSWORD=123123q
2326
BROWSER=chrome
2427

2528
#*** Uncomment and set host & port if your dev environment needs different value other than MAGENTO_BASE_URL for Rest API Requests ***#
26-
#MAGENTO_RESTAPI_SERVER_HOST=
27-
#MAGENTO_RESTAPI_SERVER_PORT=
29+
#MAGENTO_RESTAPI_SERVER_HOST=restapi.magento.com
30+
#MAGENTO_RESTAPI_SERVER_PORT=8080
31+
#MAGENTO_RESTAPI_SERVER_PROTOCOL=https
2832

2933
#*** Uncomment these properties to set up a dev environment with symlinked projects ***#
3034
#TESTS_BP=
@@ -40,4 +44,7 @@ MODULE_WHITELIST=Magento_Framework,Magento_ConfigurableProductWishlist,Magento_C
4044

4145
#*** Bool property which allows the user to toggle debug output during test execution
4246
#MFTF_DEBUG=
47+
48+
#*** Default timeout for wait actions
49+
#WAIT_TIMEOUT=10
4350
#*** End of .env ***#

etc/config/codeception.dist.yml

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ settings:
1212
memory_limit: 1024M
1313
extensions:
1414
enabled:
15-
- Codeception\Extension\RunFailed
1615
- Magento\FunctionalTestingFramework\Extension\TestContextExtension
1716
- Magento\FunctionalTestingFramework\Allure\Adapter\MagentoAllureAdapter
1817
config:

etc/config/functional.suite.dist.yml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ modules:
2020
config:
2121
\Magento\FunctionalTestingFramework\Module\MagentoWebDriver:
2222
url: "%MAGENTO_BASE_URL%"
23+
backend_url: "%MAGENTO_BACKEND_BASE_URL%"
2324
backend_name: "%MAGENTO_BACKEND_NAME%"
2425
browser: 'chrome'
2526
restart: true

src/Magento/FunctionalTestingFramework/Allure/Adapter/MagentoAllureAdapter.php

+16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use Yandex\Allure\Adapter\Event\StepStartedEvent;
1111
use Yandex\Allure\Adapter\Event\StepFinishedEvent;
1212
use Yandex\Allure\Adapter\Event\StepFailedEvent;
13+
use Yandex\Allure\Adapter\Event\TestCaseFailedEvent;
14+
use Codeception\Event\FailEvent;
1315
use Codeception\Event\SuiteEvent;
1416
use Codeception\Event\StepEvent;
1517

@@ -132,4 +134,18 @@ public function stepAfter(StepEvent $stepEvent = null)
132134
}
133135
$this->getLifecycle()->fire(new StepFinishedEvent());
134136
}
137+
138+
/**
139+
* Override of parent method, fires a TestCaseFailedEvent if a test is marked as incomplete.
140+
*
141+
* @param FailEvent $failEvent
142+
* @return void
143+
*/
144+
public function testIncomplete(FailEvent $failEvent)
145+
{
146+
$event = new TestCaseFailedEvent();
147+
$e = $failEvent->getFail();
148+
$message = $e->getMessage();
149+
$this->getLifecycle()->fire($event->withException($e)->withMessage($message));
150+
}
135151
}

src/Magento/FunctionalTestingFramework/DataGenerator/Persist/Curl/AbstractExecutor.php

+5-19
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,18 @@
1414
abstract class AbstractExecutor implements CurlInterface
1515
{
1616
/**
17-
* Base url.
17+
* Returns Magento base URL. Used as a fallback for other services (eg. WebApi, Backend)
1818
*
1919
* @var string
2020
*/
2121
protected static $baseUrl = null;
2222

2323
/**
24-
* Resolve base url.
25-
*
26-
* @return void
24+
* Returns base URL for Magento instance
25+
* @return string
2726
*/
28-
protected static function resolveBaseUrl()
27+
public function getBaseUrl(): string
2928
{
30-
31-
if ((getenv('MAGENTO_RESTAPI_SERVER_HOST') !== false)
32-
&& (getenv('MAGENTO_RESTAPI_SERVER_HOST') !== '') ) {
33-
self::$baseUrl = getenv('MAGENTO_RESTAPI_SERVER_HOST');
34-
} else {
35-
self::$baseUrl = getenv('MAGENTO_BASE_URL');
36-
}
37-
38-
if ((getenv('MAGENTO_RESTAPI_SERVER_PORT') !== false)
39-
&& (getenv('MAGENTO_RESTAPI_SERVER_PORT') !== '')) {
40-
self::$baseUrl .= ':' . getenv('MAGENTO_RESTAPI_SERVER_PORT');
41-
}
42-
43-
self::$baseUrl = rtrim(self::$baseUrl, '/') . '/';
29+
return getenv('MAGENTO_BASE_URL');
4430
}
4531
}

src/Magento/FunctionalTestingFramework/DataGenerator/Persist/Curl/AdminExecutor.php

+15-16
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,11 @@ class AdminExecutor extends AbstractExecutor implements CurlInterface
3737
private $response;
3838

3939
/**
40-
* Should executor remove backend_name from api url
40+
* Flag describes whether the request is to Magento Base URL, removes backend_name from api url
4141
* @var boolean
4242
*/
4343
private $removeBackend;
4444

45-
/**
46-
* Backend url.
47-
*
48-
* @var string
49-
*/
50-
private static $adminUrl;
51-
5245
/**
5346
* Constructor.
5447
* @param boolean $removeBackend
@@ -58,15 +51,21 @@ class AdminExecutor extends AbstractExecutor implements CurlInterface
5851
*/
5952
public function __construct($removeBackend)
6053
{
61-
if (!isset(parent::$baseUrl)) {
62-
parent::resolveBaseUrl();
63-
}
64-
self::$adminUrl = parent::$baseUrl . getenv('MAGENTO_BACKEND_NAME') . '/';
6554
$this->removeBackend = $removeBackend;
6655
$this->transport = new CurlTransport();
6756
$this->authorize();
6857
}
6958

59+
/**
60+
* Returns base URL for Magento backend instance
61+
* @return string
62+
*/
63+
public function getBaseUrl(): string
64+
{
65+
$backendHost = getenv('MAGENTO_BACKEND_BASE_URL') ?: parent::getBaseUrl();
66+
return $backendHost . getenv('MAGENTO_BACKEND_NAME') . '/';
67+
}
68+
7069
/**
7170
* Authorize admin on backend.
7271
*
@@ -76,11 +75,11 @@ public function __construct($removeBackend)
7675
private function authorize()
7776
{
7877
// Perform GET to backend url so form_key is set
79-
$this->transport->write(self::$adminUrl, [], CurlInterface::GET);
78+
$this->transport->write($this->getBaseUrl(), [], CurlInterface::GET);
8079
$this->read();
8180

8281
// Authenticate admin user
83-
$authUrl = self::$adminUrl . 'admin/auth/login/';
82+
$authUrl = $this->getBaseUrl() . 'admin/auth/login/';
8483
$data = [
8584
'login[username]' => getenv('MAGENTO_ADMIN_USERNAME'),
8685
'login[password]' => getenv('MAGENTO_ADMIN_PASSWORD'),
@@ -119,10 +118,10 @@ private function setFormKey()
119118
public function write($url, $data = [], $method = CurlInterface::POST, $headers = [])
120119
{
121120
$url = ltrim($url, "/");
122-
$apiUrl = self::$adminUrl . $url;
121+
$apiUrl = $this->getBaseUrl() . $url;
123122

124123
if ($this->removeBackend) {
125-
$apiUrl = parent::$baseUrl . $url;
124+
$apiUrl = parent::getBaseUrl() . $url;
126125
}
127126

128127
if ($this->formKey) {

src/Magento/FunctionalTestingFramework/DataGenerator/Persist/Curl/FrontendExecutor.php

+3-6
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,6 @@ class FrontendExecutor extends AbstractExecutor implements CurlInterface
6767
*/
6868
public function __construct($customerEmail, $customerPassWord)
6969
{
70-
if (!isset(parent::$baseUrl)) {
71-
parent::resolveBaseUrl();
72-
}
7370
$this->transport = new CurlTransport();
7471
$this->customerEmail = $customerEmail;
7572
$this->customerPassword = $customerPassWord;
@@ -84,11 +81,11 @@ public function __construct($customerEmail, $customerPassWord)
8481
*/
8582
private function authorize()
8683
{
87-
$url = parent::$baseUrl . 'customer/account/login/';
84+
$url = $this->getBaseUrl() . 'customer/account/login/';
8885
$this->transport->write($url);
8986
$this->read();
9087

91-
$url = parent::$baseUrl . 'customer/account/loginPost/';
88+
$url = $this->getBaseUrl() . 'customer/account/loginPost/';
9289
$data = [
9390
'login[username]' => $this->customerEmail,
9491
'login[password]' => $this->customerPassword,
@@ -146,7 +143,7 @@ public function write($url, $data = [], $method = CurlInterface::POST, $headers
146143
if (isset($data['customer_password'])) {
147144
unset($data['customer_password']);
148145
}
149-
$apiUrl = parent::$baseUrl . $url;
146+
$apiUrl = $this->getBaseUrl() . $url;
150147
if ($this->formKey) {
151148
$data['form_key'] = $this->formKey;
152149
} else {

src/Magento/FunctionalTestingFramework/DataGenerator/Persist/Curl/WebapiExecutor.php

+25-6
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,34 @@ class WebapiExecutor extends AbstractExecutor implements CurlInterface
5959
*/
6060
public function __construct($storeCode = null)
6161
{
62-
if (!isset(parent::$baseUrl)) {
63-
parent::resolveBaseUrl();
64-
}
65-
6662
$this->storeCode = $storeCode;
6763
$this->transport = new CurlTransport();
6864
$this->authorize();
6965
}
7066

67+
/**
68+
* Returns base URL for Magento Web API instance
69+
* @return string
70+
*/
71+
public function getBaseUrl(): string
72+
{
73+
$baseUrl = parent::getBaseUrl();
74+
75+
$webapiHost = getenv('MAGENTO_RESTAPI_SERVER_HOST');
76+
$webapiPort = getenv("MAGENTO_RESTAPI_SERVER_PORT");
77+
$webapiProtocol = getenv("MAGENTO_RESTAPI_SERVER_PROTOCOL");
78+
79+
if ($webapiHost) {
80+
$baseUrl = sprintf('%s://%s/', $webapiProtocol, $webapiHost);
81+
}
82+
83+
if ($webapiPort) {
84+
$baseUrl = rtrim($baseUrl, '/') . ':' . $webapiPort . '/';
85+
}
86+
87+
return $baseUrl;
88+
}
89+
7190
/**
7291
* Returns the authorization token needed for some requests via REST call.
7392
*
@@ -152,11 +171,11 @@ public function close()
152171
*/
153172
public function getFormattedUrl($resource)
154173
{
155-
$urlResult = parent::$baseUrl . 'rest/';
174+
$urlResult = $this->getBaseUrl() . 'rest/';
156175
if ($this->storeCode != null) {
157176
$urlResult .= $this->storeCode . "/";
158177
}
159-
$urlResult.= trim($resource, "/");
178+
$urlResult .= trim($resource, "/");
160179
return $urlResult;
161180
}
162181
}

src/Magento/FunctionalTestingFramework/DataGenerator/Persist/CurlHandler.php

+22-4
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,33 @@ private function resolveUrlReference($urlIn, $entityObjects)
197197
{
198198
$urlOut = $urlIn;
199199
$matchedParams = [];
200+
// Find all the params ({}) references
200201
preg_match_all("/[{](.+?)[}]/", $urlIn, $matchedParams);
201202

202203
if (!empty($matchedParams)) {
203204
foreach ($matchedParams[0] as $paramKey => $paramValue) {
205+
$paramEntityParent = "";
206+
$matchedParent = [];
207+
$dataItem = $matchedParams[1][$paramKey];
208+
// Find all the parent property (Type.key) references, assuming there will be only one
209+
// parent property reference within one param
210+
preg_match_all("/(.+?)\./", $dataItem, $matchedParent);
211+
212+
if (!empty($matchedParent) && !empty($matchedParent[0])) {
213+
$paramEntityParent = $matchedParent[1][0];
214+
$dataItem = preg_replace('/^'.$matchedParent[0][0].'/', '', $dataItem);
215+
}
216+
204217
foreach ($entityObjects as $entityObject) {
205-
$param = $entityObject->getDataByName(
206-
$matchedParams[1][$paramKey],
207-
EntityDataObject::CEST_UNIQUE_VALUE
208-
);
218+
$param = null;
219+
220+
if ($paramEntityParent === "" || $entityObject->getType() == $paramEntityParent) {
221+
$param = $entityObject->getDataByName(
222+
$dataItem,
223+
EntityDataObject::CEST_UNIQUE_VALUE
224+
);
225+
}
226+
209227
if (null !== $param) {
210228
$urlOut = str_replace($paramValue, $param, $urlOut);
211229
continue;

0 commit comments

Comments
 (0)