Skip to content

Commit 8f84d7e

Browse files
authored
Merge branch 'develop' into MQE-876
2 parents c2f07e5 + 2e466f2 commit 8f84d7e

File tree

9 files changed

+108
-37
lines changed

9 files changed

+108
-37
lines changed

dev/tests/verification/Resources/BasicFunctionalTest.txt

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ class BasicFunctionalTestCest
7575
$I->clickWithRightButton("#element .4123#element", 200, 300);
7676
$I->closeTab();
7777
$I->conditionalClick(".functionalTestSelector", ".functionalDependentTestSelector", true);
78+
$I->amGoingTo("delete entity that has the createDataKey: createKey1");
79+
$createKey1->deleteEntity();
80+
$I->deleteEntityByUrl("/V1/categories{$grabbedData}");
7881
$I->dontSee("someInput", ".functionalTestSelector");
7982
$I->dontSeeCheckboxIsChecked(".functionalTestSelector");
8083
$I->dontSeeCookie("someInput");

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

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
<clickWithRightButton selector="{{SampleSection.simpleElementOneParam('4123')}}{{SampleSection.simpleElement}}" x="{{offset.x}}" y="{{offset.y}}" stepKey="clickWithRightButtonKeyXY1" />
3939
<closeTab stepKey="closeTabKey1"/>
4040
<conditionalClick selector=".functionalTestSelector" dependentSelector=".functionalDependentTestSelector" visible="true" stepKey="conditionalClickKey1"/>
41+
<deleteData stepKey="deleteKey1" createDataKey="createKey1"/>
42+
<deleteData stepKey="deleteKey2" url="/V1/categories{$grabbedData}"/>
4143
<dontSee userInput="someInput" selector=".functionalTestSelector" stepKey="dontSeeKey1" />
4244
<dontSeeCheckboxIsChecked selector=".functionalTestSelector" stepKey="dontSeeCheckboxIsCheckedKey1"/>
4345
<dontSeeCookie userInput="someInput" stepKey="dontSeeCookieKey1"/>

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

+19-3
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@ class WebapiExecutor extends AbstractExecutor implements CurlInterface
5555
*
5656
* @param string $storeCode
5757
*/
58-
public function __construct($storeCode = 'default')
58+
public function __construct($storeCode = null)
5959
{
6060
if (!isset(parent::$baseUrl)) {
6161
parent::resolveBaseUrl();
6262
}
63+
6364
$this->storeCode = $storeCode;
6465
$this->transport = new CurlTransport();
6566
$this->authorize();
@@ -72,7 +73,7 @@ public function __construct($storeCode = 'default')
7273
*/
7374
protected function authorize()
7475
{
75-
$authUrl = parent::$baseUrl . 'rest/' . $this->storeCode . self::ADMIN_AUTH_URL;
76+
$authUrl = $this->getFormattedUrl(self::ADMIN_AUTH_URL);
7677
$authCreds = [
7778
'username' => getenv('MAGENTO_ADMIN_USERNAME'),
7879
'password' => getenv('MAGENTO_ADMIN_PASSWORD')
@@ -97,7 +98,7 @@ protected function authorize()
9798
public function write($url, $data = [], $method = CurlInterface::POST, $headers = [])
9899
{
99100
$this->transport->write(
100-
parent::$baseUrl . 'rest/' . $this->storeCode . '/' . trim($url, '/'),
101+
$this->getFormattedUrl($url),
101102
json_encode($data, JSON_PRETTY_PRINT),
102103
$method,
103104
array_unique(array_merge($headers, $this->headers))
@@ -138,4 +139,19 @@ public function close()
138139
{
139140
$this->transport->close();
140141
}
142+
143+
/**
144+
* Builds and returns URL for request, appending storeCode if needed.
145+
* @param string $resource
146+
* @return string
147+
*/
148+
public function getFormattedUrl($resource)
149+
{
150+
$urlResult = parent::$baseUrl . 'rest/';
151+
if ($this->storeCode != null) {
152+
$urlResult .= $this->storeCode . "/";
153+
}
154+
$urlResult.= trim($resource, "/");
155+
return $urlResult;
156+
}
141157
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class CurlHandler
8181
* @param EntityDataObject $entityObject
8282
* @param string $storeCode
8383
*/
84-
public function __construct($operation, $entityObject, $storeCode = 'default')
84+
public function __construct($operation, $entityObject, $storeCode = null)
8585
{
8686
$this->operation = $operation;
8787
$this->entityObject = $entityObject;

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

+3-12
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public function __construct($entityObject, $dependentObjects = [], $customFields
6363
} else {
6464
$this->entityObject = clone $entityObject;
6565
}
66-
$this->storeCode = 'default';
66+
$this->storeCode = null;
6767

6868
foreach ($dependentObjects as $dependentObject) {
6969
$this->dependentObjects[] = $dependentObject->getCreatedObject();
@@ -96,16 +96,11 @@ public function createEntity($storeCode = null)
9696
*
9797
* @param string $updateDataName
9898
* @param array $updateDependentObjects
99-
* @param string $storeCode
10099
* @return void
101100
*/
102101

103-
public function updateEntity($updateDataName, $updateDependentObjects = [], $storeCode = null)
102+
public function updateEntity($updateDataName, $updateDependentObjects = [])
104103
{
105-
if (!empty($storeCode)) {
106-
$this->storeCode = $storeCode;
107-
}
108-
109104
foreach ($updateDependentObjects as $dependentObject) {
110105
$this->dependentObjects[] = $dependentObject->getCreatedObject();
111106
}
@@ -146,14 +141,10 @@ public function getEntity($index = null, $storeCode = null)
146141
/**
147142
* Function which executes a delete request based on specific operation metadata
148143
*
149-
* @param string $storeCode
150144
* @return void
151145
*/
152-
public function deleteEntity($storeCode = null)
146+
public function deleteEntity()
153147
{
154-
if (!empty($storeCode)) {
155-
$this->storeCode = $storeCode;
156-
}
157148
$curlHandler = new CurlHandler('delete', $this->createdObject, $this->storeCode);
158149
$curlHandler->executeRequest($this->dependentObjects);
159150
}

src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php

+15-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Codeception\Exception\ModuleException;
1919
use Codeception\Util\Uri;
2020
use Codeception\Util\ActionSequence;
21+
use Magento\FunctionalTestingFramework\DataGenerator\Persist\Curl\WebapiExecutor;
2122
use Magento\FunctionalTestingFramework\Util\Protocol\CurlTransport;
2223
use Magento\FunctionalTestingFramework\Util\Protocol\CurlInterface;
2324
use Magento\Setup\Exception;
@@ -437,7 +438,6 @@ public function scrollToTopOfPage()
437438
*/
438439
public function magentoCLI($command)
439440
{
440-
441441
$apiURL = $this->config['url'] . getenv('MAGENTO_CLI_COMMAND_PATH');
442442
$executor = new CurlTransport();
443443
$executor->write($apiURL, [getenv('MAGENTO_CLI_COMMAND_PARAMETER') => $command], CurlInterface::POST, []);
@@ -446,6 +446,20 @@ public function magentoCLI($command)
446446
return $response;
447447
}
448448

449+
/**
450+
* Runs DELETE request to delete a Magento entity against the url given.
451+
* @param string $url
452+
* @return string
453+
*/
454+
public function deleteEntityByUrl($url)
455+
{
456+
$executor = new WebapiExecutor(null);
457+
$executor->write($url, [], CurlInterface::DELETE, []);
458+
$response = $executor->read();
459+
$executor->close();
460+
return $response;
461+
}
462+
449463
/**
450464
* Conditional click for an area that should be visible
451465
*

src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php

+27
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler;
99
use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject;
10+
use Magento\FunctionalTestingFramework\Exceptions\XmlException;
1011
use Magento\FunctionalTestingFramework\ObjectManager\ObjectHandlerInterface;
1112
use Magento\FunctionalTestingFramework\Page\Objects\PageObject;
1213
use Magento\FunctionalTestingFramework\Page\Objects\SectionObject;
@@ -34,6 +35,7 @@ class ActionObject
3435
const ASSERTION_ATTRIBUTES = ["expectedResult" => "expected", "actualResult" => "actual"];
3536
const ASSERTION_TYPE_ATTRIBUTE = "type";
3637
const ASSERTION_VALUE_ATTRIBUTE = "value";
38+
const DELETE_DATA_MUTUAL_EXCLUSIVE_ATTRIBUTES = ["url", "createDataKey"];
3739
const EXTERNAL_URL_AREA_INVALID_ACTIONS = ['amOnPage'];
3840
const MERGE_ACTION_ORDER_AFTER = 'after';
3941
const MERGE_ACTION_ORDER_BEFORE = 'before';
@@ -229,6 +231,9 @@ public function resolveReferences()
229231
$this->resolveSelectorReferenceAndTimeout();
230232
$this->resolveUrlReference();
231233
$this->resolveDataInputReferences();
234+
if ($this->getType() == "deleteData") {
235+
$this->validateMutuallyExclusiveAttributes(self::DELETE_DATA_MUTUAL_EXCLUSIVE_ATTRIBUTES);
236+
}
232237
}
233238
}
234239

@@ -496,6 +501,28 @@ private function findAndReplaceReferences($objectHandler, $inputString)
496501
return $outputString;
497502
}
498503

504+
/**
505+
* Validates that the mutually exclusive attributes passed in don't all occur.
506+
* @param array $attributes
507+
* @return void
508+
* @throws TestReferenceException
509+
*/
510+
private function validateMutuallyExclusiveAttributes(array $attributes)
511+
{
512+
$matches = array_intersect($attributes, array_keys($this->getCustomActionAttributes()));
513+
if (count($matches) > 1) {
514+
throw new TestReferenceException(
515+
"Actions of type '{$this->getType()}' must only contain one attribute of types '"
516+
. implode("', '", $attributes) . "'"
517+
);
518+
} elseif (count($matches) == 0) {
519+
throw new TestReferenceException(
520+
"Actions of type '{$this->getType()}' must contain at least one attribute of types '"
521+
. implode("', '", $attributes) . "'"
522+
);
523+
}
524+
}
525+
499526
/**
500527
* Validates the page objects area 'external' against a list of known incompatible types
501528
*

src/Magento/FunctionalTestingFramework/Test/etc/Actions/dataActions.xsd

+2-3
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
<xs:attribute ref="entity" use="required"/>
6868
<xs:attribute ref="createDataKey" use="required"/>
6969
<xs:attributeGroup ref="commonActionAttributes"/>
70-
<xs:attribute ref="storeCode"/>
7170
</xs:complexType>
7271

7372
<xs:complexType name="deleteDataType">
@@ -76,9 +75,9 @@
7675
</xs:annotation>
7776
<xs:simpleContent>
7877
<xs:extension base="xs:string">
79-
<xs:attribute ref="createDataKey" use="required"/>
78+
<xs:attribute ref="url"/>
79+
<xs:attribute ref="createDataKey"/>
8080
<xs:attributeGroup ref="commonActionAttributes"/>
81-
<xs:attribute ref="storeCode"/>
8281
</xs:extension>
8382
</xs:simpleContent>
8483
</xs:complexType>

src/Magento/FunctionalTestingFramework/Util/TestGenerator.php

+36-17
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ public function generateStepsPhp($actionObjects, $hookObject = false, $actor = "
481481
$visible = null;
482482
$command = null;
483483
$sortOrder = null;
484+
$storeCode = null;
484485

485486
$assertExpected = null;
486487
$assertActual = null;
@@ -510,6 +511,7 @@ public function generateStepsPhp($actionObjects, $hookObject = false, $actor = "
510511
$input = $this->addUniquenessFunctionCall($customActionAttributes['userInput']);
511512
} elseif (isset($customActionAttributes['url'])) {
512513
$input = $this->addUniquenessFunctionCall($customActionAttributes['url']);
514+
$url = $this->addUniquenessFunctionCall($customActionAttributes['url']);
513515
} elseif (isset($customActionAttributes['expectedValue'])) {
514516
//For old Assert backwards Compatibility, remove when deprecating
515517
$assertExpected = $this->addUniquenessFunctionCall($customActionAttributes['expectedValue']);
@@ -634,6 +636,9 @@ public function generateStepsPhp($actionObjects, $hookObject = false, $actor = "
634636
$visible = $customActionAttributes['visible'];
635637
}
636638

639+
if (isset($customActionAttributes['storeCode'])) {
640+
$storeCode = $customActionAttributes['storeCode'];
641+
}
637642
switch ($actionObject->getType()) {
638643
case "createData":
639644
$entity = $customActionAttributes['entity'];
@@ -690,8 +695,8 @@ public function generateStepsPhp($actionObjects, $hookObject = false, $actor = "
690695
);
691696
}
692697

693-
if (isset($customActionAttributes['storeCode'])) {
694-
$createEntityFunctionCall .= sprintf("\"%s\");\n", $customActionAttributes['storeCode']);
698+
if (isset($storeCode)) {
699+
$createEntityFunctionCall .= sprintf("\"%s\");\n", $storeCode);
695700
} else {
696701
$createEntityFunctionCall .= ");\n";
697702
}
@@ -712,18 +717,32 @@ public function generateStepsPhp($actionObjects, $hookObject = false, $actor = "
712717
$testSteps .= $createEntityFunctionCall;
713718
break;
714719
case "deleteData":
715-
$key = $customActionAttributes['createDataKey'];
716-
//Add an informative statement to help the user debug test runs
717-
$testSteps .= sprintf(
718-
"\t\t$%s->amGoingTo(\"delete entity that has the createDataKey: %s\");\n",
719-
$actor,
720-
$key
721-
);
720+
if (isset($customActionAttributes['createDataKey'])) {
721+
$key = $customActionAttributes['createDataKey'];
722+
//Add an informative statement to help the user debug test runs
723+
$contextSetter = sprintf(
724+
"\t\t$%s->amGoingTo(\"delete entity that has the createDataKey: %s\");\n",
725+
$actor,
726+
$key
727+
);
728+
$deleteEntityFunctionCall = "";
722729

723-
if ($hookObject) {
724-
$testSteps .= sprintf("\t\t\$this->%s->deleteEntity();\n", $key);
730+
if ($hookObject) {
731+
$deleteEntityFunctionCall .= sprintf("\t\t\$this->%s->deleteEntity();\n", $key);
732+
} else {
733+
$deleteEntityFunctionCall .= sprintf("\t\t$%s->deleteEntity();\n", $key);
734+
}
735+
736+
$testSteps .= $contextSetter;
737+
$testSteps .= $deleteEntityFunctionCall;
725738
} else {
726-
$testSteps .= sprintf("\t\t$%s->deleteEntity();\n", $key);
739+
$output = sprintf(
740+
"\t\t$%s->deleteEntityByUrl(%s);\n",
741+
$actor,
742+
$url
743+
);
744+
$output = $this->resolveEnvReferences($output, [$url]);
745+
$testSteps .= $this->resolveTestVariable($output, [$url], null);
727746
}
728747
break;
729748
case "updateData":
@@ -772,8 +791,8 @@ public function generateStepsPhp($actionObjects, $hookObject = false, $actor = "
772791
);
773792
}
774793

775-
if (isset($customActionAttributes['storeCode'])) {
776-
$updateEntityFunctionCall .= sprintf("\"%s\");\n", $customActionAttributes['storeCode']);
794+
if (isset($storeCode)) {
795+
$updateEntityFunctionCall .= sprintf(", \"%s\");\n", $storeCode);
777796
} else {
778797
$updateEntityFunctionCall .= ");\n";
779798
}
@@ -834,13 +853,13 @@ public function generateStepsPhp($actionObjects, $hookObject = false, $actor = "
834853
}
835854

836855
if (isset($customActionAttributes['index'])) {
837-
$getEntityFunctionCall .= sprintf("%s", (int)$customActionAttributes['index']);
856+
$getEntityFunctionCall .= sprintf(", %s", (int)$customActionAttributes['index']);
838857
} else {
839858
$getEntityFunctionCall .= 'null';
840859
}
841860

842-
if (isset($customActionAttributes['storeCode'])) {
843-
$getEntityFunctionCall .= sprintf(", \"%s\");\n", $customActionAttributes['storeCode']);
861+
if (isset($storeCode)) {
862+
$getEntityFunctionCall .= sprintf(", \"%s\");\n", $storeCode);
844863
} else {
845864
$getEntityFunctionCall .= ");\n";
846865
}

0 commit comments

Comments
 (0)